作为一个合格的程序员,如何让代码更简洁明了,提升编码速度尼。
今天跟着我一起来学习下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