Stream的作用

  • 简化代码,不易出错
  • 可读性/可维护性++

什么是“流”

  • 元素一个个地被丢入流中

Stream API: 创建Stream

  • Collection.stream()
  • Stream.of()
  • String.chars()
  • IntStream.range() ```java List users = getUsers();

// 找出所有姓王的用户,获取名字列表,按年龄排序 users.stream() .filter(user -> user.name.startWith(“王”)) .sorted(comparing(User::getAge)) .map(User::getName) .collect(toList())

  1. <a name="CH5NY"></a>
  2. ## lambda和方法引用
  3. - lambda和方法引用都能配合Stream使用
  4. - 但是方法引用有名字,更清晰,逻辑可以更复杂
  5. <a name="8lOJ3"></a>
  6. ## Stream API:中间操作
  7. 仍然返回Stream的操作
  8. - filter
  9. - map
  10. - sorted
  11. - flatMap 每使用flatMap一次,降低一次维度
  12. - ...
  13. <a name="iw8T9"></a>
  14. ## Stream API: 终结操作
  15. - 返回非stream的操作,包括void
  16. - 一个流只能被消费一次
  17. - forEach
  18. - count/max/min
  19. - findFirst/findAny
  20. - anyMatch/noneMatch
  21. - collect
  22. - ...
  23. <a name="9SwX8"></a>
  24. ## Optional的用法
  25. - 是和函数式一起用的,而不是当做空指针用的
  26. - Optional一般只是作为返回值,不推荐用于函数参数
  27. ```java
  28. // 当做空指针的用法
  29. Optional<User> user = users.stream().filter(User::isSurnameWang).findAny();
  30. if (user.isPresent()) {
  31. System.out.println(user.get().getName());
  32. } else {
  33. throw new IllegalStateException();
  34. }
  35. // 函数式用法(推荐)
  36. Optional<User> optionalUser = users.stream().filter(User::isSurnameWang).findAny();
  37. optionalUser.orElseThrow(IllegalStateException::new);
  38. optionalUser.ifPresent(System.out::println);
  39. // 进一步简化
  40. Optional<User> optionalUser = users.stream().filter(User::isSurnameWang)
  41. .findAny().orElseThrow(IllegalStateException::new);
  42. optionalUser.ifPresent(System.out::println);

collector与Collectors

  • collect操作是最强大的操作,把stream的元素收集起来
  1. List<String> list = Arrays.asList("hello man", "it is about stream", "array list example");
  2. list.stream()
  3. .map(s -> s.split(""))
  4. .flatMap(Stream::of)
  5. .collect(Collectors.toList());
  • Collectors

    • toSet()/toList()/toCollection()
    • joining()
    • toMap()
    • groupingBy()/partitionBy(Predicate)
  • 实现返回TreeSet:.collect(Collectors.toCollection(TreeSet::new))

并发流

  • parallelStream()
  • 通过并发,可以提高互相独立的操作的性能
  • 在使用正确的情况下,可以获得近似线性的性能提升
  • 小心使用!性能要测试,使用时必须明确知道自己在做什么,明确没有线程不安全操作
  • 如果不能明确自己在做什么,就不要用
  1. // 统计[1, 1000_0000)之间的偶数数量
  2. // 普通流
  3. long startTime = System.currentTimeMillis();
  4. IntStream.range(1, 1000_0000).filter(i -> i % 2 == 0).count();
  5. long endTime = System.currentTimeMillis();
  6. System.out.println(endTime - startTime); // 80
  7. // 并发流
  8. long startTime1 = System.currentTimeMillis();
  9. IntStream.range(1, 1000_0000).parallel().filter(i -> i % 2 == 0).count();
  10. long endTime1 = System.currentTimeMillis();
  11. System.out.println(endTime1 - startTime1); // 33