我想对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)
而且我想知道是否有更好的方法来做到这一点,我的意思是让界面更容易使用?
提前致谢!
两点:
首先,您不必重新发明轮子,您可以使用已经支持过滤和转换集合和迭代的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)
编辑:
应该提到一个更重要的事情:这些filter和transform方法不会创建独立于原始集合的新集合.他们创建的是一个"视图",它在技术上是一个代理对象,指向原始集合并在迭代,查询等过程中懒惰地应用给定Predicate或其Function元素.
这有时很方便,但你必须记住,为了获得一个独立的新集合(当然不是深刻的),你需要将它传递给一个新的构造函数(或工厂).采集.
List<String> filteredList =
new ArrayList<>(Collections2.filter(strings, startsWithS));
Run Code Online (Sandbox Code Playgroud)
顺便说一句,这可能是使用静态导入filter方法来减少冗长程度的好机会.
| 归档时间: |
|
| 查看次数: |
228 次 |
| 最近记录: |