在Java中只使用谓词,不使用集合或数组来创建一个集合数据结构。如何实现迭代器相关功能?
注意:这是为了练习函数式编程,而不是为了实际使用
我创建了一个集合实现,它使用Java谓词来检查集合中是否存在对象。添加一个对象是通过创建一个新的谓词(以检查传入的对象是否等于新添加的对象)来处理的,或者使用前面的谓词对其进行排序
我已经完成了基本功能的实现和测试:contains
,add
,remove
,intersect
,setMinus
,union
然而,我一直在研究如何实现任何与迭代器相关的函数,例如,使用户可以使用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 楼答案
我真的很难理解你是如何试图实现一个数据结构来保存值,而没有一个底层数据结构来存储所说的值
实际更新数据结构内容的各种方法除了基于测试谓词的结果返回
true
或false
之外,什么都不做例如,
HashSet
是Set
接口(本身是Collection
接口的扩展)的一个实现,它使用HashMap
作为底层的支持数据结构我想既然你试图实现类似的东西,尽管使用^ {CD7}}你应该考虑类似的东西。
因此,如果您真的想继续这个过程,可以让实现使用
List
对象作为支持数据结构。有了这些,你的PredicateSet
类就需要继续扩展AbstractSet
类(从而获得所有的功能)并实现Set
接口如果操作正确,您的类将需要提供和
iterator
实现,这将自动允许使用AbstractCollection#toArray
方法我建议大家阅读一下
HashSet
的实施情况,了解更多想法