Stream流
Stream流
1|0体验Stream流
- Stream流一般配合Lamda表达式使用
- 函数式编程
- 通过字面意思即可展示无关逻辑的语句
public class Demo { public static void main(String[] args) { //创建集合,存储多个字符串元素 ArrayList<String> list = new ArrayList<>(); list.add("张三丰"); list.add("李白"); list.add("王二"); list.add("张译"); list.add("马文才"); list.add("张怀民"); //创建新集合,以存储“张”开头的元素 ArrayList<String> zhang = new ArrayList<>(); for (String s : list) { if (s.startsWith("张")){ zhang.add(s); } } //创建新集合,以存储“张”开头的长度为3的元素 ArrayList<String> zhangSan = new ArrayList<>(); for (String s : zhang) { if (s.length()==3){ zhangSan.add(s); } } //遍历集合 for (String s : zhangSan) { System.out.println(s); } } }
运行结果:
张三丰 张怀民
不难看出,代码过长且重复度过高;通过Stream流改进
public class Demo { public static void main(String[] args) { //创建集合,存储多个字符串元素 ArrayList<String> list = new ArrayList<>(); list.add("张三丰"); list.add("李白"); list.add("王二"); list.add("张译"); list.add("马文才"); list.add("张怀民"); //使用Stream和方法引用改进 list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(System.out::println); } }
运行结果:
张三丰 张怀民
2|0Stream流的生成方式
2|1Stream流的使用
- 生成流
通过数据源生成流
如:list.stream()- 中间操作
一个流后面可以跟多个中间操作
如:filter()
如:filter().filter()- 终结操作
一个流只能有一个终结操作
如:forEach()
2|2Stream流的常见生成方式
public class Demo1 { public static void main(String[] args) { //Collection体系的集合,使用默认方法stream()生成流 ArrayList<String> list = new ArrayList<>(); Stream<String> listStream = list.stream(); HashSet<String> set = new HashSet<>(); Stream<String> setStream = set.stream(); //Map体系集合,间接生成流 HashMap<String, String> map = new HashMap<>(); //键的流 Stream<String> keyStream = map.keySet().stream(); //值的流 Stream<String> valueStream = map.values().stream(); //键值对对象的流 Stream<Map.Entry<String, String>> entryStream = map.entrySet().stream(); //数组通过Stream接口的静态方法of(T... values)生成流 String[] strArr = {"hello","world","java"}; //of中的参数可变 Stream<String> strArrStream = Stream.of(strArr); Stream<String> strArrStream1 = Stream.of("hello","world","java"); Stream<Integer> strArrStream2 = Stream.of(10,20,33); } }
3|0Stream流中间操作
- 以Stream开头的语句,做了终结操作之后,就不能再次开始;否则会报错。
- 以数据源开始转为stream流的语句,做了终结操作之后,还可以再次以数据源开始做操作
3|1filter
public class Demo { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("张三丰"); list.add("李白"); list.add("王二"); list.add("张译"); list.add("马文才"); list.add("张怀民"); //输出“张”开头的元素 list.stream().filter(s -> s.startsWith("张")).forEach(System.out::println); System.out.println("----------------"); //输出长度为3的元素 list.stream().filter(s -> s.length() == 3).forEach(System.out::println); System.out.println("----------------"); //输出“张”开头,并且长度为3的元素 list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(System.out::println); } }
运行结果:
张三丰 张译 张怀民 ---------------- 张三丰 马文才 张怀民 ---------------- 张三丰 张怀民
3|2limit & skip
public class Demo { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("张三丰"); list.add("李白"); list.add("王二"); list.add("张译"); list.add("马文才"); list.add("张怀民"); //输出前3个元素 list.stream().limit(3).forEach(System.out::println); System.out.println("-------------"); //输出除了前3个元素以外的元素 list.stream().skip(3).forEach(System.out::println); System.out.println("-------------"); //跳过前2个元素,输出接下来的2个元素 list.stream().skip(2).limit(2).forEach(System.out::println); } }
运行结果:
张三丰 李白 王二 ------------- 张译 马文才 张怀民 ------------- 王二 张译
3|3concat & distinct
public class Demo2 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("张三丰"); list.add("李白"); list.add("王二"); list.add("张译"); list.add("马文才"); list.add("张怀民"); //需求1:获取前4个元素,组成一个流 Stream<String> s1 = list.stream().limit(4); //需求2:跳过2个元素,组成一个流 Stream<String> s2 = list.stream().skip(2); //需求3:合并需求1和需求2的流,输出 //Stream.concat(s1,s2).forEach(System.out::println); //需求4:合并需求1和需求2的流,输出,要求字符串元素不能重复 Stream.concat(s1,s2).distinct().forEach(System.out::println); } }
运行结果:
张三丰 李白 王二 张译 马文才 张怀民
3|4sorted
public class Demo3 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("libai"); list.add("yangyuhuan"); list.add("wuzetian"); list.add("zhaohuaizhen"); list.add("sikongzhen"); list.add("shangguanwaner"); //需求1:按照字母顺序输出数据 list.stream().sorted().forEach(System.out::println); System.out.println("------------"); //需求2:按照字符串长度输出数据 list.stream().sorted((s1, s2) -> s1.length() - s2.length()).forEach(System.out::println); System.out.println("------------"); //需求3:按照字符串长度输出数据,长度相同时自然排序 list.stream().sorted((s1, s2) -> { int num = s1.length() - s2.length(); int num2 = num == 0 ? s1.compareTo(s2) : num; return num2; }).forEach(System.out::println); } }
运行结果:
libai shangguanwaner sikongzhen wuzetian yangyuhuan zhaohuaizhen ------------ libai wuzetian yangyuhuan sikongzhen zhaohuaizhen shangguanwaner ------------ libai wuzetian sikongzhen yangyuhuan zhaohuaizhen shangguanwaner
3|5map & mapToInt
Stream流调用了mapToInt()方法,就会变成IntStream流
IntStream流可以调用sum()方法
public class Demo4 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("10"); list.add("20"); list.add("30"); list.add("40"); list.add("50"); //需求:使用map()将集合中的字符串转为整数后输出 list.stream().map(s -> Integer.parseInt(s)).forEach(System.out::println); System.out.println("-----------"); //方法引用 list.stream().map(Integer::parseInt).forEach(System.out::println); System.out.println("-----------"); //需求2:使用mapToInt()将集合中的字符串转为整数后输出 list.stream().mapToInt(Integer::parseInt).forEach(System.out::println); System.out.println("-----------"); //需求3:使用IntStream()中的sum(),返回int元素的总和,输出结果 System.out.println(list.stream().mapToInt(Integer::parseInt).sum()); } }
运行结果:
10 20 30 40 50 ----------- 10 20 30 40 50 ----------- 10 20 30 40 50 ----------- 150
4|0Stream流常见的终结操作方法
4|1forEach & count
public class Demo5 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("张三丰"); list.add("李白"); list.add("王二"); list.add("张译"); list.add("马文才"); list.add("张怀民"); //需求1:输出集合中的元素 list.stream().forEach(System.out::println); //需求1:统计以“张”开头的元素,输出统计结果 System.out.println(list.stream().filter(s -> s.startsWith("张")).count()); } }
运行结果:
张三丰 李白 王二 张译 马文才 张怀民 3
5|0综合练习
public class Demo6 { public static void main(String[] args) { ArrayList<String> list1 = new ArrayList<>(); list1.add("马保国"); list1.add("陈龙"); list1.add("张丰毅"); list1.add("胡歌"); list1.add("李永健"); list1.add("赵本山"); ArrayList<String> list2 = new ArrayList<>(); list2.add("林黛玉"); list2.add("刘亦菲"); list2.add("陶虹"); list2.add("宋佳"); list2.add("林心如"); list2.add("张嘉倪"); //男演员只要名字为三个字的前3人 Stream<String> man = list1.stream().filter(s -> s.length() == 3).limit(3); //女演员只要姓林的,并且不要第一个 Stream<String> women = list2.stream().filter(s -> s.startsWith("林")).skip(1); //把man和women合并在一起 Stream<String> concat = Stream.concat(man, women); //将concat中的元素作为构造方法的参数,创建对象,遍历数据 concat.map(Actor::new).forEach(s-> System.out.println(s.getName())); } }
运行结果:
马保国 张丰毅 李永健 林心如
6|0收集操作
将流中的数据存入集合
public class Demo6 { public static void main(String[] args) { ArrayList<String> arrayList = new ArrayList<>(); arrayList.add("马保国"); arrayList.add("陈龙"); arrayList.add("张丰毅"); arrayList.add("胡歌"); arrayList.add("李永健"); arrayList.add("张择端"); //需求1:以流的方式拿到以“张”开头的元素, Stream<String> strStream = arrayList.stream().filter(s -> s.startsWith("张")); //需求2:将流收集到list集合,并遍历集合 List<String> list = strStream.collect(Collectors.toList()); for (String s : list) { System.out.println(s); } System.out.println("------"); HashSet<Integer> hashSetset = new HashSet<>(); hashSetset.add(10); hashSetset.add(20); hashSetset.add(30); hashSetset.add(33); hashSetset.add(35); //需求3:获取大于25的元素 Stream<Integer> setStream = hashSetset.stream().filter(s -> s > 25); //需求4:将流收集到set集合,并遍历 Set<Integer> set = setStream.collect(Collectors.toSet()); for (Integer i : set) { System.out.println(i); } } }
运行结果:
张丰毅 张择端 ------ 33 35 30
public class Demo6 { public static void main(String[] args) { String[] str = {"张艺兴,11","刘强东,29","朱之文,33","高启强,28"}; //需求1:获取年龄大于28的元素 Stream<String> stringStream = Stream.of(str).filter(s -> Integer.parseInt(s.split(",")[1]) > 28); //需求2:把流存入Map集合,并遍历 Map<String, Integer> map = stringStream.collect(Collectors.toMap(s -> s.split(",")[0], s -> Integer.parseInt(s.split(",")[1]))); for (Map.Entry<String, Integer> entry : map.entrySet()) { System.out.println(entry.getKey() + "-" + entry.getValue()); } } }
运行结果:
朱之文-33 刘强东-29
__EOF__

本文作者:茶碗儿
本文链接:https://www.cnblogs.com/chawaner/p/17110081.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文链接:https://www.cnblogs.com/chawaner/p/17110081.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix