我想根据谓词筛选java.util.Collection。


当前回答

我的回答建立在Kevin Wong的基础上,这里是一个使用spring中的CollectionUtils和Java 8 lambda表达式的一行程序。

CollectionUtils.filter(list, p -> ((Person) p).getAge() > 16);

这是我见过的最简洁易读的方法(不使用基于方面的库)。

Spring CollectionUtils可从Spring版本4.0.2获得。请记住,您需要JDK 1.8和语言级别8+。

其他回答

使用java 8,特别是lambda表达式,你可以像下面的例子那样简单:

myProducts.stream().filter(prod -> prod.price>10).collect(Collectors.toList())

其中,对于myProducts集合中的每个产品,如果prodc .price>10,则将该产品添加到新的过滤列表中。

我将把RxJava加入其中,它在Android上也可用。RxJava可能并不总是最好的选择,但如果您希望在集合上添加更多转换或在过滤时处理错误,RxJava将为您提供更大的灵活性。

Observable.from(Arrays.asList(1, 2, 3, 4, 5))
    .filter(new Func1<Integer, Boolean>() {
        public Boolean call(Integer i) {
            return i % 2 != 0;
        }
    })
    .subscribe(new Action1<Integer>() {
        public void call(Integer i) {
            System.out.println(i);
        }
    });

输出:

1
3
5

更多关于RxJava过滤器的细节可以在这里找到。

Java集合流的一个替代(更轻量级的)选择是Ocl.java库,它使用vanilla集合和lambdas: https://github.com/eclipse/agileuml/blob/master/Ocl.java

例如,对数组列表中的单词进行简单的筛选和求和 可能是:

ArrayList<Word> sel = Ocl.selectSequence(words, 
                             w -> w.pos.equals("NN")); 
int total = Ocl.sumint(Ocl.collectSequence(sel,
                             w -> w.text.length())); 

Where Word有字符串pos;字符串文本;属性。效率似乎与流选项相似,例如,在两个版本中,10000个单词在大约50毫秒内处理。

Python、Swift等都有等效的OCL库。基本上,Java集合流重新发明了OCL操作——>select, ->collect等,这些操作自1998年以来就存在于OCL中。

在我的情况下,我正在寻找与特定字段空排除列表。 这可以用for循环来完成,并填充没有空地址的对象的临时列表。 但是多亏了Java 8流

List<Person> personsList = persons.stream()
.filter(p -> p.getAdrress() != null).collect(Collectors.toList());

#java #集合#集合#java8 #流

设置:

public interface Predicate<T> {
  public boolean filter(T t);
}

void filterCollection(Collection<T> col, Predicate<T> predicate) {
  for (Iterator i = col.iterator(); i.hasNext();) {
    T obj = i.next();
    if (predicate.filter(obj)) {
      i.remove();
    }
  }
}

的用法:

List<MyObject> myList = ...;
filterCollection(myList, new Predicate<MyObject>() {
  public boolean filter(MyObject obj) {
    return obj.shouldFilter();
  }
});