java8 stream接口简介_java 8 Stream 代码清单+API介绍

https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/

构造Stream

//1. Individual values

Stream stream = Stream.of("a", "b", "c");//2. Arrays

String [] strArray = new String[] {"a", "b", "c"};

stream=Stream.of(strArray);

stream=Arrays.stream(strArray);//3. Collections

List list =Arrays.asList(strArray);

stream= list.stream();

数值流的构造

//数值流有IntStream、DoubleStream、LongStream三种,目的是为了减少封箱拆箱的花费

IntStream.of(new int[]{1, 2, 3}).forEach(System.out::println);

IntStream.range(1, 3).forEach(System.out::println);

IntStream.rangeClosed(1, 3).forEach(System.out::println);

流转化为其他数据结构

//1. Array

String[] strArray1 = stream.toArray(String[]::new);//2. Collection

List list1 =stream.collect(Collectors.toList());

List list2 = stream.collect(Collectors.toCollection(ArrayList::new));

Set set1=stream.collect(Collectors.toSet());

Stack stack1= stream.collect(Collectors.toCollection(Stack::new));//3. String

String str = stream.collect(Collectors.joining()).toString(); //joining就是把流的每一个元素连接起来,可以传入参数表示连接的时候中间的连接符号

流的操作分类

Intermediate:

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

Terminal:

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

Short-circuiting:

anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 limit

map/flatMap(映射)

//一对一的映射

List output =wordList.stream().

map(String::toUpperCase).collect(Collectors.toList());

List nums = Arrays.asList(1, 2, 3, 4);

List squareNums =nums.stream().map(n-> n *n).collect(Collectors.toList());

//一对多Stream> inputStream = Stream.of(

Arrays.asList(1), Arrays.asList(2, 3),Arrays.asList(4, 5, 6));

Stream outputStream = inputStream.flatMap(childList -> childList.stream());

所谓flat,就是降低了这个流的维度,把每一个元素拿出来组成一个新的流,所谓的使得流扁平了

filter

List output =reader.lines(). flatMap(line->Stream.of(line.split(REGEXP))).

filter(word-> word.length() > 0). collect(Collectors.toList());

//这里我reader是BufferedReader,lines方法返回每一行的数据作为一个元素,注意Stream一次性的特点,消耗之后就不能在使用看来,在处理文件相关内容的时候要格外的注意

forEach

stream.filter(p-> p.getGender() ==Person.Sex.MALE)

.forEach(p-> System.out.println(p.getName()));

forEach 方法接收一个 Lambda 表达式,然后在 Stream 的每一个元素上执行该表达式。

forEach 是 terminal 操作,因此它执行后,Stream 的元素就被“消费”掉了,你无法对一个 Stream 进行两次 terminal 运算

peek

对每个元素执行操作并返回一个新的 Stream

Stream.of("one", "two", "three", "four")

.filter(e-> e.length() > 3)

.peek(e-> System.out.println("Filtered value: " +e))

.map(String::toUpperCase)

.peek(e-> System.out.println("Mapped value: " +e))

.collect(Collectors.toList());

findFirst

一个 termimal 兼 short-circuiting 操作,它总是返回 Stream 的第一个元素,或者空。

返回值类型:Optional

reduce

提供一个起始值(种子),然后依照运算规则(BinaryOperator),和前面 Stream 的第一个、第二个、第 n 个元素组合。从这个意义上说,字符串拼接、数值的 sum、min、max、average 都是特殊的 reduce

Stream.reduce(0, (a, b) -> a+b)等价于sum()//字符串连接,concat = "ABCD"

String concat = Stream.of("A", "B", "C", "D").reduce("", String::concat);//求最小值,minValue = -3.0

double minValue = Stream.of(-1.5, 1.0, -3.0, -2.0).reduce(Double.MAX_VALUE, Double::min);//求和,sumValue = 10, 有起始值

int sumValue = Stream.of(1, 2, 3, 4).reduce(0, Integer::sum);//求和,sumValue = 10, 无起始值,这里返回的是Optional类型

sumValue = Stream.of(1, 2, 3, 4).reduce(Integer::sum).get();//过滤,字符串连接,concat = "ace"

concat = Stream.of("a", "B", "c", "D", "e", "F").

filter(x-> x.compareTo("Z") > 0).

reduce("", String::concat);

limit/skip

limit 返回 Stream 的前面 n 个元素;skip 则是扔掉前 n 个元素。

limit 和 skip 对 sorted 后的运行次数无影响,就是说你不知道sorted的结果你limit没有用,不知道从哪里limit还是一样得排序

sorted

List personList2 = persons.stream().limit(2).sorted((p1, p2) ->p1.getName().compareTo(p2.getName())).collect(Collectors.toList());

没有实现Comparable的要指定Comparable(Lumbda表达式)

min/max/distinct

BufferedReader br = new BufferedReader(new FileReader("c:\\SUService.log"));int longest =br.lines().mapToInt(String::length).max().getAsInt();

br.close();

System.out.println(longest);

List words =br.lines().flatMap(line-> Stream.of(line.split(" "))). filter(word-> word.length() > 0).

map(String::toLowerCase).distinct(). sorted(). collect(Collectors.toList());

Match

allMatch:Stream 中全部元素符合传入的 predicate,返回 true

anyMatch:Stream 中只要有一个元素符合传入的 predicate,返回 true

noneMatch:Stream 中没有一个元素符合传入的 predicate,返回 true

boolean isAllAdult =persons.stream().allMatch(p-> p.getAge() > 18);

Stream.generate

根据传入的Supplier 生成流,流的长度是无限的

Stream.iterate

iterate 跟 reduce 操作很像,接受一个种子值,和一个 UnaryOperator(例如 f)。然后种子值成为 Stream 的第一个元素,f(seed) 为第二个,f(f(seed)) 第三个,以此类推。

Stream.iterate(0, n -> n + 3).limit(10). forEach(x -> System.out.print(x + " "));.

用 Collectors 来进行 reduction 操作

java.util.stream.Collectors 类的主要作用就是辅助进行各类有用的 reduction 操作,例如转变输出为 Collection,把 Stream 元素进行归组。

Collectors .groupingBy/partitioningBy

按照条件分类,返回一个Map

把学生按照年龄进行分组,注意返回值的Map:key是分组的条件,val是符合条件的数据的集合

Map> personGroups = Stream.generate(newPersonSupplier()). limit(100). collect(Collectors.groupingBy(Person::getAge));

Iterator it=personGroups.entrySet().iterator();while(it.hasNext()) {

Map.Entry> persons =(Map.Entry) it.next();

System.out.println("Age " + persons.getKey() + " = " +persons.getValue().size());

}

partitioningBy 注意返回值的key是Boolean类型,就是把集合分成了两部分

Map> children = Stream.generate(newPersonSupplier()).

limit(100).

collect(Collectors.partitioningBy(p-> p.getAge() < 18));

System.out.println("Children number: " + children.get(true).size());

System.out.println("Adult number: " + children.get(false).size());

总之,Stream 的特性可以归纳为:

不是数据结构

它没有内部存储,它只是用操作管道从 source(数据结构、数组、generator function、IO channel)抓取数据。

它也绝不修改自己所封装的底层数据结构的数据。例如 Stream 的 filter 操作会产生一个不包含被过滤元素的新 Stream,而不是从 source 删除那些元素。

所有 Stream 的操作必须以 lambda 表达式为参数

不支持索引访问

你可以请求第一个元素,但无法请求第二个,第三个,或最后一个。不过请参阅下一项。

很容易生成数组或者 List

惰性化

很多 Stream 操作是向后延迟的,一直到它弄清楚了最后需要多少数据才会开始。

Intermediate 操作永远是惰性化的。

并行能力

当一个 Stream 是并行化的,就不需要再写多线程代码,所有对它的操作会自动并行进行的。

可以是无限的

集合有固定大小,Stream 则不必。limit(n) 和 findFirst() 这类的 short-circuiting 操作可以对无限的 Stream 进行运算并很快完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值