返回基于成员变量或映射函数的子列表

Nim*_*sky 1 java generics functional-programming guava

我有一个pojo列表 List<Pojo> pojoList; 并pojo.getColour();返回一个Enum实例.

我想这样做:

List<Pojo> newlist = new ArrayList<Pojo>();
for(Pojo pojo:pojoList){
  if(pojo.getColour() == Colour.Red){
    newList.add(pojo);
  }
}
Run Code Online (Sandbox Code Playgroud)

我可以看到自己对其他类型的列表使用类似的函数,而不是重复大量的代码是一种使它成为通用和/或功能的方法?这样我就可以根据不同的规则创建不同类型的子列表?

Col*_*inD 6

首先,我应该注意,如果你只想要一个ArrayList包含匹配元素的new ,那么你在你的例子中做到的方式就好了.在Java具有lambda表达式之前,你不会让它变得更简单或更好看.

既然你用标记了这个,那么你就可以用Guava做到这一点.你基本上是在谓词(== Color.Red)和函数(pojo.getColour())的组合上过滤原始列表.所以,如果你有一个静态的最终Function<Pojo, Colour>COLOURPojo(这样的):

public static final Function<Pojo, Colour> COLOUR =
    new Function<Pojo, Colour>() {
      @Override public Colour apply(Pojo input) {
        return input.getColour();
      }
    };
Run Code Online (Sandbox Code Playgroud)

你可以像这样创建这样的组合:

Predicate<Pojo> isRedPojo = Predicates.compose(
    Predicates.equalTo(Colour.Red), Pojo.COLOUR);
Run Code Online (Sandbox Code Playgroud)

然后,您可以创建原始列表的筛选视图:

Iterable<Pojo> redPojos = Iterables.filter(pojoList, isRedPojo);
Run Code Online (Sandbox Code Playgroud)

ArrayList如果您愿意,您可以将过滤后的视图复制到:

List<Pojo> copy = Lists.newArrayList(redPojos);
Run Code Online (Sandbox Code Playgroud)

  • apache commons-collections也有很好的实用工具.Collection <Pojo> filtered = CollectionUtils.filter(pojoCollection,new Predicate(){...}); (2认同)
  • @Matt:我认为commons-collections过滤方法_removes_元素与原始集合不匹配,我不太喜欢.Guava有更明确命名的`Iterables.removeIf(Iterable,Predicate)`方法. (2认同)