java8 Stream详解和使用

java8 Stream详解和使用

什么是Stream

看Stream的javadoc说明

**
 * A sequence of elements supporting sequential and parallel aggregate
 * operations.  The following example illustrates an aggregate operation using
 * {@link Stream} and {@link IntStream}:
 *
 * <pre>{@code
 *     int sum = widgets.stream()
 *                      .filter(w -> w.getColor() == RED)
 *                      .mapToInt(w -> w.getWeight())
 *                      .sum();
 * }</pre>
 *

一个元素的序列,支持串行和并行的聚合操作。javadoc给的example就是一个stream的操作。

需要注意的是如果两个代码(两个终止操作)对一个流进行操作,会报错 stream has already been operated upon or closed

因为一个流遇到终止操作就会关闭

Stream的特性

javadoc文档中是这样描述流的:

去执行一个计算,stream操作被组成流管道(pipeline)。stream的pipeline由源(数组、集合、函数表达式、I/O通道等等)的零个或者多个的中间操作(中间操作转换一个stream成为另外的stream,比如说filter)和一个终止操作(比如sum count forEach)组成。stream是有惰性的,只有在执行了终止操作时才会对源执行计算,并且只有在需要的时候才使用源的元素。

/** 
To perform a computation, stream operations are composed into a stream pipeline. A stream pipeline consists of a source (which might be an array, a collection, a generator function, an I/O channel, etc), zero or more intermediate operations (which transform a stream into another stream, such as filter(Predicate)), and a terminal operation (which produces a result or side-effect, such as count() or forEach(Consumer)). Streams are lazy; computation on the source data is only performed when the terminal operation is initiated, and source elements are consumed only as needed.
*/

所有总结流的特性:

  • 流包括源、中间操作和终止操作
  • 流具有惰性,只有在执行了终止操作的时候才会去对源进行计算。

比如下面的代码:并不会打印test,因为流具有惰性,我们没有执行终止操作。

List<String> list = Arrays.asList("hello","world","hello world");
        list.stream().map(String::toUpperCase).map(m ->{
            System.out.println("test");
            return m;
        });

下面这段代码就会打印结果,因为我们用了终止操作forEach()\

 public static void main(String[] args) {
        List<String> list = Arrays.asList("hello","world","hello world");
        list.stream().map(String::toUpperCase).forEach(System.out::println);

    }

javadoc 中写到 除了Stream 这个对象的引用流,还有专门的 IntStream,LongStream,DoubleStream,所有的这些流都具有流的特性

In addition to Stream, which is a stream of object references, there are primitive specializations for IntStream, LongStream, and DoubleStream, all of which are referred to as "streams" and conform to the characteristics and restrictions described here.

主要的操作举例

  • 获取stream

    Stream<String> stream = Stream.of("zhangsan","lisi");
    Stream<String> stream2 = Stream.of(new String[]{"zhangsan","lisi"});
    // iterate创建的是一个无线的,加了limit就能控制数量了
    Stream.iterate(0,x -> x+1).limit(10).forEach(System.out::println);
    
  • map

     // map 集合中的字符串转成大写
     List<String> list2 = Arrays.asList("hello","world","hello world");
     list2.stream().map( m -> m.toUpperCase()).collect(Collectors.toList()).forEach(System.out::println);
    
  • filter

    // filter 过滤掉集合中Integer类型的元素
    List<Object> filterList = Arrays.asList("hello","world","hello world",1);
    	filterList.stream().filter(o -> o instanceof String).collect(Collectors.toList()).forEach(System.out::println);
    
  • limit

    //  limit 取集合中前两个元素
            List<String> limitList = Arrays.asList("hello","world","hello world");
            limitList.stream().limit(2).collect(Collectors.toList()).forEach(System.out::println);
    
  • skip

     // skip 跳过第一个元素
            List<String> skipList = Arrays.asList("hello","world","hello world");
            skipList.stream().skip(1).collect(Collectors.toList()).forEach(System.out::println);
    
  • distinct

     // distinct 去掉重复的元素
            List<String> distinctList = Arrays.asList("hello","world","hello world","hello");
            distinctList.stream().distinct().collect(Collectors.toList()).forEach(System.out::println);
    
  • IntSummaryStatistics

    // IntSummaryStatistics 取平均数 最大值 数量 等概览值
            IntSummaryStatistics intSummaryStatistics = Stream.iterate(1, i -> i * 2).limit(6).mapToInt(i -> i).summaryStatistics();
            System.out.println(intSummaryStatistics.getAverage());
            System.out.println(intSummaryStatistics.getCount());
            System.out.println(intSummaryStatistics.getMax());
            System.out.println(intSummaryStatistics.getMin());
            System.out.println(intSummaryStatistics.getSum());
    
  • flatMap

    //创建一个 装有两个泛型为integer的集合
            Stream<List<Integer>> flatMapStream = Stream.of(Arrays.asList(1, 2, 3), Arrays.asList(4, 5));
            // flatMap 接受的是一个Function 传入 List 返回 Stream 看javaDoc给的例子
            // orders.flatMap(order -> order.getLineItems().stream())...
           /* flatMapStream.flatMap(m -> {
                // 这种方式new了一个list把传入的add到新的了
                List arrayList = Lists.newArrayList();
                arrayList.addAll(m);
                return arrayList.stream();
            }).collect(Collectors.toList()).forEach(System.out::println);*/
    
            // 改进一下  这种方式应用了第一个list
            flatMapStream.flatMap(m -> m.stream()).collect(Collectors.toList()).forEach(System.out::println);
    
    
 List<String> list = Arrays.asList("hello","hi","你好");
        List<String> list1 = Arrays.asList("zhangsan","lisi","wangwu");
        // 想要输出 hello zhangsan hi zhangsan 你好zhangsan hello lisi ....
        List<String> collect = list.stream().flatMap(o -> list1.stream().map(o1 -> o + o1)).collect(Collectors.toList());
        collect.stream().forEach(System.out::println);

-----------------------输出----------------
    hellozhangsan
hellolisi
hellowangwu
hizhangsan
hilisi
hiwangwu
你好zhangsan
你好lisi
你好wangwu

你可能感兴趣的:(java8)