java 8 Stream操作Collection集合详解

KLQ 2020-08-26 16:23:56 java常见问答 3997

下面的文章要给大家讲到的就是Java 8 Stream操作Collection集合的详细内容,对这个方面有疑惑的小伙伴可以通过下文来进行一下了解。

Java 8新增了Stream、IntStream、LongStream、DoubleStream等流式 API,它们代表多个支持串行和并行聚集操作的元素。

在上面的四个接口当中,Stream是一个通用的流接口,IntStream、LongStream、DoubleStream代表元素类型为int、long、double的流。

Java 8还为上面每个流式API提供了对应的Builder。

例:Stream.Builder、IntStream.Builder、LongStream.Builder、DoubleStream.Builder,开发者可以通过这些Builder来创建对应的流。

下面是独立使用Stream的步骤:

独立使用Stream的步骤

在上面的步骤当中,步骤4能够根据具体需求来调用不同的方法。

Stream提供了很多的聚集方法供用户调用。

对于大部分聚集方法来说,每个Stream只可以执行一次。

示例:

public class IntStreamTest
{
    public static void main(String[] args)
    {
        IntStream is = IntStream.builder()
            .add(20)
            .add(13)
            .add(-2)
            .add(18)
            .build();
        // 下面调用聚集方法的代码每次只能执行一行
        System.out.println("is 所有元素的最大值:" + is.max()
            .getAsInt());
        System.out.println("is 所有元素的最小值:" + is.min()
            .getAsInt());
        System.out.println("is 所有元素的总和:" + is.sum());
        System.out.println("is 所有元素的总数:" + is.count());
        System.out.println("is 所有元素的平均值:" + is.average());
        System.out.println("is所有元素的平方是否都大于20: " + is.allMatch(ele - > ele * ele > 20));
        System.out.println("is是否包含任何元素的平方大于20 : " + is.anyMatch(ele - > ele * ele > 20));
        // 将is映射成一个新Stream,新Stream的每个元素是原Stream元素的2倍+1
        IntStream newIs = is.map(ele - > ele * 2 + 1);
        // 使用方法引用的方式来遍历集合元素
        newIs.forEach(System.out::println); // 输岀 41 27 -3 37
    }
}

先创建了一个IntStream,之后分别多次调用IntStream的聚集方法执行操作,这样就能够获取该流的相关信息。

注意一下,下面的5~13行代码每次只可以执行一行,所以,需要将其他代码注释掉。

Stream提供了大量的方法进行聚集操作,这些方法既能够是“中间的”(intermediate),也可以是 "末端的"(terminal)。

中间方法-中间操作允许流保持打开状态,并允许直接调用后续方法。

上面程序中的map()方法就是中间方法。

中间方法的返回值是另外一个流。

末端方法-末端方法是对流的最终操作。

当对某个Stream执行末端方法后,该流将会被“消耗”且不再可用。

上面程序中的sum()、count()、average()等方法都是末端方法。

流的方法还有下面的特征:

有状态的方法-这种方法会给流增加一些新的属性,比如元素的唯一性、元素的最大数量、保证元素以排序的方式被处理等。

有状态的方法往往需要更大的性能开销。

短路方法-短路方法可以尽早结束对流的操作,不必检查所有的元素。

下面是Stream常用的中间方法:

Stream常用的中间方法

Stream常用的末端方法:

Stream常用的末端方法

Java 8允许使用流式API来操作集合,Collection接口提供了一个stream()默认方法,该方法可返回该集合对应的流,之后就可以通过流式API来操作集合元素,因为Stream能够对集合元素进行整体的聚集操作,所以Stream极大地丰富了集合的功能。

在之前介绍过的java 8 Predicate操作Collection集合详解一文当中,一节的示例程序需要额外定义一个calAll()方法来遍历集合元素,之后依次对每个集合元素进行判断,这样做的话就很麻烦,假如,使用Stream的话,就能够直接对集合中所有的元素进行批量操作。

下面的话就使用Stream来改写这个程序:

public class CollectionStream
{
    public static void main(String[] args)
    {
        // 创建一个集合
        Collection objs = new HashSet();
        objs.add(new String("XXX网Java教程"));
        objs.add(new String("XXX网C++教程"));
        objs.add(new String("XXX网C语言教程"));
        objs.add(new String("XXX网Python教程"));
        objs.add(new String("XXX网Go教程"));
        // 统计集合中出现“XXX网”字符串的数量
        System.out.println(objs.stream()
            .filter(ele - > ((String) ele)
                .contains("XXX网"))
            .count()); // 输出 5
        // 统计集合中出现“Java”字符串的数量
        System.out.println(objs.stream()
            .filter(ele - > ((String) ele)
                .contains("Java"))
            .count()); // 输出 1
        // 统计集合中出现字符串长度大于 12 的数量
        System.out.println(objs.stream()
            .filter(ele - > ((String) ele)
                .length() > 12)
            .count()); // 输出 1
        // 先调用Collection对象的stream ()方法将集合转换为Stream
        // 再调用Stream的mapToInt()方法获取原有的Stream对应的IntStream
        objs.stream()
            .mapToInt(ele - > ((String) ele)
                .length())
            // 调用forEach()方法遍历IntStream中每个元素
            .forEach(System.out::println); // 输出 11 11 12 10 14
    }
}

输出结果:

5    1    1    11    11    12    10    14

代码第11~20行能够看出,程序只要调用Collection 的 stream()方法就能够返回该集合对应的Stream,之后就能够通过Stream提供的方法对所有集合元素进行处理,这样就可以很大的简化了集合编程的代码,这也是Stream编程带来的优势。

第18行代码先调用Collection对象的stream()方法将集合转换为Stream对象,之后调用Stream对象的mapToInt()方法将其转换为IntStream这个mapToInt。

方法就是一个中间方法,所以,程序可以继续调用IntStream的forEach()方法来遍历流中的元素。

文章内容就给你介绍到这里了,更多java基础知识和java编程常见问题,可以继续关注奇Q工具网来进行了解哦。

推荐阅读:

java使用foreach循环遍历Collection集合详解

java使用Lambda表达式遍历Iterator迭代器详解

Iterator是什么?java Iterator遍历Collection集合元素详解