筛选Java集合的最佳方法是什么?

What is the best way to filter a Java Collection?

我想基于谓词过滤一个java.util.Collection


Java 8(2014)在一行代码中使用流和lambDas解决了这个问题:

1
2
List<Person> beerDrinkers = persons.stream()
    .filter(p -> p.getAge() > 16).collect(Collectors.toList());

这是一个教程。

使用Collection#removeIf在适当的位置修改集合。(注意:在这种情况下,谓词将删除满足谓词的对象):

1
persons.removeIf(p -> p.getAge() <= 16);

lambdaj允许在不写入循环或内部类的情况下筛选集合:

1
2
List<Person> beerDrinkers = select(persons, having(on(Person.class).getAge(),
    greaterThan(16)));

你能想象一些更可读的东西吗?

免责声明:我是兰姆达吉的撰稿人


假设你使用Java 1.5,而你不能添加谷歌收藏,我会做一些非常相似的事情。这是琼恩评论中的一个小变异

第一个将此界面添加到您的编码器。

1
public interface IPredicate<T> { boolean apply(T type); }

当某个预言者是某一种类型的真实性时,其实现者可以回答。如果TUserAuthorizedUserPredicateIf TIf TIf UserAuthorizedUserPredicateImplements IPredicate,then EDOCX1〔4

然后在一些公用类,你可以说

1
2
3
4
5
6
7
8
9
public static <T> Collection<T> filter(Collection<T> target, IPredicate<T> predicate) {
    Collection<T> result = new ArrayList<T>();
    for (T element: target) {
        if (predicate.apply(element)) {
            result.add(element);
        }
    }
    return result;
}

假设你有可能使用

1
2
3
4
5
6
7
8
Predicate<User> isAuthorized = new Predicate<User>() {
    public boolean apply(User user) {
        // binds a boolean method in User to a reference
        return user.isAuthorized();
    }
};
// allUsers is a Collection<User>
Collection<User> authorizedUsers = filter(allUsers, isAuthorized);

如果线性检查的性能令人关注,那么我可能想有一个目标收集的域名对象。The domain object that has the target collection would have filtering logic for the methods that initiatize,add and set the target collection.

更新:

在实用类别中(让我们说预言),我增加了一种选择方法,其中包括一种选择方法,当预测值不返回预期值时,缺陷值,以及一种用于参数的静态属性,以便在新的IPREDICATE中使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class Predicate {
    public static Object predicateParams;

    public static <T> Collection<T> filter(Collection<T> target, IPredicate<T> predicate) {
        Collection<T> result = new ArrayList<T>();
        for (T element : target) {
            if (predicate.apply(element)) {
                result.add(element);
            }
        }
        return result;
    }

    public static <T> T select(Collection<T> target, IPredicate<T> predicate) {
        T result = null;
        for (T element : target) {
            if (!predicate.apply(element))
                continue;
            result = element;
            break;
        }
        return result;
    }

    public static <T> T select(Collection<T> target, IPredicate<T> predicate, T defaultValue) {
        T result = defaultValue;
        for (T element : target) {
            if (!predicate.apply(element))
                continue;
            result = element;
            break;
        }
        return result;
    }
}

The following example looks for missing objects between collections:

1
2
3
4
5
6
7
8
9
10
11
List<MyTypeA> missingObjects = (List<MyTypeA>) Predicate.filter(myCollectionOfA,
    new IPredicate<MyTypeA>() {
        public boolean apply(MyTypeA objectOfA) {
            Predicate.predicateParams = objectOfA.getName();
            return Predicate.select(myCollectionB, new IPredicate<MyTypeB>() {
                public boolean apply(MyTypeB objectOfB) {
                    return objectOfB.getName().equals(Predicate.predicateParams.toString());
                }
            }) == null;
        }
    });

The following example,looks for an instance in a collection,and returns the first element of the collection as default value when the instance is not found:

1
2
3
4
MyType myObject = Predicate.select(collectionOfMyType, new IPredicate<MyType>() {
public boolean apply(MyType objectOfMyType) {
    return objectOfMyType.isDefault();
}}, collectionOfMyType.get(0));

Update(after Java 8 release):

自从我(艾伦)第一次回答这个问题以来已经有好几年了,我仍然不相信我收集了这么多的答案。以任何速率,现在爪哇8号已将语言封闭,我的答案将被认为是不同的,简单的。根据Java 8,不需要单独的静态功用等级。所以如果你想找到第一个元素,那就是你的预言。

1
2
3
4
5
final UserService userService = ... // perhaps injected IoC
final Optional<UserModel> userOption = userCollection.stream().filter(u -> {
    boolean isAuthorized = userService.isAuthorized(u);
    return isAuthorized;
}).findFirst();

《第八届任择议定书》第1〔6〕条、第isPresent()条、第orElse(defaultUser)条、第orElseGet(userSupplier)条和第orElseThrow(exceptionSupplier)条以及其他摩纳哥职能,如mapflatMapfilter

如果你想简单地收集所有与预言匹配的使用者,那么使用EDOCX1

1
2
3
4
5
final UserService userService = ... // perhaps injected IoC
final List<UserModel> userOption = userCollection.stream().filter(u -> {
    boolean isAuthorized = userService.isAuthorized(u);
    return isAuthorized;
}).collect(Collectors.toList());

See here for more examples on how Java 8 streams work.


Use collections.filter(collection,predicate),from Apache commons.


"最好"的方式太宽泛了。这是"短"?快感?可以读?在现场过滤还是进入另一个收藏?

简单(但并非最容易理解)的方法是以Iterate it and use iterator.remove()方法:

1
2
3
4
5
Iterator<Foo> it = col.iterator();
while( it.hasNext() ) {
  Foo foo = it.next();
  if( !condition(foo) ) it.remove();
}

现在,为了使它更加现实,你可以将它写成一种有用的方法。然后发明一个IPREDICATE接口,创建一个匿名执行该接口,并做一些类似的事情:

1
2
3
4
5
6
CollectionUtils.filterInPlace(col,
  new IPredicate<Foo>(){
    public boolean keepIt(Foo foo) {
      return foo.isBar();
    }
  });

过滤器位置()Iterate the collection and calls predicate.keepit()to learn if the instance to be kept in the collection.

我实在看不出第三方图书馆为这项任务提出的理由。


Consider Google Collections for an Updated Collections Framework that Supports Generics.

最新资料:谷歌收藏图书馆现已被删除。你应该使用Guava的最新释放。它仍然对收集框架具有同样的扩展,包括基于预测的过滤机制。


等待Java 8:

1
2
3
4
5
6
7
List<Person> olderThan30 =
  //Create a Stream from the personList
  personList.stream().
  //filter the element to select only those with age >= 30
  filter(p -> p.age >= 30).
  //put those filtered elements into a new List.
  collect(Collectors.toList());


我将把RxJava放到环中,它也可以在Android上使用。RxJava可能并不总是最好的选择,但是如果您希望在集合中添加更多转换或在过滤时处理错误,它将给予您更多的灵活性。

1
2
3
4
5
6
7
8
9
10
11
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
2
3
1
3
5

有关RxJava的filter的更多详细信息,请参见此处。


自从Java 8早期发布以来,您可以尝试如下:

1
2
Collection<T> collection = ...;
Stream<T> stream = collection.stream().filter(...);

例如,如果您有一个整数列表,并且您想要过滤大于10的数字,然后将这些数字打印到控制台,那么您可以执行如下操作:

1
2
List<Integer> numbers = Arrays.asList(12, 74, 5, 8, 16);
numbers.stream().filter(n -> n > 10).forEach(System.out::println);

你确定你想过滤自己的收藏吗,比一个编辑更糟糕?

See org.apache.commons.collections.iterators.filteriterator

Or using version 4 of Apache commons org.apache.commons.collectis4.iterators.filteriterator


The setup:

1
2
3
4
5
6
7
8
9
10
11
12
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();
    }
  }
}

The use:

ZZU1


一些平直的爪哇爪哇怎么样?

1
2
3
4
5
 List<Customer> list ...;
 List<Customer> newList = new ArrayList<>();
 for (Customer c : list){
    if (c.getName().equals("dd")) newList.add(c);
 }

简单、易读、简单(并且在Android中工作!)但是如果你使用Java 8,你可以用甜蜜的一行来做:

1
List<Customer> newList = list.stream().filter(c -> c.getName().equals("dd")).collect(toList());

注意tolist()是静态导入的。


让我们看看如何使用Eclipse集合(以前的GS集合)过滤内置JDK列表和可变列表。

1
2
List<Integer> jdkList = Arrays.asList(1, 2, 3, 4, 5);
MutableList<Integer> ecList = Lists.mutable.with(1, 2, 3, 4, 5);

如果您想要过滤小于3的数字,您将期望得到以下输出。

1
2
List<Integer> selected = Lists.mutable.with(1, 2);
List<Integer> rejected = Lists.mutable.with(3, 4, 5);

下面介绍如何使用匿名内部类作为Predicate进行过滤。

1
2
3
4
5
6
7
8
9
10
11
Predicate<Integer> lessThan3 = new Predicate<Integer>()
{
    public boolean accept(Integer each)
    {
        return each < 3;
    }
};

Assert.assertEquals(selected, Iterate.select(jdkList, lessThan3));

Assert.assertEquals(selected, ecList.select(lessThan3));

下面是一些使用谓词工厂过滤JDK列表和Eclipse集合可变列表的替代方法。

1
2
3
Assert.assertEquals(selected, Iterate.select(jdkList, Predicates.lessThan(3)));

Assert.assertEquals(selected, ecList.select(Predicates.lessThan(3)));

这里是一个不为谓词分配对象的版本,它使用谓词2工厂,而使用selectWith方法,该方法采用Predicate2

1
2
Assert.assertEquals(
    selected, ecList.selectWith(Predicates2.<Integer>lessThan(), 3));

有时你想过滤一个负面的条件。Eclipse集合中有一种特殊的方法,称为reject

1
2
3
Assert.assertEquals(rejected, Iterate.reject(jdkList, lessThan3));

Assert.assertEquals(rejected, ecList.reject(lessThan3));

下面是如何使用Java 8 lambda作为EDCOX1(0)的方法进行过滤。

1
2
3
4
5
Assert.assertEquals(selected, Iterate.select(jdkList, each -> each < 3));
Assert.assertEquals(rejected, Iterate.reject(jdkList, each -> each < 3));

Assert.assertEquals(selected, gscList.select(each -> each < 3));
Assert.assertEquals(rejected, gscList.reject(each -> each < 3));

方法partition将返回两个集合,其中包含Predicate选择和拒绝的元素。

1
2
3
4
5
6
7
PartitionIterable<Integer> jdkPartitioned = Iterate.partition(jdkList, lessThan3);
Assert.assertEquals(selected, jdkPartitioned.getSelected());
Assert.assertEquals(rejected, jdkPartitioned.getRejected());

PartitionList<Integer> ecPartitioned = gscList.partition(lessThan3);
Assert.assertEquals(selected, ecPartitioned.getSelected());
Assert.assertEquals(rejected, ecPartitioned.getRejected());

注意:我是Eclipse集合的提交者。


使用foreach DSL,您可以编写

1
2
3
4
5
6
7
8
9
10
11
import static ch.akuhn.util.query.Query.select;
import static ch.akuhn.util.query.Query.$result;
import ch.akuhn.util.query.Select;

Collection<String> collection = ...

for (Select<String> each : select(collection)) {
    each.yield = each.value.length() > 3;
}

Collection<String> result = $result();

给定一个集合[快速,棕色,狐狸,跳跃,越过,懒惰,狗],这会导致[快速,棕色,跳跃,越过,懒惰],即所有字符串超过三个字符。

foreach DSL支持的所有迭代样式都是

  • AllSatisfy
  • AnySatisfy
  • Collect
  • Counnt
  • CutPieces
  • Detect
  • GroupedBy
  • IndexOf
  • InjectInto
  • Reject
  • Select

有关详细信息,请参阅https://www.iam.unibe.ch/scg/svn_repos/sources/foreach


《谷歌图书馆图书馆收藏》2.Filter(收藏、预测)方法只是你在寻找的东西。


由于Java 9 EDOCX1的引用14启用:

1
2
3
public static <T, A, R>
    Collector<T, ?, R> filtering(Predicate<? super T> predicate,
                                 Collector<? super T, A, R> downstream)

因此,过滤应为:

1
collection.stream().collect(Collectors.filtering(predicate, collector))

例子:

1
2
List<Integer> oddNumbers = List.of(1, 19, 15, 10, -10).stream()
            .collect(Collectors.filtering(i -> i % 2 == 1, Collectors.toList()));

这一点,加上缺少真正的闭包,是我对Java最大的抱怨。老实说,上面提到的大多数方法都很容易阅读,而且非常有效;但是,在与.NET、Erlang等一起使用之后……在语言层次上集成的列表理解使一切变得更加清晰。没有语言层面的补充,Java就不能像这一领域中的许多其他语言一样干净。

如果性能是一个很大的问题,那么google集合就是解决问题的方法(或者编写自己的简单谓词实用程序)。对于某些人来说,lambdaj语法更易于阅读,但它的效率并不高。

还有我写的图书馆。我将忽略任何关于它效率的问题(是的,它是那么糟糕)……是的,我清楚地知道它是基于反射的,不,我实际上不使用它,但它确实有效:

1
2
3
LinkedList<Person> list = ......
LinkedList<Person> filtered =
           Query.from(list).where(Condition.ensure("age", Op.GTE, 21));

1
2
LinkedList<Person> list = ....
LinkedList<Person> filtered = Query.from(list).where("x => x.age >= 21");


jfilter http://code.google.com/p/jfilter/最适合您的需求。

JFLAST是一个简单的、高性能的开源Java库,用于查询JavaBean的集合。

关键特征

  • 支持collection(java.util.collection、java.util.map和array)属性。
  • 支持任何深度的收藏。
  • 支持内部查询。
  • 支持参数化查询。
  • 可以在短短100毫秒内过滤100万条记录。
  • 过滤器(查询)是以简单的JSON格式提供的,类似于mangodb查询。下面是一些例子。
  • "id":"$le":"10"
    • 其中,对象ID属性小于等于10。
  • "id":"$in":["0","100"]
    • 其中,对象ID属性为0或100。
  • "lineitems":"lineamount":"1"
    • 其中参数化类型的LineItems集合属性的LineMount等于1。
  • "$和":["id":"0


    我编写了一个扩展的iterable类,它支持在不复制集合内容的情况下应用函数算法。

    用途:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    List<Integer> myList = new ArrayList<Integer>(){ 1, 2, 3, 4, 5 }

    Iterable<Integer> filtered = Iterable.wrap(myList).select(new Predicate1<Integer>()
    {
        public Boolean call(Integer n) throws FunctionalException
        {
            return n % 2 == 0;
        }
    })

    for( int n : filtered )
    {
        System.out.println(n);
    }

    上面的代码将实际执行

    1
    2
    3
    4
    5
    6
    7
    for( int n : myList )
    {
        if( n % 2 == 0 )
        {
            System.out.println(n);
        }
    }

    这里有一些非常好的答案。我,我想尽可能保持简单易读:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public abstract class AbstractFilter<T> {

        /**
         * Method that returns whether an item is to be included or not.
         * @param item an item from the given collection.
         * @return true if this item is to be included in the collection, false in case it has to be removed.
         */

        protected abstract boolean excludeItem(T item);

        public void filter(Collection<T> collection) {
            if (CollectionUtils.isNotEmpty(collection)) {
                Iterator<T> iterator = collection.iterator();
                while (iterator.hasNext()) {
                    if (excludeItem(iterator.next())) {
                        iterator.remove();
                    }
                }
            }
        }
    }


    使用集合查询引擎(CQEngine)。这是迄今为止最快的方法。

    请参见:如何查询Java中的对象集合(标准/SQLlike)?


    Java8之前的简单解决方案:

    1
    2
    ArrayList<Item> filtered = new ArrayList<Item>();
    for (Item item : items) if (condition(item)) filtered.add(item);

    不幸的是,此解决方案不是完全通用的,它输出的是一个列表,而不是给定集合的类型。此外,引入库或编写包装此代码的函数对我来说似乎是多余的,除非条件很复杂,但是您可以为条件编写函数。


    https://code.google.com/p/joquery网站/

    支持不同的可能性,

    给定集合,

    1
    Collection<Dto> testList = new ArrayList<>();

    类型的,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    class Dto
    {
        private int id;
        private String text;

        public int getId()
        {
            return id;
        }

        public int getText()
        {
            return text;
        }
    }

    滤波器

    爪哇7

    1
    2
    3
    4
    Filter<Dto> query = CQ.<Dto>filter(testList)
        .where()
        .property("id").eq().value(1);
    Collection<Dto> filtered = query.list();

    爪哇8

    1
    2
    3
    4
    5
    Filter<Dto> query = CQ.<Dto>filter(testList)
        .where()
        .property(Dto::getId)
        .eq().value(1);
    Collection<Dto> filtered = query.list();

    也,

    1
    2
    3
    4
    5
    6
    Filter<Dto> query = CQ.<Dto>filter()
            .from(testList)
            .where()
            .property(Dto::getId).between().value(1).value(2)
            .and()
            .property(Dto::grtText).in().value(new string[]{"a","b"});

    排序(也适用于Java 7)

    1
    2
    3
    4
    5
    Filter<Dto> query = CQ.<Dto>filter(testList)
            .orderBy()
            .property(Dto::getId)
            .property(Dto::getName)
        Collection<Dto> sorted = query.list();

    分组(也可用于Java 7)

    1
    2
    3
    4
    GroupQuery<Integer,Dto> query = CQ.<Dto,Dto>query(testList)
            .group()
            .groupBy(Dto::getId)
        Collection<Grouping<Integer,Dto>> grouped = query.list();

    连接(也可用于Java 7)

    鉴于,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    class LeftDto
    {
        private int id;
        private String text;

        public int getId()
        {
            return id;
        }

        public int getText()
        {
            return text;
        }
    }

    class RightDto
    {
        private int id;
        private int leftId;
        private String text;

        public int getId()
        {
            return id;
        }

        public int getLeftId()
            {
                return leftId;
            }

        public int getText()
        {
            return text;
        }
    }

    class JoinedDto
    {
        private int leftId;
        private int rightId;
        private String text;

        public JoinedDto(int leftId,int rightId,String text)
        {
            this.leftId = leftId;
            this.rightId = rightId;
            this.text = text;
        }

        public int getLeftId()
        {
            return leftId;
        }

        public int getRightId()
            {
                return rightId;
            }

        public int getText()
        {
            return text;
        }
    }

    Collection<LeftDto> leftList = new ArrayList<>();

    Collection<RightDto> rightList = new ArrayList<>();

    可以像,

    1
    2
    3
    4
    5
    6
    7
    8
    Collection<JoinedDto> results = CQ.<LeftDto, LeftDto>query().from(leftList)
                    .<RightDto, JoinedDto>innerJoin(CQ.<RightDto, RightDto>query().from(rightList))
                    .on(LeftFyo::getId, RightDto::getLeftId)
                    .transformDirect(selection ->  new JoinedDto(selection.getLeft().getText()
                                                         , selection.getLeft().getId()
                                                         , selection.getRight().getId())
                                     )
                    .list();

    表达

    1
    2
    3
    4
    Filter<Dto> query = CQ.<Dto>filter()
        .from(testList)
        .where()
        .exec(s -> s.getId() + 1).eq().value(2);

    我的答案是基于Kevin Wong的,这里是一个使用EDCOX1,8从春天和8的lambda表达式。

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

    这和我所看到的任何其他方法一样简洁易读(不使用基于方面的库)

    SpringCollectionUtils可以从Spring4.0.2.release获得,记住您需要JDK1.8和语言级别8+。


    使用java 8,特别是lambda expression,您可以像下面的示例一样简单地做到这一点:

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

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


    我需要根据列表中已经存在的值筛选列表。例如,删除后面所有小于当前值的值。2 5 3 4 7 5->2 5 7。或者,例如删除所有重复项3 5 4 2 3 5 6->3 5 4 2 6。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    public class Filter {
        public static <T> void List(List<T> list, Chooser<T> chooser) {
            List<Integer> toBeRemoved = new ArrayList<>();
            leftloop:
            for (int right = 1; right < list.size(); ++right) {
                for (int left = 0; left < right; ++left) {
                    if (toBeRemoved.contains(left)) {
                        continue;
                    }
                    Keep keep = chooser.choose(list.get(left), list.get(right));
                    switch (keep) {
                        case LEFT:
                            toBeRemoved.add(right);
                            continue leftloop;
                        case RIGHT:
                            toBeRemoved.add(left);
                            break;
                        case NONE:
                            toBeRemoved.add(left);
                            toBeRemoved.add(right);
                            continue leftloop;
                    }
                }
            }

            Collections.sort(toBeRemoved, new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    return o2 - o1;
                }
            });

            for (int i : toBeRemoved) {
                if (i >= 0 && i < list.size()) {
                    list.remove(i);
                }
            }
        }

        public static <T> void List(List<T> list, Keeper<T> keeper) {
            Iterator<T> iterator = list.iterator();
            while (iterator.hasNext()) {
                if (!keeper.keep(iterator.next())) {
                    iterator.remove();
                }
            }
        }

        public interface Keeper<E> {
            boolean keep(E obj);
        }

        public interface Chooser<E> {
            Keep choose(E left, E right);
        }

        public enum Keep {
            LEFT, RIGHT, BOTH, NONE;
        }
    }

    这个会像这样使用。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    List<String> names = new ArrayList<>();
    names.add("Anders");
    names.add("Stefan");
    names.add("Anders");
    Filter.List(names, new Filter.Chooser<String>() {
        @Override
        public Filter.Keep choose(String left, String right) {
            return left.equals(right) ? Filter.Keep.LEFT : Filter.Keep.BOTH;
        }
    });

    在Java 8中,可以直接使用此筛选器方法,然后执行此操作。

    1
    2
    3
    4
    5
    6
    7
     List<String> lines = Arrays.asList("java","pramod","example");

     List<String> result = lines.stream()              
             .filter(line -> !"pramod".equals(line))    
             .collect(Collectors.toList());              

     result.forEach(System.out::println);

    番石榴:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Collection<Integer> collection = Lists.newArrayList(1, 2, 3, 4, 5);

    Iterators.removeIf(collection.iterator(), new Predicate<Integer>() {
        @Override
        public boolean apply(Integer i) {
            return i % 2 == 0;
        }
    });

    System.out.println(collection); // Prints 1, 3, 5