接上篇文章 java8 新特性 由于上篇过于庞大,使得重点不够清晰,本篇单独拿出 java8 的 Stream 重点说明 ,并做了点补充。
java.util.Collection
接口的默认方法 stream
或者 parallelStream
java.util.Arrays
的方法 stream
将数组变成流 Stream 分为中间操作和后期操作,中期操作会形成一个新的 Stream ,但不会马上对数据进行处理,到后期操作时,再遍历整个集合;可以没有中期操作直接后期操作。
forEach,collect,reduce,anyMatch,allMatch,noneMatch,findFirst 等;
其中属 collect 最为常用,还有一个专门用于 collect 的 Collectors 类,可以用于将集合转成 List,Set,Map 等
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor public class Vehicle { //车架号 private String vin; // 车主手机号 private String phone; // 车主姓名 private String name; // 所属车租车公司 private Integer companyId; // 个人评分 private Double score; //安装的设备列表imei,使用逗号分隔 private String deviceNos; }
static List<Vehicle> vehicles = new ArrayList<>(); @Before public void init(){ List<String> imeis = new ArrayList<>(); for (int i = 0; i <5 ; i++) { List<String> singleVehicleDevices = new ArrayList<>(); for (int j = 0; j < 3; j++) { String imei = RandomStringUtils.randomAlphanumeric(15); singleVehicleDevices.add(imei); } imeis.add(StringUtils.join(singleVehicleDevices,',')); } vehicles.add(new Vehicle("KPTSOA1K67P081452","17620411498","9420",1,4.5,imeis.get(0))); vehicles.add(new Vehicle("KPTCOB1K18P057071","15073030945","张玲",2,1.4,imeis.get(1))); vehicles.add(new Vehicle("KPTS0A1K87P080237","19645871598","sanri1993",1,3.0,imeis.get(2))); vehicles.add(new Vehicle("KNAJC526975740490","15879146974","李种",1,3.9,imeis.get(3))); vehicles.add(new Vehicle("KNAJC521395884849","13520184976","袁绍",2,4.9,imeis.get(4))); }
vehicles.forEach(vehicle -> System.out.println(vehicle)); //这样就可以遍历打印 vehicles.forEach(System.out::println);
Map<String,Integer> map = new HashMap<>(); map.put("a",1);map.put("b",2);map.put("c",3); map.forEach((k,v) -> System.out.println("key:"+k+",value:"+v));
// 去掉评分为 3 分以下的车 List<Vehicle> collect = vehicles.stream().filter(vehicle -> vehicle.getScore() >= 3).collect(Collectors.toList());
对一个 List<Object>
大部分情况下,我们只需要列表中的某一列,或者需要把里面的每一个对象转换成其它的对象,这时候可以使用 map 映射,示例:
// 取出所有的车架号列表 List<String> vins = vehicles.stream().map(Vehicle::getVin).collect(Collectors.toList());
// 按照公司 Id 进行分组 Map<Integer, List<Vehicle>> companyVehicles = vehicles.stream().collect(Collectors.groupingBy(Vehicle::getCompanyId)); // 按照公司分组求司机打分和 Map<Integer, Double> collect = vehicles.stream().collect(Collectors.groupingBy(Vehicle::getCompanyId, Collectors.summingDouble(Vehicle::getScore)));
// 单列排序 vehicles.sort((v1,v2) -> v2.getScore().compareTo(v1.getScore())); // 或使用 Comparator 类来构建比较器,流处理不会改变原列表,需要接收返回值才能得到预期结果 List<Vehicle> collect = vehicles.stream().sorted(Comparator.comparing(Vehicle::getScore).reversed()).collect(Collectors.toList()); // 多列排序,score 降序,companyId 升序排列 List<Vehicle> collect = vehicles.stream().sorted(Comparator.comparing(Vehicle::getScore).reversed() .thenComparing(Comparator.comparing(Vehicle::getCompanyId))) .collect(Collectors.toList());
// 查出所有车绑定的所有设备 List<String> collect = vehicles.stream().map(vehicle -> { String deviceNos = vehicle.getDeviceNos(); return StringUtils.split(deviceNos,','); }).flatMap(Arrays::stream).collect(Collectors.toList());
flatMap 很适合 List<List>
或 List<object []>
这种结构,可以当成一个列表来处理;像上面的设备列表,在数据库中存储的结构就是以逗号分隔的数据,而车辆列表又是一个列表数据。
// 将 List 转成 Map ; key(vin) == > Vehicle Map<String, Vehicle> vinVehicles = vehicles.stream().collect(Collectors.toMap(Vehicle::getVin, vehicle -> vehicle));
// 对所有司机的总分求和 Double reduce = vehicles.stream().parallel().map(Vehicle::getScore).reduce(0d, Double::sum);
// 总的分值 Double totalScore = vehicles.stream().parallel().map(Vehicle::getScore).reduce(0d, Double::sum); // 查看每一个司机占的分值比重 List<String> collect = vehicles.stream() .mapToDouble(vehicle -> vehicle.getScore() / totalScore) .mapToLong(weight -> (long) (weight * 100)) .mapToObj(percentage -> percentage + "%") .collect(Collectors.toList());
// 检查是否有姓李的司机 true boolean anyMatch = vehicles.stream().anyMatch(vehicle -> vehicle.getName().startsWith("李")); // 检查是否所有司机的评分都大于 3 分 false boolean allMatch = vehicles.stream().allMatch(vehicle -> vehicle.getScore() > 3); // 检查是否有 3 公司的特务 true boolean noneMatch = vehicles.stream().noneMatch(vehicle -> vehicle.getCompanyId() == 3);
创作不易,希望可以支持下我的开源软件,及我的小工具,欢迎来 gitee 点星,fork ,提 bug 。
Excel 通用导入导出,支持 Excel 公式
博客地址: https://blog.csdn.net/sanri1993/article/details/100601578
gitee: https://gitee.com/sanri/sanri-excel-poi
使用模板代码 ,从数据库生成代码 ,及一些项目中经常可以用到的小工具
博客地址: https://blog.csdn.net/sanri1993/article/details/98664034
gitee: https://gitee.com/sanri/sanri-tools-maven