Java 过滤器与一个谓词一起工作,但不能与另一个谓词一起工作

问题描述

帮助!这没有丝毫的意义。 我有一个 Java 集合和一个过滤这个集合的方法

public void filter(Predicate<? super T> predicate) {
    for (MyItem<T> item=head; item!=null; item=item.next) {
        if(predicate.test(item.key))
            remove(item.key);
        item = item.next;
    }
}

然后,当我用一个谓词运行它时,它就起作用了。

public static void main(String[] args) {
    MySet<Integer> set = new MySet<>();
    for(int i=0; i<20; i++) {
        set.add(i);
    }
    set.filter(x->x%2==0);
    MyItem<Integer> item = set.head;
    for(int i=0; i<10; i++) {
        System.out.println(item.key);
        item = item.next;
    }
}

它正确输出了从 1 到 19 的所有奇数。 但是,如果我将谓词更改为 x->x%2==1,它不会输出从 0 到 18 的所有偶数,而是输出从 0 到 9 的所有数字。

为什么这可能?

提前致谢!

解决方法

您有 2 次 item=item.next,一次在 for 循环声明中,一次在内部。所以你跳过了一半的项目。

for (MyItem<T> item=head; item!=null; item=item.next) {
    if(predicate.test(item.key))
        remove(item.key);
    // item = item.next; ???
}
,

问题很可能来自这样一个事实,即您跳过 filter 方法内部循环中的每一个元素。您在那里调用 item = item.next 两次,作为循环的“增量”(循环定义的第三部分),然后在每次迭代结束时调用。

public void filter(Predicate<? super T> predicate) {
    for (MyItem<T> item=head; item!=null; item=item.next) { //<- here
        if(predicate.test(item.key))
            remove(item.key);
        item = item.next; //<- here
    }
}

删除其中任何一个,最好在最后一行,它应该可以正常工作。