作为一个合格的程序员,如何让代码更简洁明了,提升编码速度尼。
今天跟着我一起来学习下java 8 stream 流的应用吧。
废话不多说,直入正题。
考虑以下业务场景,有四个人员信息,我们需要根据性别统计人员的姓名。
package com; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class Test { public static void main(String[] args) { List<Map<String, String>> list = new ArrayList<>(); Map<String, String> map = new HashMap<>(); map.put("userName", "张三"); map.put("age", "18"); map.put("sex", "男"); list.add(map); Map<String, String> map1 = new HashMap<>(); map1.put("userName", "李四"); map1.put("age", "20"); map1.put("sex", "女"); list.add(map1); Map<String, String> map2 = new HashMap<>(); map2.put("userName", "王五"); map2.put("age", "15"); map2.put("sex", "女"); list.add(map2); Map<String, String> map3 = new HashMap<>(); map3.put("userName", "若风"); map3.put("age", "23"); map3.put("sex", "男"); list.add(map3); //现在我们要根据性别统计人员的姓名 //初级写法 StringBuilder stringBuilder1 = new StringBuilder(); StringBuilder stringBuilder2 = new StringBuilder(); for (Map<String, String> item : list) { //指向当前下标的map System.out.println("item: " + item); if (item.get("sex").equals("男")) { //存性别为男的人员名称,以逗号隔开 stringBuilder1.append(item.get("userName")).append(","); } else { //存性别为女的人员名称,以逗号隔开 stringBuilder2.append(item.get("userName")).append(","); } } //去掉最后一个逗号 String userName_nan = stringBuilder1.deleteCharAt(stringBuilder1.length() - 1).toString(); String userName_nv = stringBuilder2.deleteCharAt(stringBuilder2.length() - 1).toString(); System.out.println("userName_nan: " + userName_nan); System.out.println("userName_nv: " + userName_nv); } }
打印记录如下:
是不是感觉代码写的不怎么优雅,那么我们开始换个姿势,用java8 Stream 流的方式来操作。
package com; import org.apache.commons.lang.StringUtils; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class Test { public static void main(String[] args) { List<Map<String, String>> list = new ArrayList<>(); Map<String, String> map = new HashMap<>(); map.put("userName", "张三"); map.put("age", "18"); map.put("sex", "男"); list.add(map); Map<String, String> map1 = new HashMap<>(); map1.put("userName", "李四"); map1.put("age", "20"); map1.put("sex", "女"); list.add(map1); Map<String, String> map2 = new HashMap<>(); map2.put("userName", "王五"); map2.put("age", "15"); map2.put("sex", "女"); list.add(map2); Map<String, String> map3 = new HashMap<>(); map3.put("userName", "若风"); map3.put("age", "23"); map3.put("sex", "男"); list.add(map3); //现在我们要根据性别统计人员的姓名 //初级写法 // StringBuilder stringBuilder1 = new StringBuilder(); // StringBuilder stringBuilder2 = new StringBuilder(); // for (Map<String, String> item : list) { // //指向当前下标的map // System.out.println("item: " + item); // if (item.get("sex").equals("男")) { // //存性别为男的人员名称,以逗号隔开 // stringBuilder1.append(item.get("userName")).append(","); // } else { // //存性别为女的人员名称,以逗号隔开 // stringBuilder2.append(item.get("userName")).append(","); // } // } // //去掉最后一个逗号 // String userName_nan = stringBuilder1.deleteCharAt(stringBuilder1.length() - 1).toString(); // String userName_nv = stringBuilder2.deleteCharAt(stringBuilder2.length() - 1).toString(); // System.out.println("userName_nan: " + userName_nan); // System.out.println("userName_nv: " + userName_nv); //java8 stream流的写法 //先定义一个Map 用来存储我们的人员姓名 Map<String, String> userNameMap = new HashMap<>(4); //装逼开始 // list.stream().map(v1 -> { //map 可以理解为new 一个新的对象,复制原来list的数据copy 到一个新的List ,用map对数据进行修改操作时,不会改变原来的对象。需要返回值!!! //v1指向当前下标的map对象 System.out.println("v1: " + v1); //定义一个新的map 用来存储人员的姓名和性别 Map<String, String> data = new HashMap<>(); map.put("userName", v1.get("userName")); map.put("sex", v1.get("sex")); return map; }).reduce(userNameMap, (a, b) -> { //a 可以理解为上一次循环的返回结果 //b 当前的循环对象 //取出当前循环的人员姓名 String thisUserName = b.get("userName"); //取出当前循环的人员性别 String thisSex = b.get("sex"); if (thisSex.equals("男")) { //取上一次循环的返回结果,第一次循环,是没有值的,第二次循环时,取得是第一次循环的返回结果,以此类推。 String val = a.get("newMenUserName"); System.out.println("val: " + val); //第一次循环时val 是没有值的,我们赋值一个空的字符串, // 第二次循环时,把第一次循环的返回的newUserName的值取出来,加上逗号,拼接当前下标的人员姓名 String newUserName = (StringUtils.isBlank(val) ? StringUtils.EMPTY : val + ",") + thisUserName; //把拼接好的人员姓名添加到map 中 System.out.println("newUserName: " + newUserName); a.put("newMenUserName", newUserName); } else { //取上一次循环的返回结果,第一次循环,是没有值的,第二次循环时,取得是第一次循环的返回结果,以此类推。 String val = a.get("newWomenUserName"); System.out.println("val: " + val); //第一次循环时val 是没有值的,我们赋值一个空的字符串, // 第二次循环时,把第一次循环的返回的newUserName的值取出来,加上逗号,拼接当前下标的人员姓名 String newUserName = (StringUtils.isBlank(val) ? StringUtils.EMPTY : val + ",") + thisUserName; System.out.println("newUserName: " + newUserName); //把拼接好的人员姓名添加到map 中 a.put("newWomenUserName", newUserName); } //返回当前循环的map return a; }); System.out.println("userNameMap: " + userNameMap); System.out.println("userName_nan: " + userNameMap.get("newMenUserName")); System.out.println("userName_nv: " + userNameMap.get("newWomenUserName")); } }
打印的值如下:
场景二、取两个List 的交集
package com; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class Test { public static void main(String[] args) { // 业务场景2:取出两个List 的数值相同的元素(交集) List<Integer> list1=new ArrayList<>(); list1.add(1); list1.add(2); list1.add(3); list1.add(4); List<Integer> list2=new ArrayList<>(); list2.add(2); list2.add(4); //交集 List<Integer> list3=new ArrayList<>(); //初级写法 for(Integer item:list1){ if(list2.contains(item)){ list3.add(item); } } System.out.println("for循环的结果"); System.out.println("list3: "+list3); System.out.println("------------------------------------------------------------"); //stream 流的写法 //v1 表示当前下标的对象 //filter 过滤掉结果为false 的数据 list3=list1.stream().filter(v1->list2.contains(v1)).collect(Collectors.toList()); System.out.println("stream循环的结果"); System.out.println("list3: "+list3); //list 本身的方法 System.out.println("------------------------------------------------------------"); System.out.println("old 数据,list1:"+list1); System.out.println("old 数据,list2:"+list2); list1.retainAll(list2); System.out.println("new 数据,list1"+list1); System.out.println("new 数据,list2"+list2); } }
打印结果:
场景三、对一个List 排序
package com; import java.util.*; import java.util.stream.Collectors; public class Test { public static void main(String[] args) { // 业务场景3:对List 排序 List<Map<String, String>> list = new ArrayList<>(); Map<String, String> map = new HashMap<>(); map.put("userName", "张三"); map.put("age", "18"); map.put("sex", "男"); list.add(map); Map<String, String> map1 = new HashMap<>(); map1.put("userName", "李四"); map1.put("age", "20"); map1.put("sex", "女"); list.add(map1); Map<String, String> map2 = new HashMap<>(); map2.put("userName", "王五"); map2.put("age", "15"); map2.put("sex", "女"); list.add(map2); Map<String, String> map3 = new HashMap<>(); map3.put("userName", "若风"); map3.put("age", "23"); map3.put("sex", "男"); list.add(map3); //stream 流的写法 System.out.println("------------------------排序前--------------------------------"); System.out.println("排序前,List :"+list); //sorted stream排序,这里我们根据年龄和姓名进行排序 //Test::age Java 8 中我们可以通过 `::` 关键字来访问类的构造方法,对象方法,静态方法。 //装逼开始 List<Map<String, String>> list2=list.stream().sorted(Comparator.comparing(Test::age).thenComparing(Comparator.comparing(Test::userName))).collect(Collectors.toList()); System.out.println(); System.out.println("------------------------排序后--------------------------------"); System.out.println("排序后,list2 :"+list2); } private static String userName(Map<String,String> map){ return map.get("userName"); } private static Integer age(Map<String,String> map){ return Integer.parseInt(map.get("age")); } }
打印结果:
总结:
原文:https://www.cnblogs.com/yunsun/p/12902150.html