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(流)的各种操作)】——————————————————————————————
推荐阅读
- 一起来学习C语言的字符串转换函数
- C语言字符函数中的isalnum()和iscntrl()你都知道吗
- C语言浮点函数中的modf和fmod详解
- C语言中的时间函数clock()和time()你都了解吗
- 概率论/统计学|随机变量 的 分布函数 与 概率密度函数 的区别
- vue组件中为何data必须是一个函数()
- iOS-Swift-map|iOS-Swift-map filter reduce、函数式编程
- R语言|R语言 函数
- 2018-05-30闭包和函数
- 函数的一些东西