🌈键盘敲烂,年薪30万🌈
一、概念介绍
结合了Lambda表达式,简化集合,数组的操作,可以快速过滤,筛选等等。
比如我现在要从集合里面过滤所有姓张的,只要获取到的前两个,将一种……用流就很简单
可以把流想象成车间里面的工作流,经过每道工序,最终生产出成品。
二、stream流的使用
获取stream流 -> 中间方法处理数据(筛选/处理/转换类型) -> 收集流(转为集合/数组等)
注意:
流一经使用后就销毁,所以流在收集之后该流就不能在使用了,在使用要获取新的流。
1.获取stream流的方法
①单列集合:调用stream静态方法
示例 获取流并打印输出
//单列集合获取stream流 ArrayList<String> list = new ArrayList<>(); Collections.addAll(list, "a", "b","a", "b","a", "b"); //获取单列集合流 Stream<String> stream1 = list.stream(); stream1.forEach(new Consumer<String>() { @Override public void accept(String s) { System.out.println(s); } }); //用Lambda表达式简化 list.stream().forEach(s-> System.out.println(s));
②双列集合:先转为单列集合或entry集合,再调用stream静态方法
示例 获取流并打印输出
//双列集合的stream流 HashMap<String, String> hm = new HashMap<>(); //转为keyset单列集合 hm.keySet().stream().forEach(s -> System.out.println(s)); //转为entrySet集合 hm.entrySet().stream().forEach(s-> System.out.println(s));
③数组:使用Arrays.stream方法
示例 获取流并打印输出
int[] arr = {1,2,3,4,5,6}; Arrays.stream(arr).forEach(val-> System.out.println(val));
④零散数据(同类型):
示例 获取流并打印输出
Stream.of(1,2,3,4,5).forEach(val-> System.out.println(val));
注意:
stream.of方法的形参是可变参数,也可以传入数组,但是只能传入引用数据类型的数组
int[] arr1 = {1,2,3,4}; String[] arr2 = {"aa","bb"}; //参数是可变参数类型,所以你要是传入数组,只能传入引用数据类型的数据 Stream.of(arr2).forEach(val-> System.out.println(val)); //有问题了 打印的是arr1的地址 Stream.of(arr1).forEach(val-> System.out.println(val));
2.使用中间方法处理数据
需要注意的是,流在使用终结方法后,不能再次复用,所以我们一般采用链式编程的方法
- 📕filter()方法
示例演示:筛选出集合中姓氏为张的
ArrayList<String> list = new ArrayList<>(); Collections.addAll(list, "张无忌", "张无忌","张无忌","张三丰", "周芷若", "赵敏", "杨逍", "杨坤"); //s表示每一个流中的对象 list.stream().filter(new Predicate<String>() { @Override public boolean test(String s) { return s.startsWith("张"); } }); //Lambda表达式改写 list.stream().filter(s->s.startsWith("张")).filter(s->s.length() == 3).forEach(s-> System.out.println(s));
- 📕limit()和skip()演示
示例演示:
//获取和跳过元素 //获取前3个 list.stream().limit(3).forEach(s-> System.out.println(s)); //跳过前3个 list.stream().skip(3).forEach(s -> System.out.println(s)); //获取流中的2-4个 list.stream().skip(2).limit(2).forEach(s -> System.out.println(s));
- 📕distinct()去重
distinct去重 底层是创建利用hashcode 和 equals方法
如果要操作的对象是自定义数据类型,要重写这两个方法
//distinct 去重 //元素去重,依赖hashcode 和 equals方法 //如果存储自定义的数据类型,要重写hashcode和equals方法 list.stream().distinct().forEach(s-> System.out.println(s));
- 📕map转换数据类型 重要
示例演示:将流中的String属性转为Integer类型。
/ map 转换数据类型 ArrayList<String> list = new ArrayList<>(); Collections.addAll(list, "张无忌-18", "赵敏-19"); //拿到list里面的年龄 //将string - integer类型 list.stream().map(new Function<String, Integer>() { @Override public Integer apply(String s) { String[] split = s.split("-"); return Integer.parseInt(split[1]); } }).forEach(s-> System.out.println(s)); System.out.println("------------------"); //Lambda表达式改写 list.stream().map(s->Integer.parseInt(s.split("-")[1])).forEach(s-> System.out.println(s));
- 📕concat合并两个流
示例演示:
//合并方法 //concat Stream.concat(list.stream().limit(1), list.stream().limit(2)).forEach(s-> System.out.println(s));
3.使用收集方法处理数据
------将流收集到数组中
------将流收集到集合中
------遍历 统计
- 📕foreach()和count() - 遍历和统计
ArrayList<String> list = new ArrayList<>(); Collections.addAll(list,"张无忌","张三丰", "周芷若", "赵敏", "杨逍", "杨坤"); //遍历 list.stream().forEach(s-> System.out.println(s)); //统计 long count = list.stream().count(); System.out.println(count);
- 📕collect() - 过滤数据并收集到list、set集合里
//收集所有的男性 到list集合里面 ArrayList<String> list = new ArrayList<>(); Collections.addAll(list, "张无忌-男-18", "张三丰-男-15", "周芷若-女-16", "赵敏-女-16" , "杨逍-男-19", "杨坤-男-12"); //注意这里的equals方法 不能直接用==比较 List<String> newlist1 = list.stream().filter(s -> s.split("-")[1].equals("男")) .collect(Collectors.toList()); System.out.println(newlist1); //到set集合里面 Set<String> newlist2 = list.stream().filter(s -> s.split("-")[1].equals("男")) .collect(Collectors.toSet());
- 📕toArray() - 收集到数组
String[] newarr1 = list.stream().limit(2).toArray(new IntFunction<String[]>() { @Override //value是数组的长度 public String[] apply(int value) { return new String[value]; } }); System.out.println(Arrays.toString(newarr1)); //lambda表达式改写 String[] newarr2 = list.stream().limit(2).toArray(len -> new String[len]); System.out.println(Arrays.toString(newarr2));
- 📕还是collect()
收集到map集合里面,指定键和值,键不能有重复
//收集到map集合里面 //键:姓名 值:性别 //注意 收集到map集合里面,键值不能重复 ArrayList<String> list = new ArrayList<>(); Collections.addAll(list, "张无忌-男-18", "张三丰-男-15", "周芷若-女-16", "赵敏-女-16" , "杨逍-男-19", "杨坤-男-12"); Map<String, Integer> newlist3 = list.stream().filter(s -> s.split("-")[1].equals("男")) .collect(Collectors.toMap( //第一个string代表流里面的数据,第二个string代表键的数据类型 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(newlist3); Map<String, Integer> newlist4 = list.stream() .filter(s -> "男".equals(s.split("-")[1])) .collect(Collectors.toMap( s -> s.split("-")[0] , s -> Integer.parseInt(s.split("-")[2]) )); System.out.println(newlist4);