将"过滤器"方法添加到元素列表的更好方法是什么?

Voi*_*ain 1 java filter

我想对java中的元素列表实现一个过滤方法,所以我可以根据我的过滤器删除列表中的一些元素.而且,最重要的是,我想尽可能简单地设计界面.

这是我的实现:我创建了一个名为EasierList的类,在类中,我添加了一个方法,其签名和实现如下所示:

public IEasierList<T> filter(ISelection<T> filter) {
    List<T> result = new ArrayList<T>();
    for(T item : mInternalList) {
        if(filter.accept(item)) {
            result.add(item);
        }
    }

    mInternalList = result;
    return new EasierList<T>(this);
}
Run Code Online (Sandbox Code Playgroud)

至于ISelection接口,它非常简单:

public boolean accept(T obj);
Run Code Online (Sandbox Code Playgroud)

所以,你可以说,使用这个类的用户需要编写这样的代码来使用过滤器:

aEasierList.filter(new ISelection<T>() {
@Override
public boolean accept(T obj) {
        // some test
    return false;
}
});
Run Code Online (Sandbox Code Playgroud)

而且我想知道是否有更好的方法来做到这一点,我的意思是让界面更容易使用?

提前致谢!

Nat*_*tix 5

两点:

首先,您不必重新发明轮子,您可以使用已经支持过滤转换集合和迭代的Guava.当然,这些方法是静态的,但你可以使用他们的标准,或接口.ListCollectionIterable

其次,由于Java还不支持lambda表达式(计划用于Java 8),所以详细的匿名类是实现函数对象的唯一方法(如果你不想创建一个完整的命名类).但是,您可以通过不在适当的位置实现匿名类来帮助自己,但是将其存储在静态字段中:

private static final Predicate<String> startsWithS = new Predicate<String>() {
    @Override public boolean apply(String string) {
        return string.startsWith("S");
    }
}
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它:

Collection<String> strings = ...
Collection<String> filtered = Collections2.filter(strings, startsWithS);
Run Code Online (Sandbox Code Playgroud)

编辑:

应该提到一个更重要的事情:这些filtertransform方法不会创建独立于原始集合的新集合.他们创建的是一个"视图",它在技术上是一个代理对象,指向原始集合并在迭代,查询等过程中懒惰地应用给定Predicate或其Function元素.

这有时很方便,但你必须记住,为了获得一个独立的新集合(当然不是深刻的),你需要将它传递给一个新的构造函数(或工厂).采集.

List<String> filteredList =
    new ArrayList<>(Collections2.filter(strings, startsWithS));
Run Code Online (Sandbox Code Playgroud)

顺便说一句,这可能是使用静态导入filter方法来减少冗长程度的好机会.