有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在Java中只使用谓词,不使用集合或数组来创建一个集合数据结构。如何实现迭代器相关功能?

注意:这是为了练习函数式编程,而不是为了实际使用

我创建了一个集合实现,它使用Java谓词来检查集合中是否存在对象。添加一个对象是通过创建一个新的谓词(以检查传入的对象是否等于新添加的对象)来处理的,或者使用前面的谓词对其进行排序

我已经完成了基本功能的实现和测试:containsaddremoveintersectsetMinusunion

然而,我一直在研究如何实现任何与迭代器相关的函数,例如,使用户可以使用for each循环

有什么实用的方法可以做到这一点吗?(即避免集合或数组)

以下是我到目前为止的情况。我还创造了一些unit tests here

import java.util.Collection;
import java.util.function.Predicate;

public class PredicateSet<E> {

    private Predicate<E> rootPredicate = e -> false;
    private int size = 0;

    public int size() { return size; }

    public boolean isEmpty() { return size == 0; }

    public boolean contains(Object o) {
        try {
            return rootPredicate.test((E) o);
        } catch (ClassCastException cce) {
            return false;
        }
    }

    public boolean add(E e) {
        if (contains(e))
            return false;
        Predicate<E> newPredicate = e::equals;
        rootPredicate = newPredicate.or(rootPredicate);
        size++;
        return true;
    }

    public boolean remove(Object o) {
        try {
            if (!contains(o))
                return false;
        } catch (ClassCastException cce) {
            return false;
        }
        E e = (E) o;
        Predicate<E> newPredicate = e::equals;
        rootPredicate = newPredicate.negate().and(rootPredicate);
        size--;
        return true;
    }

    public boolean containsAll(Collection<? extends E> c) {
        return c.stream().allMatch(this::contains);
    }

    public boolean addAll(Collection<? extends E> c) {
        var changed = false;
        for (E e : c) {
            if (add(e))
                changed = true;
        }
        return changed;
    }

    public boolean removeAll(Collection<? extends E> c) {
        var changed = false;
        for (E e : c) {
            if (remove(e))
                changed = true;
        }
        return changed;
    }

    public boolean intersect(Collection<? extends E> c) {
        PredicateSet<E> intersection = new PredicateSet<>();

        for (var x : c) {
            try {
                if (contains(x))
                    intersection.add(x);
            } catch (ClassCastException ignored) {
            }
        }
        var changed = this.size != intersection.size;
        this.rootPredicate = intersection.rootPredicate;
        this.size = intersection.size;
        return changed;
    }

    public boolean setMinus(Collection<? extends E> c) {

        var changed = false;
        for (var x : c) {
            try {
                if (remove(x))
                    changed = true;
            } catch (ClassCastException ignored) {
            }
        }
        return changed;
    }

    public boolean union(Collection<? extends E> c) {
        var changed = false;
        for (var x : c) {
            try {
                if (add(x))
                    changed = true;
            } catch (ClassCastException ignored) {
            }
        }
        return changed;
    }

    public void clear() {
        this.size = 0;
        rootPredicate = e -> false;
    }
}

共 (1) 个答案

  1. # 1 楼答案

    我真的很难理解你是如何试图实现一个数据结构来保存值,而没有一个底层数据结构来存储所说的值

    实际更新数据结构内容的各种方法除了基于测试谓词的结果返回truefalse之外,什么都不做

    例如,HashSetSet接口(本身是Collection接口的扩展)的一个实现,它使用HashMap作为底层的支持数据结构

    我想既然你试图实现类似的东西,尽管使用^ {CD7}}你应该考虑类似的东西。

    因此,如果您真的想继续这个过程,可以让实现使用List对象作为支持数据结构。有了这些,你的PredicateSet类就需要继续扩展AbstractSet类(从而获得所有的功能)并实现Set接口

    如果操作正确,您的类将需要提供和iterator实现,这将自动允许使用AbstractCollection#toArray方法

    我建议大家阅读一下HashSet的实施情况,了解更多想法