Stream 的常用操作

Intermediate :

一个流可以后面跟随零个或多个 intermediate 操作。其目的主要是打开流,做出某种程度的数据映射/过滤,然后返回一个新的流,交给下一个操作使用。这类操作都是惰性化的(lazy),就是说,仅仅调用到这类方法,并没有真正开始流的遍历。

 

map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel(并行)、 sequential、 unordered

 

map (对元素进行处理并返回处理结果)

 

Stream<Integer> simpleStream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

//Intermediate(媒介) 惰性求值方法(N)

simpleStream.map(x->x+5+"\t").forEach(System.out::print);

控制台输出

mapToInt、mapToLong、mapToDouble 都是在map方法的基础上返回对应类型的专业化流

//在map操作的基础上返回该数据类型对应的专业化Stream

IntStream intStream = simpleStream.mapToInt(x -> x + 5);

DoubleStream doubleStream = simpleStream.mapToDouble(x -> x + 5);

LongStream longStream = simpleStream.mapToLong(x -> x + 5);

例:小写元素转大写

//小写元素转大写

Stream<String> stringStream = Stream.of("a", "b", "c", "d");

//stringStream.map(x->x.toUpperCase()).forEach(System.out::println);

//可简写

stringStream.map(String::toUpperCase).forEach(System.out::println);

 

 

filter(过滤)

//filter 依据lambda过滤Stream元素

long count = simpleStream.filter(x -> x > 4).count();

System.out.println(count);

 

distinct​(元素去重)

//distinct 元素去重,对于有序流不影响其排序

Stream<Integer> distinctStream = Stream.of(1, 2, 3, 4, 4, 4, 4, 5, 6, 7, 8, 9);

distinctStream.distinct().map(x->x+"\t").forEach(System.out::print);

控制台输出

 

sorted(元素排序)

//sorted 元素排序,按照自然循序或compare规则排序

//自然顺序排序

Stream<Integer> sortedStream = Stream.of(1, 5, 9, 7, 3, 6, 4, 8, 2,0);

sortedStream.sorted().map(x->x+"\t").forEach(System.out::print);

System.out.println();

//倒序

Stream<Integer> sortedStream1 = Stream.of(1, 5, 9, 7, 3, 6, 4, 8, 2,0);

sortedStream1.sorted(Comparator.reverseOrder()).map(x->x+"\t").forEach(System.out::print);

控制台输出

 

limit(截取前N个元素)

//返回由此流的元素组成的流,截短长度不要超过maxSize 。

Stream<Integer> limitStream = Stream.of(1, 5, 9, 7, 3, 6, 4, 8, 2,0);

limitStream.limit(3).map(x->x+"\t").forEach(System.out::print);

控制台输出

 

skip​(截取后N个元素)

//在丢弃流的第一个n元素后,返回由该流的剩余元素组成的流。 如果此流包含少于n元素,那么将返回一个空流。

Stream<Integer> skip​Stream = Stream.of(1, 5, 9, 7, 3, 6, 4, 8, 2,0);

skip​Stream.skip(3).map(x->x+"\t").forEach(System.out::print);

控制台输出

 

Terminal :

一个流只能有一个 terminal 操作,当这个操作执行后,流就被使用“光”了,无法再被操作。所以这必定是流的最后一个操作。Terminal 操作的执行,才会真正开始流的遍历,并且会生成一个结果,或者一个 side effect。

 

forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator

 

forEach/​forEachOrder(遍历)

forEach是并行处理的,forEachOrder是按顺序处理的,显然前者速度更快。

 

toArray(返回一个数组对象)

//toArray

Stream<Integer> arrayStream = Stream.of(1, 5, 9, 7, 3, 6, 4, 8, 2,0);

//无参,返回一个Object数组

Object[] objects = arrayStream.toArray();

//发生器函数采用一个整数,它是所需数组的大小,并产生一个所需大小的数组

//构造引用 ,限定返回数组类型

String[] strings = arrayStream.toArray(String[]::new);

 

reduce(累积-减少,总和,最小,最大,平均和字符串连接等)

 

F//reduce 减少操作

//T reduce​(T identity,BinaryOperator<T> accumulator)

// 使用提供的身份值和associative累积功能对此流的元素执行reduction ,并返回减小的值

IntStream range = IntStream.rangeClosed(1, 10);

int reduce = range.reduce(0, Integer::sum);

System.out.println(reduce);

//等价于

IntStream range1 = IntStream.rangeClosed(1, 10);

int reduce1 = range1.reduce(0, (a, b) -> a + b);

System.out.println(reduce1);

 

//Optional<T> reduce​(BinaryOperator<T> accumulator)

IntStream range2 = IntStream.rangeClosed(1, 10);

OptionalInt reduce2= range2.reduce((a, b) -> a + b);

int asInt = reduce2.getAsInt();

System.out.println(asInt);

 

collect (将Stream转换为其他数据结构)

//collect 将Stream转换为其他数据结构

//提供了两个重载的方法

 

//<R> R collect​(Supplier<R> supplier, BiConsumer<R,? super T> accumulator, BiConsumer<R,R> combiner)

//supplier:一个能创造目标类型实例的方法。

// accumulator:一个将当元素添加到目标中的方法。

// combiner:一个将中间状态的多个结果整合到一起的方法(并发的时候会用到)

IntStream stream = Arrays.stream(range(1, 10).toArray());

ArrayList<Object> collect = stream.collect(ArrayList::new, List::add, List::addAll);

System.out.println(collect.toString());

 

//<R,A> R collect​(Collector<? super T,A,R> collector)

//注:Stream的特化IntStream,LongStream,DoubleStream不具备该方法

List<String> strings = Arrays.asList("a", "b", "c", "d", "e");

//可以通过Collectors提供的静态方法返回各种数据,其实就是另一个方法的封装简化

//List->Set

Set<String> collect1 = strings.stream().collect(Collectors.toSet());

System.out.println(collect1.toString());

//List->Map

Map<String, String> collect3 = strings.stream().collect(Collectors.toMap(x -> x.toUpperCase(), y -> y.toString()));

System.out.println(collect3.toString());

 

anyMatch/allMatch/noneMatch (是否满足条件)

 

IntStream stream1 = Arrays.stream(range(1, 10).toArray());

//anyMatch 表示,判断的条件里,任意一个元素成功,返回true

System.out.println(stream1.anyMatch(x->x>5)); //返回true

 

//allMatch 表示,判断条件里的元素,所有的都是,返回true

System.out.println(stream1.allMatch(x->x>0)); //返回true

 

//noneMatch 跟allMatch相反,判断条件里的元素,所有的都不是,返回true

System.out.println(stream1.noneMatch(x->x<0)); //返回true

 

 

Short-circuiting :

 

  • 于一个 intermediate 操作,如果它接受的是一个无限大(infinite/unbounded)的 Stream,但返回一个有限的新 Stream。
  • 对于一个 terminal 操作,如果它接受的是一个无限大的 Stream,但能在有限的时间计算出结果。

当操作一个无限大的 Stream,而又希望在有限时间内完成操作,则在管道内拥有一个 short-circuiting 操作是必要非充分条件。

 

anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 limit

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章