一、Stream流的思想
stream流是将要处理的元素集合看作是一种流的形式,通过Stream API对流进行操作
二、Stream的作用
结合了Lambda表达式,简化集合、数组的操作
三、stream的使用步骤
- 先得到一条Stream流(流水线),并把数据放上去
- 使用中间方法对流水线上的数据进行操作
- 使用终结方法对流水线上的数据进行操作。
3.1 创建Stream的方法
如果是双列集合则无法直接使用Stream流,这里可以使用KetSet()或者entrySet()方法转成单列集合再进行操作
3.2 单列集合获取String流:
public class StreamDemo1 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"a","b","c","d","e","f");
//获取一条流水线,并把集合中的元素放在流水线上
list.stream().forEach(s-> System.out.println(s));
}
}
输出结果
3.2 双列集合获取Stream流
public class StreamDemo2 {
public static void main(String[] args) {
//创建双列集合
HashMap<String,Integer> hm = new HashMap<>();
//添加数据
hm.put("a",10);
hm.put("b",20);
hm.put("c",30);
hm.put("d",40);
//第一种获取Stream流
//hm.keySet().stream().forEach(s -> System.out.print(s));
//第二种获取Stream方法
hm.entrySet().stream().forEach(s -> System.out.print(s));
}
}
运行结果
3.3 数组获取Stream流
public class StreamDemo3 {
public static void main(String[] args) {
//1.创建数组
int[] arr1 = {1,2,3,4,5,6,7,8,9};
String[] arr2 = {"a","b","c","d","e"};
//2.获取Stream流
Arrays.stream(arr1).forEach(s->System.out.print(s));
System.out.println();
System.out.println("========================");
Arrays.stream(arr2).forEach(s->System.out.print(s));
}
}
运行结果:
3.4 一堆零散的数据
注意必须是同类型的数据才可以放在流水线上
public class StreamDemo4 {
public static void main(String[] args) {
Stream.of(1,2,3,4,5,6).forEach(s-> System.out.print(s));
System.out.println();
Stream.of("a","b","c","d","e","f").forEach(s-> System.out.print(s));
}
}
运行结果
四、Stream流的中间方法
中间方法,返回的是新的Stream流,原来的Stream流只能使用一次,建议使用链式编程。
修改Stream流中的数据,不会影响原来集合或者数组中的数据。
4.1 过滤集合中的元素。
public class StringDemo5 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌","濯芷箬","李志强","张三丰","诸葛大力","王二麻子");
//要求把集合中的元素过滤,只要姓张的三字名称
list.stream().filter(s->s.startsWith("张")).filter(s->s.length()==3).forEach(s-> System.out.println(s));
}
}
运行结果:
4.2 跳过元素和获取前几个元素
运行结果为
4.3 元素去重
public class StringDemo5 {
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<>();
Collections.addAll(list1,"张无忌-11","张无忌-11","濯芷箬-20","李志强-14","张三丰-25","诸葛大力-20","王二麻子-28");
//元素去重
list1.stream().distinct().forEach(s-> System.out.print(s+" "));
}
}
运行结果:
4.4 合并两个流
public class StringDemo5 {
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<>();
Collections.addAll(list1,"张无忌","濯芷箬","李志强","张三丰","诸葛大力","王二麻子");
ArrayList<String> list2 = new ArrayList<>();
Collections.addAll(list2,"a","b","c");
//合并两个流
Stream.concat(list1.stream(),list2.stream()).forEach(s-> System.out.print(s));
}
}
运行结果
4.5 类型转换
public class StringDemo5 {
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<>();
Collections.addAll(list1,"张无忌-11","濯芷箬-20","李志强-14","张三丰-25","诸葛大力-20","王二麻子-28");
//要求只获取里面的年龄并且打印出来
list1.stream()
.map(s->Integer.parseInt(s.split("-")[1]))
.forEach(s-> System.out.print(s+" "));
}
}
运行结果
五、Stream的终结方法
注意:终结方法后无法再次使用流了
终结方法的collect方法
public class StringDemo5 {
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<>();
Collections.addAll(list1, "张无忌-男-11","濯芷箬-20","李志强-男-14","张三丰-男-25","诸葛大力-20","王二麻子-28");
//需求:把男性的名字收集到新集合中
List<String> newList = list1.stream().filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toList());
System.out.println(newList);
//收集set集合中
Set<String> newSet = list1.stream().filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toSet());
System.out.println(newSet);
//收集map集合中
Map<String,Integer> newMap = list1.stream().filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toMap(s -> s.split("-")[0],s -> Integer.parseInt(s.split("-")[2])));
System.out.println(newMap);
//不用lamabda表达式的形式
//键:姓名 值:年龄
/*
*toMap:参数一表述键的生成规则
* 参数二表述值的生成规则
*/
/**
* 参数一:
* Function接口中的R apply(T t):
* 泛型一:指定流中每一个数据的类型
* 泛型二:apply方法的返回值类型,也是新流中每一个数据的类型
* 参数二:
* Function接口中的R apply(T t):
* 泛型一:指定流中每一个数据的类型
* 泛型二:apply方法的返回值类型,也是新流中每一个数据的类型
*/
//注意:
// toMap如果收集的键是重复的,会抛出异常:java.lang.IllegalStateException:
// Duplicate key 张无忌
Map<String,Integer> newMap1 = list1.stream().filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toMap(new Function<String, String>() {
@Override
public String apply(String s) {
return s.split("-")[0];
}
}, new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return Integer.parseInt(s.split("-")[2]);
}
}));
System.out.println(newMap1);
}
}
运行结果