Java8--Stream的各种用法(一)

java8中对集合的操作,新增了Stream, 配合lmbda表达是,极大提高了我们对集合数据的处理效率。Stream是java8中处理集合的关键抽象概念,可以执行复杂的查找、筛选、过滤、排序、聚合、数据映射等操作。

操作分类

  • 中间操作:
    • 无状态:元素的处理不受之前元素影响,如: map()、 mapToInt() 、flatMap()、flatMapToLong()、peek()、unordered()、filter()
    • 有状态:该操作只有拿到所有元素之后才能继续,如:distinct()、 sorted()、limit()、skip()
  • 结束操作:
    • 非短路操作:必须处理所有元素才能得到结果,如:foreach()、forEachOrdered()、toArray()、reduce()、collect()、max()、min()、count()
    • 短路操作:遇到某些符合条件的元素就可以得到结果, ru:anyMatch()、allMatch()、noneMatch()、findFirst()、findAny()

Stream创建

1、通过集合数组创建:

  1. Collection.stream():我们最常用到的当时list.stream()
    // 顺序流
    Stream<Object> stream = new ArrayList<>().stream();
    
    // 并行流
    Stream<Object> parallelStream = new ArrayList<>(). parallelStream();
  2. Array.stream: 
     IntStream stream = Arrays.stream(new int[10]);
  3. Stream的静态方法:of()、iterate()、generate()、builder().build();

    Stream<Integer> of = Stream.of(1,2,3);
    
    //生成无限的顺序流, 需要用limit限制元素个数
    Stream<Integer> iterate = Stream.iterate(0, x -> x + 1).limit(2);
    
    //生成无限的无序流, 需要limit限制元素个数
    Stream<Double> generate = Stream.generate(Math::random).limit(2);
    
    Stream<Object> build = Stream.builder().add("123).build();

    这里简单说明一下stream和parallelStream的简单区分: stream 是顺序流;parallelStream是并行流,内部以多线程并行执行的方式对流进行操作,所以需要流中的数据处理没有顺序要求。

Stream API的介绍和使用: 

1、foreach、forEachOrdered

forEachOrdered 适用用于并行流的情况下进行迭代,能保证迭代的有序性

Stream.of("a,b,c","d,e,f")
        .forEach(System.out::println);

2、find:findFirst、findAny

findFirst、findAny 查找第一个、查找任何一个 返回的类型为Optional

Optional<String> any = Stream.of("a,b,c", "d,e,f").findAny();

String first = Stream.of("a,b,c", "d,e,f").findFirst().get();

3、match: noneMatch、allMatch、anyMatch

数据流中是否存在符合条件的元素 返回值为bool 值

  • noneMatch: 数据流中没有元素符合条件,返回true
  • allMatch: 数据流中全部元素符合条件,返回true
  • anyMatch:数据流中存在任一元素符合条件,返回true
Stream.of("a,b,c","d,e,f").noneMatch(s -> s.equals("123"));
Stream.of("a,b,c","d,e,f").allMatch(s -> s.equals("123"));
Stream.of("a,b,c","d,e,f").anyMatch(s -> s.equals("123"));

4、聚合:max、min、count

min、max 最值操作,需要自定义比较器,返回数据流中最大最小的值

count 统计元素个数

Optional<Integer> max = Stream.of(1, 2, 3, 4).max((i1, i2) -> i1.compareTo(i2));

long num = Stream.of(1, 2, 3, 4).count();

5、reduce

规约操作,将整个数据流的值规约为一个值,count、min、max底层就是使用reduce

  • T reduce(T identity, BinaryOperator<T> accumulator)
  • Optional<T> reduce(BinaryOperator<T> accumulator);
  • <U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator,
                 BinaryOperator<U> combiner);

reduce 有三个重写的方法, 我们常用的是第一个,直接返回我们想要的对象。

Integer reduce = Stream.of(1, 2, 3, 4).reduce(0, (i1, i2) -> i1 + i2);

6、map转换, 将对象A -> B

mapToInt、mapToLong、mapToDouble 默认提供了转int,long,double的操作符。

List<String> list = Stream.of(1, 2, 3, 4).map(i -> String.valueOf(i)).collect(Collectors.toList());

一般在实际应用中,我们会提取List<T> 中的T的某一个字段值组成list / set: 

List<String> nameList = list.stream()
                            .map(User::getName)
                            .collect(Collectors.toList())

7、faltMap 数据扁平化

flatmapToInt 、flatmapToLong 、flatmapToDouble 默认提供了拍平成int,long,double的操作符

Stream.of("a,b,c", "d,e,f")
        .flatMap(s -> Stream.of(s.split(",")))
        .forEach(System.out::println);

8、筛选:filter、limit、skip

  • filter: 过滤
  • limit( long n):限制返回数据条数
  • skip( long n):调过前面几条数据,获取后面的数据
Stream.of(1, 2, 3, 4, 5)
        .filter(i -> i < 5)
        .skip(1)
        .limit(2);

9、distinct去重 

Stream.of(1, 2, 2, 4, 2).distinct();

10、peek 挑出

提前消费数据

Stream.of(1, 2, 3, 4, 5).peek(i -> i++); 

11、sorted 排序

对元素排序,前提是实现Comparable接口,也可以自定义比较器

Stream.of(2,5,3,1,0).sorted()

12、collect 

收集操作,将所有数据收集起来,这个操作非常重要,官方的提供的Collectors 提供了非常多收集器,可以说Stream 的核心在于Collectors。 对此我们会专门写一篇文章介绍Collectors的使用

Stream.of(1,2,3,1,2)
        .collect(Collectors.toSet())
        .forEach(System.out::println);

猜你喜欢

转载自blog.csdn.net/zhoushimiao1990/article/details/127286689