官网地址: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() − 为集合创建并行流。

  1. List<String> items = Arrays.asList("1", "2", "3", "4", "5");
  2. items.stream().filter(i -> !i.isEmpty()).collect(Collectors.toList());

1.3 forEach

Stream 提供了新的方法 forEach来迭代流中的每个数据。
遍历一个list:

  1. List<String> items = Arrays.asList("1", "2", "3", "4", "5");
  2. items.forEach(item -> System.out.print(item));
  3. //或者
  4. items.forEach(System.out::println);

遍历一个map:

  1. Map<String, String> map = new HashMap<>();
  2. map.put("a", "1");
  3. map.put("b", "2");
  4. map.put("c", "3");
  5. map.put("d", "4");
  6. map.put("e", "5");
  7. map.forEach((k, v) -> System.out.println("key:" + k + " value:" + v));

1.4 map

map 方法用于映射每个元素到对应的结果(允许你把 object 转化成其他对象)
将一个List里面的字符转换成大写字母:

  1. class Person {
  2. private Integer id;
  3. private String name;
  4. private Integer age;
  5. public Person(Integer id, String name, Integer age) {
  6. this.id = id;
  7. this.name = name;
  8. this.age = age;
  9. }
  10. public Person() {
  11. }
  12. public Integer getId() {
  13. return id;
  14. }
  15. public void setId(Integer id) {
  16. this.id = id;
  17. }
  18. public String getName() {
  19. return name;
  20. }
  21. public void setName(String name) {
  22. this.name = name;
  23. }
  24. public Integer getAge() {
  25. return age;
  26. }
  27. public void setAge(Integer age) {
  28. this.age = age;
  29. }
  30. @Override
  31. public String toString() {
  32. return "Person{" +
  33. "id=" + id +
  34. ", name='" + name + '\'' +
  35. ", age=" + age +
  36. '}';
  37. }
  38. }
  39. public void map() {
  40. List<Person> list = Arrays.asList(new Person(1, "zhangsan", 18), new Person(2, "lisi", 19), new Person(3, "wangwu", 20));
  41. List namList = list.stream().map(x -> x.getName().toUpperCase()).collect(Collectors.toList());
  42. System.out.println(namList);
  43. }

输出:

  1. [ZHANGSAN, LISI, WANGWU]

objects List转化为 其他 objects List

  1. List<Person> list = Arrays.asList(new Person(1, "zhangsan", 18), new Person(2, "lisi", 19), new Person(3, "wangwu", 20));
  2. List<Person> otherList = list.stream().map(x -> {
  3. Person p = new Person();
  4. p.setId(x.getId());
  5. p.setName(x.getName());
  6. p.setAge(x.getAge());
  7. if ("lisi".equals(x.getName())) {
  8. p.setName("zhaoliu");
  9. }
  10. return p;
  11. }).collect(Collectors.toList());
  12. System.out.println(otherList);

输出:

  1. [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 方法过滤出空字符串:

  1. List<String> items = Arrays.asList("1", "2", "3", "4", "5");
  2. List filterList = items.stream().filter(i -> "4".equals(i)).collect(Collectors.toList());
  3. System.out.println("filterList:"+filterList);

输出:

  1. filterList:[4]

1.6 limit

limit 方法用于获取指定数量的流。
输出list中的三个元素:

  1. List<String> items = Arrays.asList("1", "2", "3", "4", "5");
  2. List limitList = items.stream().limit(3).collect(Collectors.toList());
  3. System.out.println(limitList);

输出:

  1. [1, 2, 3]

1.7 sorted

sorted 方法用于对流进行排序。
对list进行排序:

  1. List<String> items = Arrays.asList("1", "3", "5", "2", "4");
  2. //正序
  3. List sortedList = items.stream().sorted().collect(Collectors.toList());
  4. //倒序
  5. List sortedList2 = items.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
  6. System.out.println(sortedList);
  7. System.out.println(sortedList2);

输出:

  1. [1, 2, 3, 4, 5]
  2. [5, 4, 3, 2, 1]

对集合对象进行排序:

  1. List<Person> persionList = Arrays.asList(new Person(2, "zhangsan", 18), new Person(1, "lisi", 19), new Person(3, "wangwu", 20));
  2. //正序
  3. List pList = persionList.stream().sorted(Comparator.comparing(x -> x.id)).collect(Collectors.toList());
  4. //或者
  5. List pList2 = persionList.stream().sorted(Comparator.comparing(Person::getId)).collect(Collectors.toList());
  6. //倒序
  7. List pList3 = persionList.stream().sorted(Comparator.comparing(Person::getId).reversed()).collect(Collectors.toList());
  8. System.out.println(pList);
  9. System.out.println(pList2);
  10. System.out.println(pList3);

输出:

  1. [Person{id=1, name='lisi', age=19}, Person{id=2, name='zhangsan', age=18}, Person{id=3, name='wangwu', age=20}]
  2. [Person{id=1, name='lisi', age=19}, Person{id=2, name='zhangsan', age=18}, Person{id=3, name='wangwu', age=20}]
  3. [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 来输出空字符串的数量:

  1. List<String> items = Arrays.asList("1", "2", "3", "4", "5");
  2. Long count=items.parallelStream().filter(x->x.isEmpty()).count();
  3. System.out.println(count);

1.9 Collectors

Collectors 类实现了很多归约操作,例如将流转换成集合和聚合元素。Collectors可用于返回列表或字符串:

  1. List<String> items = Arrays.asList("1", "2", "3", "4", "5");
  2. List list=items.stream().filter(x->!x.isEmpty()).collect(Collectors.toList());
  3. String s=items.stream().filter(x->!x.isEmpty()).collect(Collectors.joining(";"));
  4. System.out.println(list);
  5. System.out.println(s);

输出:

  1. [1, 2, 3, 4, 5]
  2. 1;2;3;4;5

1.10 统计

另外,一些产生统计结果的收集器也非常有用。它们主要用于int、double、long等基本类型上,它们可以用来产生类似如下的统计结果。

  1. List<String> items = Arrays.asList("1", "2", "3", "4", "5");
  2. IntSummaryStatistics iss =items.stream().mapToInt(x->Integer.parseInt(x)).summaryStatistics();
  3. System.out.println(iss.getMax());
  4. System.out.println(iss.getMin());
  5. System.out.println(iss.getAverage());
  6. System.out.println(iss.getSum());

输出:

  1. 5
  2. 1
  3. 3.0
  4. 15