Java8函数式编程之七(Stream(流)的各种操作)

上篇博客对流的基础知识进行了介绍,本篇博客将着重介绍关于流的各种操作,使用很多的实例代码,你只需要将其放进你的main函数中就能运行。
——————————————
创建流:

public class StreamTest1 { public static void main(String[] args){ //流的创建方式 //1. Stream stream1 = Stream.of("hello","world","hello world"); //2. String[] array = new String[]{"hello","world"}; Stream stream2 = Stream.of(array); //3. Stream stream3 = Arrays.stream(array); //4.通过结合创建,最常见的方式 List list = Arrays.asList(array); Stream stream4 = list.stream(); }}

————————————————
IntStream.of(new int[]{3,4,5,4,3,2,3,4,4,22,4}).forEach(System.out :: println); //range()方法,范围 [3,6) IntStream.range(3,8).forEach(System.out :: println); //rangeClosed()方法,范围[3,8] IntStream.rangeClosed(3,8);

————————————————————
//map()方法,映射 List list = Arrays.asList(1,2,3,4,5); System.out.print(list.stream().map(i -> i * 2).reduce(0,Integer :: sum));

————————————————————————
//构造流 Stream stream = Stream.of("hello","world"); //遍历流 String[] array = stream.toArray(length -> new String[length]); //方法引用 String[] array1 = stream.toArray(String[] :: new); Arrays.asList(array).forEach(System.out ::println); Arrays.asList(array1).forEach(System.out :: println);

————————————————————————————
Stream stream = Stream.of("hello","world"); //将流转换为一个List List list = stream.collect(Collectors.toList()); list.forEach(System.out :: println);

————————————————————————————
//将流转换为Set Stream stream = Stream.of("hello","world"); Set set = stream.collect(Collectors.toCollection(TreeSet ::new)); set.forEach(System.out :: println);

——————————————————
//拼接字符串 Stream stream = Stream.of("hello","world"); String str = stream.collect(Collectors.joining()).toString(); System.out.print(str);

————————————————————————
//将集合中的每个元素转换为大写 List list = Arrays.asList("hello","world","hello world"); list.stream().map(str -> str.toUpperCase()).collect(Collectors.toList()).forEach(System.out :: println);

————————————————
//flatMap 将每个List都平平方,再将其作为一个整体输出,也就是一个List。 Stream> stream = Stream.of(Arrays.asList(1,2),Arrays.asList(3,4,5),Arrays.asList(7,8,9)); stream.flatMap(theList -> theList.stream()).map(item -> item * item).forEach(System.out :: println);

————————————————
// generate()方法 Stream stream = Stream.generate(UUID.randomUUID()::toString); stream.findFirst().ifPresent(System.out::println); // iterate方法 Stream.iterate(1, item -> item + 2).limit(6).forEach(System.out::println);

——————————————
// 找出流中大于2的元素,然后将每个元素乘以2,然后忽略掉流中的前两个元素, // 再取流中的前两个元素,最后求出流中元素的总和 Stream stream = Stream.iterate(1, item -> item + 2).limit(6); System.out.println(stream.filter(item -> item > 2).mapToInt(item -> item * 2).skip(2).limit(2).sum());

——————————————
// 找出流中大于2的元素,然后将每个元素乘以2,然后忽略掉流中的前两个元素, // 再取流中的前两个元素,最后求出流中最小的元素 // 注意 min()返回的是int的包装类型 OptionalInt // 这样的区别在于返回的值是否能够为空,下面这种会抛出异常 System.out.println(stream.filter(item -> item > 2).mapToInt(item -> item * 2).skip(2).limit(2).min());

——————————————————
List list = Arrays.asList("hello", "world", "hello world"); //将集合的每个单词首字母变大写后输出 list.stream().map(item -> item.substring(0, 1).toUpperCase() + item.substring(1)).forEach(System.out :: println); //下面没有任何输出 因为map操作是惰性求值的,也就是在没有遇到终止操作之前,是不会求值的。惰性求值 list.stream().map(item -> { String result = item.substring(0, 1).toUpperCase() + item.substring(1); System.out.println("test"); return result; }); //下面将会有输出 。因为有终止信号 forEach()立即求值 list.stream().map(item -> { String result = item.substring(0, 1).toUpperCase() + item.substring(1); System.out.println("test"); return result; }).forEach(System.out::println);

————————————————————
流的短路与并发流:
//对比串行流与并行流 List list = new ArrayList<>(5000000); for (int i = 0; i < 5000000; ++i) { list.add(UUID.randomUUID().toString()); } System.out.println("开始排序"); long startTime = System.nanoTime(); // 时间更精确// 串行流 // list.stream().sorted().count(); //花费9s ,只有一个线程// 并行流 list.parallelStream().sorted().count(); // 花费5s , 多个线程long endTime = System.nanoTime(); long millis = TimeUnit.NANOSECONDS.toMillis(endTime - startTime); System.out.println("排序耗时: " + millis);

————————————————————————
流的短路:
// 将列表中长度为5的单词的长度打印出来。 List list = Arrays.asList("hello", "world", "hello world"); list.stream().mapToInt(item -> item.length()).filter(length -> length == 5).findFirst().ifPresent(System.out :: println); // 对比下面的方式 list.stream().mapToInt(item -> { int length = item.length(); System.out.println(item); return length; }).filter(length -> length == 5).findFirst().ifPresent(System.out::println); /* * 打印的结果 hello 5 这其实就是流的短路。找到了符合条件的,其他的就不再执行。 */

——————————————————————————
// 找出所有单词,并且去重.
List list = Arrays.asList("hello welcome", "world hello", "hello world hello", "hello welcome"); // 输出的是四个数组对象 list.stream().map(item -> item.split(" ")).distinct().collect(Collectors.toList()).forEach(System.out :: println); // 应该使用flatMap . flatMap()的作用在于打平 List reList = list.stream().map(item -> item.split(" ")).flatMap(Arrays::stream).distinct() .collect(Collectors.toList()); reList.forEach(System.out::println);

————————————————
流的分组与分区:
Student student1 = new Student("zhangsan", 100, 20); Student student2 = new Student("lisi", 90, 20); Student student3 = new Student("wangwu", 50, 30); Student student4 = new Student("lisi", 90, 25); // 根据名字进行分组 /* * F 传统的方式 Map> 1.循环列表 2.取出学生的名字 * 3.检查map中是否存在该名字,不存在直接加到map中.存在则将map中的list对象取出来,然后将 student对象加到List中 * */// jdk8中提供的分组方式, 和SQL中的分组是一样的概念// 把对象加在流中 List> students = Arrays.asList(student1, student2, student3, student4); // 实现分组 Map> map = students.stream().collect(Collectors.groupingBy(Student::getName)); // 方法引用System.out.println(map); // 根据分数分组Map> map1 = students.stream().collect(Collectors.groupingBy(Student::getScore)); // 方法引用System.out.println(map1); // 求每个分组后的平均值Map map3 = students.stream() .collect(Collectors.groupingBy(Student::getName, Collectors.averagingDouble(Student::getScore))); System.out.println(map3); // 分区: partition by .分区是分组的特殊情况。结果只会有两组 Map> map4 = students.stream() .collect(Collectors.partitioningBy(student -> student.getScore() > 90)); System.out.println(map4);

【Java8函数式编程之七(Stream(流)的各种操作)】——————————————————————————————

    推荐阅读