美文网首页
如何过滤Java集合中的元素

如何过滤Java集合中的元素

作者: 大哥你先走 | 来源:发表于2019-01-09 23:04 被阅读0次

1. Overview

在本篇简短的教程中,我们将学习在Java中过滤集合元素的几种方法,过滤其实就是找到集合中满足条件的所有元素(某种条件下等同于删除不满足条件的元素)。

在实际的Java应用中集合过滤是一个基本的工作,为此有很多第三方类库提供了集合过滤的功能。

在本篇教程中我们使用以下方法实现集合过滤功能:

  • Java 8 Streams’ filter() function
  • Relevant Eclipse Collections APIs
  • Apache’s CollectionUtils filter() method
  • Guava’s Collections2 filter() approach
  • Vavr's Stream API

2. 使用Java Stream API

自Java 8 推出以来,Streams 在集合数据处理场景发挥了巨大的作用。在大多数情况下,使用Streams都是处理集合数据的首选方法,Java 提供原生支持,不依赖任何第三方类库。

2.1. 使用 Stream.filter 对集合过滤

为了简单起见,我们所有样例代码都以提取整数集合中所有的偶数为目标。因此,集合中的所有元素都需要执行 ‘value % 2 == 0‘ 检查,在Java中可以用 Predicate 对象表示检查条件。

    @Test
    public void test_findEvenNumber_returnSuccess() throws Exception {
        List<Integer> numbers = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
        List<Integer> evenNumbers = findEvenNumbersUserStream(numbers);
        evenNumbers.forEach(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) {
                assertTrue(integer % 2 == 0);
            }
        });
    }

    private List<Integer> findEvenNumbersUserStream(List<Integer> baseCollection) {
        Predicate<Integer> streamsPredicate = item -> item % 2 == 0;
        return baseCollection.stream()
            .filter(streamsPredicate)
            .collect(Collectors.toList());
    }

本文提供的所有可以对集合进行过滤的第三方类库都有自己特有的 *Predicate * 实现,但是所有的实现都是一个函数式接口,因此可以使用 Lambda 表达式来定义。

3. 使用 Eclipse Collections

我们利用第三方库来实现我们的目标(集合过滤),不管是我们的应用还没有使用Java 8 开发还是我们想使用第三方组件提供但是Java不具备的高级功能。

Eclipse Collections是一个努力跟上新范例,不断发展并接受所有最新Java版本引入的更改的第三方优秀Java类库。

3.1. 依赖

pom.xml 文件添加如下依赖即可使用 Eclipse Collections:

<dependency>
    <groupId>org.eclipse.collections</groupId>
    <artifactId>eclipse-collections</artifactId>
    <version>9.2.0</version>
</dependency>

eclipse-collections 包括所有必须的数据结构接口和API实现。

3.2. 使用 Eclipse Collections 过滤集合

基于Eclipse Collections 提供的 MutableList 数据结构实现集合过滤:

    @Test
    public void test_findEvenNumbersUseEclipse_returnSuccess() throws Exception {
        List<Integer> numbers = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
        List<Integer> evenNumbers = findEvenNumbersUseEclipse(numbers);
        evenNumbers.forEach(integer -> assertTrue(integer % 2 == 0));
    }
    

    public List<Integer> findEvenNumbersUseEclipse(List<Integer> input) {
        org.eclipse.collections.api.block.predicate.Predicate<Integer> eclipsePredicate
            = item -> item % 2 == 0;

        List<Integer> filteredList = Lists.mutable
            .ofAll(input)
            .select(eclipsePredicate);
        return filteredList;
    }

一种替代方案是使用 Iterate 的静态方法 select() 来实现集合过滤功能:

    @Test
    public void test_findEvenNumbersUseEclipseWithStaticMethod_returnSuccess() throws Exception {
        List<Integer> numbers = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
        List<Integer> evenNumbers = findEvenNumbersUseEclipseWithStaticMethod(numbers);
        evenNumbers.forEach(integer -> assertTrue(integer % 2 == 0));
    }

    public List<Integer> findEvenNumbersUseEclipseWithStaticMethod(List<Integer> input) {
        org.eclipse.collections.api.block.predicate.Predicate<Integer> eclipsePredicate
            = item -> item % 2 == 0;
        return (List<Integer>) Iterate.select(input, eclipsePredicate);
    }

4. 使用 Apache 的 CollectionUtils

4.1. 依赖

pom.xml 文件添加如下依赖即可使用 Apache 的 CollectionUtils:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.2</version>
</dependency>

4.2. 使用 CollectionUtils 过滤集合

使用 CollectonUtils‘ 过滤集合的样例代码如下:

    @Test
    public void test_findEvenNumbersUseApache_returnSuccess() throws Exception {
        List<Integer> inputs = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
        Collection<Integer> numbers = new LinkedList(inputs);
        Collection<Integer> evenNumbers = findEvenNumbersUseApache(numbers);
        evenNumbers.forEach(integer -> assertTrue(integer % 2 == 0));
    }

    public Collection<Integer> findEvenNumbersUseApache(Collection<Integer> baseCollection) {
        org.apache.commons.collections4.Predicate<Integer> apachePredicate = item -> item % 2 == 0;

        CollectionUtils.filter(baseCollection, apachePredicate);
        return baseCollection;
    }

注意Apache 的 CollectionUtils 过滤方法会移除输入集合中不满足过滤条件的元素,因此要求集合是可变集合而且支持 remove 操作,否在会抛出异常。

5. 使用 Guava 的 Collections2 进行集合过滤

Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库,提供了很多简化Java开发的功能,感兴趣的可以从官方文档获取更多信息。

5.1. 依赖

使用Guava之前首先引入Guava,对于maven构建的工程可以将如下依赖添加到 pom.xml 文件:

<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>27.0.1-jre</version>
</dependency>

5.2. 使用 Collections2 过滤集合

Guava Collections2* 过滤集合的方式和 Apache CollectionUtils 过滤集合的方式类似,但是不需要修改原来的集合,因此不要求原集合为可变集合:

    @Test
    public void test_findEvenNumbersUseGuava_returnSuccess() throws Exception {
        List<Integer> inputs = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
        Collection<Integer> evenNumbers = findEvenNumbersUseGuava(inputs);
        evenNumbers.forEach(integer -> assertTrue(integer % 2 == 0));
    }

    public Collection<Integer> findEvenNumbersUseGuava(Collection<Integer> baseCollection) {
        com.google.common.base.Predicate<Integer> guavaPredicate = item -> item % 2 == 0;

        return Collections2.filter(baseCollection, guavaPredicate);
    }

6. 使用 Vavr 的 Stream 进行集合过滤

Vavr(以前称为Javaslang)是Java 8+的函数库,它提供持久数据类型和功能控制结构。

6.1. 依赖

使用Vavr之前首先引入Vavr,对于maven构建的工程可以将如下依赖添加到 pom.xml 文件

<dependency>
    <groupId>io.vavr</groupId>
    <artifactId>vavr</artifactId>
    <version>0.9.2</version>
</dependency>

6.2. 使用 Collections2 过滤集合

使用 Vavr的 Strem 对集合过滤和使用Java原生的 Stream 对集合过滤语法一样,而且两者都使用Java 定义的 Predicate

    @Test
    public void test_findEvenNumbersUseVavr_returnSuccess() throws Exception {
        List<Integer> inputs = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
        List<Integer> evenNumbers = Stream.concat(inputs).filter(integer -> integer.intValue() % 2 == 0).asJavaMutable();
        evenNumbers.forEach(integer -> assertTrue(integer % 2 == 0));
    }

7. 总结

本文介绍了5种对Java 集合过滤的方法,包括Java原生支持的Stream和其他第三方库支持的方法,这些第三方库都是很好的Java开发工具,建议大家可以了解一下。

本文所有样例的源代码可以从Github获取。

8 参考

[1] How to Filter a Collection in Java
[2] eclipse-collections
[3] Apache commons-collections
[4] Guava
[5] Vavr

相关文章

  • 如何过滤Java集合中的元素

    1. Overview 在本篇简短的教程中,我们将学习在Java中过滤集合元素的几种方法,过滤其实就是找到集合中满...

  • 如何在列表、字典、集合中根据条件筛选数据

    迭代方式(Low) 列表:过滤掉列表中的负数 字典:过滤字典中值大于90的值 集合:过滤集合中能被3整除的元素

  • 数组过滤某一属性值的实体

    使用谓词过滤不可变集合和可变集合的区别是:过滤不可变集合时,会返回符合条件的集合元素组成的新集合;过滤可变集合时,...

  • Swift 函数学习笔记

    sorted 排序函数 map遍历集合元素 filter过滤集合 reduce 遍历集合,计算元素 reverse...

  • jquery-过滤性选择器

    :first过滤选择器 该类型的选择器是根据某过滤规则进行元素的匹配,书写时以“:”号开头,通常用于查找集合元素中...

  • 【骚全带你学Java---九、认识java数组】

    java中数组 数组是指一组数据的集合,数组中的每个数据称为元素。在Java中,数组也是Java对象。数组中的元素...

  • 20170705 List类

    参考文献:《Java疯狂讲义》(第三版) List集合类 List集合代表一个元素有序,重复的集合,集合中每个元素...

  • JAVA-集合

    JAVA集合 Java集合是使程序能够存储和操纵元素不固定的一组数据。 JAVA中的集合是一个类似一个‘’容器‘’...

  • 并发修改异常

    案例:判断集合中是否存在java,如果有则添加android且遍历集合元素 方法一:使用collection集合中...

  • 集合的函数API

    基础 filter 和 map filter进行条件过滤需要的新集合 map进行元素操作改变元素内容,生成新集合 ...

网友评论

      本文标题:如何过滤Java集合中的元素

      本文链接:https://www.haomeiwen.com/subject/gcfwrqtx.html