一、Stream流的获取
1、单列集合:使用Collection中的默认方法
// 1.单列集合获取流
List<String> arrayList = new ArrayList<>();
// 使用Collection中的默认方法
arrayList.stream();
2、双列集合:无法直接使用,先要转换为单列集合
// 2.双列集合
HashMap<Integer,String> map = new HashMap<>();
// 先转换为单列集合,再使用Collection中的默认方法
map.entrySet().stream();
3、数组:使用Arrays工具类中的静态方法
// 3.数组
String[] strings = new String[10];
// 使用Arrays工具类中的静态方法
Arrays.stream(strings);
4、一堆零散数据:Stream接口中的静态方法
需要注意的是,这里的一堆零散数据,需要是同一种数据类型;另外,如果这里传入的是一个数组对象,数组对象中的元素需要是引用数据类型,如果是基本数据类型,Stream.of()会把整个数组,当做是一个元素来处理。
// 4.一对零散的数据,使用Stream中的静态方法
Stream.of("java", "C", "python");
二、Stream流的中间方法
【方法一】filter():过滤
List<String> strings = new ArrayList<>();
Collections.addAll(strings, "java", "python", "C", "C#", "C++", "Go");
// 使用stream().filter()找出包含“C”的元素并打印
strings.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.contains("C");
}
}).forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
可以lambda表达式简化代码
List<String> strings = new ArrayList<>();
Collections.addAll(strings, "java", "python", "C", "C#", "C++", "Go");
// 使用stream().filter()找出包含“C”的元素并打印
strings.stream().filter(s -> s.contains("C")).forEach(System.out::println);
【方法二】limit(long maxSize):获取前几个元素
List<String> strings = new ArrayList<>();
Collections.addAll(strings, "java", "python", "C", "C#", "C++", "Go");
// 使用stream().limit()获取前3个元素
strings.stream().limit(3).forEach(System.out::println);
【方法三】skip(long n):跳过前几个元素
List<String> strings = new ArrayList<>();
Collections.addAll(strings, "java", "python", "C", "C#", "C++", "Go");
// 使用stream().skip()跳过前2个元素
strings.stream().skip(2).forEach(System.out::println);
【方法四】distinct():元素去重,依赖(hashCode和equals方法)
因为元素是否重复依赖hashCode和equals方法,所以如果是自定义对象去重,javaBean里面需要重写hashCode和equals方法
List<String> strings = new ArrayList<>();
Collections.addAll(strings, "java", "python", "C", "C#", "C++", "Go", "C");
// 使用stream().distinct()去重
strings.stream().distinct().forEach(System.out::println);
【方法五】concat(String a, Stream b):合并a和b两个流为一个流
List<String> strings = new ArrayList<>();
Collections.addAll(strings, "java", "python", "C", "C#", "C++", "Go", "C");
List<Integer> integers = new ArrayList<>();
Collections.addAll(integers, 1, 3, 4, 5, 6, 7);
// 使用Stream.concat()合并两个流
Stream.concat(strings.stream(), integers.stream()).forEach((Consumer<Serializable>) System.out::println);
【方法六】map(Function <T, R> mapper):转换流中的数据类型
List<String> strings = new ArrayList<>();
Collections.addAll(strings, "java", "python", "C", "C#", "C++", "Go", "C");
// 转换流中的数据类型,map(s -> s.length())相当于输入(String类型),输出字符串的长度(Integer)
strings.stream().map(s -> s.length()).forEach(System.out::println);
需要注意的是,stream流中对元素的操作不会影响原集合/数组的元素内容;另外,stream流只能使用一次,所以使用stream流对元素操作,建议使用链式编程
三、Stream流的终结方法
【方法一】void forEach(Consumer action):遍历
输出打印stream流操作后的元素,上面中间方法的操作结果都是用这个方法查看的
【方法二】long count():统计
List<String> strings = new ArrayList<>();
Collections.addAll(strings, "java", "python", "C", "C#", "C++", "Go", "C");
// 统计符合过滤条件的元素并打印,注意返回的是long类型
long count = strings.stream().filter(s -> s.contains("C")).count();
System.out.println(count);
【方法三】toArray():收集流中的数据,放到数组中
需要注意接收元素的数组长度,如果长度小于符合条件元素的个数,会报错
List<String> strings = new ArrayList<>();
Collections.addAll(strings, "java", "python", "C", "C#", "C++", "Go", "C");
// 将符合条件的元素存入到集合中,需要注意数组长度,长度如果小于符合条件的元素数量会报错
String[] stringArr = strings.stream().filter(s -> s.contains("C")).toArray(value -> new String[10]);
System.out.println(Arrays.toString(stringArr));
【方法四】collect(Collector collector):收集流中的数据,放到集合中
String[] strings = {"java", "python", "C", "C#", "C++", "Go", "C"};
// 将符合条件的元素收集放到List集合里
List<String> c = Arrays.stream(strings).filter(s -> s.contains("C")).collect(Collectors.toList());
System.out.println(c);
四、Stream流的收集方法toMap()
String[] strings = {"java", "python", "C", "C#", "C++", "Go"};
// toMap()内有两个参数,所以需要new Function()方法,Funciton方法内的参数一指输入类型,参数二值输出类型
// 我这里将符合条件的字符串,以字符串内容为键,字符串的长度为值,将字符串的内容输出为Map集合
Map<String, Integer> map = Arrays.stream(strings)
.filter(s -> s.contains("C"))
// 指定Map中键的内容
.collect(Collectors.toMap(new Function<String, String>() {
@Override
public String apply(String s) {
return s;
}
// 指定Map中值的内容
}, new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return s.length();
}
}));
System.out.println(map);
可用lambda表达式简化代码
String[] strings = {"java", "python", "C", "C#", "C++", "Go"};
// toMap()内有两个参数,所以需要new Function()方法,Funciton方法内的参数一指输入类型,参数二值输出类型
// 我这里将符合条件的字符串,以字符串内容为键,字符串的长度为值,将字符串的内容输出为Map集合
Map<String, Integer> map = Arrays.stream(strings)
.filter(s -> s.contains("C"))
// 指定Map中键和值的内容
.collect(Collectors.toMap(s -> s, s -> s.length()));
System.out.println(map);
引用
https://www.bilibili.com/video/BV1yW4y1Y7Ms/?p=36&share_source=copy_web&vd_source=8d1a3172aa5ba3ea7bdfa82e535732a8
【P36-39】