官网地址:https://www.oracle.com/java/technologies/javase/8-whats-new.html
Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。
Stream使用一种类似用SQL语句从数据库查询数据的直观方式来提供一种对Java集合运算和表达的高阶抽象。
Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
这种风格将要处理的元素集合看作一种流,流在管道中传输,并且可以在管道的节点上进行处理,比如筛选,排序,聚合等。
元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。
1.1什么是 Stream?
Stream(流)是一个来自数据源的元素队列并支持聚合操作
元素:是特定类型的对象,形成一个队列。Java中的Stream并不会存储元素,而是按需计算。
数据源 :流的来源。可以是集合,数组,I/O channel,产生器generator等。
聚合操作: 类似SQL语句一样的操作,比如filter, map, reduce, find,match, sorted等。
和以前的Collection操作不同,Stream操作还有两个基础的特征:
Pipelining::中间操作都会返回流对象本身。这样多个操作可以串联成一个管道,如同流式风格(fluent style)。这样做可以对操作进行优化,比如延迟执行(laziness)和短路( short-circuiting)。
内部迭代:以前对集合遍历都是通过Iterator或者For-Each的方式,显式的在集合外部进行迭代,这叫做外部迭代。Stream提供了内部迭代的方式,通过访问者模式(Visitor)实现。
1.2 生成流
在Java 8中,集合接口有两个方法来生成流:
stream() −为集合创建串行流。
parallelStream() − 为集合创建并行流。
List<String> items = Arrays.asList("1", "2", "3", "4", "5");items.stream().filter(i -> !i.isEmpty()).collect(Collectors.toList());
1.3 forEach
Stream 提供了新的方法 forEach来迭代流中的每个数据。
遍历一个list:
List<String> items = Arrays.asList("1", "2", "3", "4", "5");items.forEach(item -> System.out.print(item));//或者items.forEach(System.out::println);
遍历一个map:
Map<String, String> map = new HashMap<>();map.put("a", "1");map.put("b", "2");map.put("c", "3");map.put("d", "4");map.put("e", "5");map.forEach((k, v) -> System.out.println("key:" + k + " value:" + v));
1.4 map
map 方法用于映射每个元素到对应的结果(允许你把 object 转化成其他对象)
将一个List
class Person {private Integer id;private String name;private Integer age;public Person(Integer id, String name, Integer age) {this.id = id;this.name = name;this.age = age;}public Person() {}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "Person{" +"id=" + id +", name='" + name + '\'' +", age=" + age +'}';}}public void map() {List<Person> list = Arrays.asList(new Person(1, "zhangsan", 18), new Person(2, "lisi", 19), new Person(3, "wangwu", 20));List namList = list.stream().map(x -> x.getName().toUpperCase()).collect(Collectors.toList());System.out.println(namList);}
输出:
[ZHANGSAN, LISI, WANGWU]
objects List转化为 其他 objects List
List<Person> list = Arrays.asList(new Person(1, "zhangsan", 18), new Person(2, "lisi", 19), new Person(3, "wangwu", 20));List<Person> otherList = list.stream().map(x -> {Person p = new Person();p.setId(x.getId());p.setName(x.getName());p.setAge(x.getAge());if ("lisi".equals(x.getName())) {p.setName("zhaoliu");}return p;}).collect(Collectors.toList());System.out.println(otherList);
输出:
[Person{id=1, name='zhangsan', age=18}, Person{id=2, name='zhaoliu', age=19}, Person{id=3, name='wangwu', age=20}]
1.5 filter
filter 方法用于通过设置条件过滤出元素。以下代码片段使用filter 方法过滤出空字符串:
List<String> items = Arrays.asList("1", "2", "3", "4", "5");List filterList = items.stream().filter(i -> "4".equals(i)).collect(Collectors.toList());System.out.println("filterList:"+filterList);
输出:
filterList:[4]
1.6 limit
limit 方法用于获取指定数量的流。
输出list中的三个元素:
List<String> items = Arrays.asList("1", "2", "3", "4", "5");List limitList = items.stream().limit(3).collect(Collectors.toList());System.out.println(limitList);
输出:
[1, 2, 3]
1.7 sorted
sorted 方法用于对流进行排序。
对list进行排序:
List<String> items = Arrays.asList("1", "3", "5", "2", "4");//正序List sortedList = items.stream().sorted().collect(Collectors.toList());//倒序List sortedList2 = items.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());System.out.println(sortedList);System.out.println(sortedList2);
输出:
[1, 2, 3, 4, 5][5, 4, 3, 2, 1]
对集合对象进行排序:
List<Person> persionList = Arrays.asList(new Person(2, "zhangsan", 18), new Person(1, "lisi", 19), new Person(3, "wangwu", 20));//正序List pList = persionList.stream().sorted(Comparator.comparing(x -> x.id)).collect(Collectors.toList());//或者List pList2 = persionList.stream().sorted(Comparator.comparing(Person::getId)).collect(Collectors.toList());//倒序List pList3 = persionList.stream().sorted(Comparator.comparing(Person::getId).reversed()).collect(Collectors.toList());System.out.println(pList);System.out.println(pList2);System.out.println(pList3);
输出:
[Person{id=1, name='lisi', age=19}, Person{id=2, name='zhangsan', age=18}, Person{id=3, name='wangwu', age=20}][Person{id=1, name='lisi', age=19}, Person{id=2, name='zhangsan', age=18}, Person{id=3, name='wangwu', age=20}][Person{id=3, name='wangwu', age=20}, Person{id=2, name='zhangsan', age=18}, Person{id=1, name='lisi', age=19}]
1.8 并行(parallel)程序
parallelStream 是流并行处理程序的代替方法。以下实例我们使用parallelStream 来输出空字符串的数量:
List<String> items = Arrays.asList("1", "2", "3", "4", "5");Long count=items.parallelStream().filter(x->x.isEmpty()).count();System.out.println(count);
1.9 Collectors
Collectors 类实现了很多归约操作,例如将流转换成集合和聚合元素。Collectors可用于返回列表或字符串:
List<String> items = Arrays.asList("1", "2", "3", "4", "5");List list=items.stream().filter(x->!x.isEmpty()).collect(Collectors.toList());String s=items.stream().filter(x->!x.isEmpty()).collect(Collectors.joining(";"));System.out.println(list);System.out.println(s);
输出:
[1, 2, 3, 4, 5]1;2;3;4;5
1.10 统计
另外,一些产生统计结果的收集器也非常有用。它们主要用于int、double、long等基本类型上,它们可以用来产生类似如下的统计结果。
List<String> items = Arrays.asList("1", "2", "3", "4", "5");IntSummaryStatistics iss =items.stream().mapToInt(x->Integer.parseInt(x)).summaryStatistics();System.out.println(iss.getMax());System.out.println(iss.getMin());System.out.println(iss.getAverage());System.out.println(iss.getSum());
输出:
513.015
