java8 Stream 操作

600 阅读3分钟

什么是流

流不存储元素,无需迭代集合中的元素,就可以从管道提取和操作元素。这些管道通常被组合在一起,形成一系列对流进行操作的管道

创建流

1、由集合创建流
ArrayList<Integer> list = new ArrayList<>();
Stream<Integer> stream1 = list.stream();

Set<String> set = new HashSet<>();
Stream<String> stream2 = set.stream();

Map<String,String> map = new HashMap<>();
Stream<Map.Entry<String, String>> stream3 = map.entrySet().stream();
2、创建序列流
//创建一个整型序列流
IntStream range = IntStream.range(0, 100);
3、创建一个迭代流
//iterate()方法的第一个参数是一个初始值,会作为第二个参数函数接口方法的的参数,然后函数接口方法的返回值又会当成参数传入
//特别注意不能不忘记limit()方法,不然会死循环
Stream.iterate(0,e -> ++e).limit(10).forEach(System.out::println);
4、build方法创建流
//流的构建器,可以单独添加元素
Stream.Builder<String> builder = Stream.builder();
builder.add("a").add("b").accept("c");
//调用build()方法后就不能在添加元素了
builder.build().forEach(System.out::println);
5、使用数组创建一个流
int[] arr = {1,2,3,4,5};
//可以使用Arrays的stream()传入一个数组创建流
IntStream stream4 = Arrays.stream(arr);
6、其他
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13);

//由正则表达式创建一个流对象
Stream<String> stream5 = Pattern.compile("[ .,?]+").splitAsStream("要输入的字符串");
```

中间操作

1、peek() 无修改的查看元素
long count = IntStream.range(0, 100).
        peek(System.out::println).
        sum();
2 sorted()、distinct()
Random random = new Random();
IntStream.range(1,100).
        map(random::nextInt).
        boxed(). //元素自动装箱
        sorted((x,y) -> y.compareTo(x)). //排序
        distinct(). //去重
        peek(System.out::println).collect(Collectors.toCollection(ArrayList::new));
3、filter(Predicate) 过滤元素
ArrayList<Object> collect = IntStream.range(0, 1000).
        //筛选出符合要求的元素返回true
        filter(e -> {
    for (int i = 2;i < e;i++){
        if ((e % i) == 0){
            return false;
        }
    }
    if(e ==0 || e == 1)
        return false;
    return true;
}).collect(ArrayList::new, ArrayList::add,ArrayList::addAll);
System.out.println(collect);
4、map()将元素映射到另一种元素,返回新元素到流中
Stream<Integer> integerStream = IntStream.
        range(0, 100).
        mapToObj(e -> UUID.randomUUID().toString()).
        //将uuid字符串映射成int类型返回到流中
        map(String::length);
5、flatMap() 与map()相似,但方法返回一个流,将流中的元素汇总
Stream<String> stream = IntStream.range(0, 100).
        mapToObj(e -> UUID.randomUUID().toString()).
        //flatMap 返回一个流对象,所有流对象中的元素会汇总在一个流中
        flatMap(e -> Arrays.stream(e.split("-")));

最终操作

1、结果汇总成数组 toArray()
String[] strings = Stream.of("a", "b", "c").
        //生成对应类型的数组。IntFunction函数接口方法接受一个int类型的参数,作为创建数组的元素个数的参数
        toArray(String[]::new);
Object[] objects = Stream.of("a", "b", "c").
        //生成object数组
        toArray();
2、循环forEach(Consumer)
IntStream.range(0,100).forEach(System.out::println);
3、保存到集合collect()
Stream.iterate(0,e -> ++e).limit(100).collect(Collectors.toCollection(ArrayList::new));
4、组合reduce(BinaryOperator)

接受两个参数,返回一个结果结果作为下一次迭代的第一个参数

//计算元素之和
Optional<Integer> reduce = Stream.iterate(0, e -> ++e).limit(100).reduce(Integer::sum);
//找到最大的元素
Optional<Integer> reduce1 = Stream.iterate(0, e -> ++e).limit(100).reduce((x, y) -> x <= y ? y : x);
5、匹配

allMatch(Predicate) 流中的所有元素都返回true 结果为true 否则为false

anyMatch(Predicate) 有一个元素满足条件返回true,

noneMatch(Predicate) 所有元素都不满足返条件返回true

//所有元素都大于条件返回true
boolean b = IntStream.range(11, 21).allMatch(e -> e > 10);
//任意一个元素满足就返回true
boolean b1 = IntStream.range(11, 21).anyMatch(e -> e > 17);
//所有元素都不满足条件时返回true
boolean b2 = IntStream.range(11, 21).noneMatch(e -> e > 21);
6、查找

findFirst() 返回元素流中的第一个

findAny() 非并行流会选择流中的第一个元素

OptionalInt first = IntStream.range(11, 21).findFirst();
OptionalInt any = IntStream.range(11, 21).findAny();
7、最大值,最小值,计数
Stream<Date> dateStream = Stream.of(new Date(2020, 10, 1), new Date(2020, 10, 2), new Date(2020, 10, 3));
long count = dateStream.count();
System.out.println(count);

Stream<Date> dateStream1 = Stream.of(new Date(2020, 10, 1), new Date(2020, 10, 2), new Date(2020, 10, 3));
Optional<Date> max = dateStream1.max(Date::compareTo);
System.out.println(max);

Stream<Date> dateStream2 = Stream.of(new Date(2020, 10, 1), new Date(2020, 10, 2), new Date(2020, 10, 3));
Optional<Date> min = dateStream2.min((x,y) -> x.compareTo(y));
System.out.println(min);
8、数字流聚合函数
OptionalInt max = IntStream.range(0, 100).max();
OptionalDouble average = IntStream.range(0, 100).average();
OptionalInt min = IntStream.range(0, 100).min();