好记性-烂笔头:JDK8流操作
1):对象 List<User> 转 Map<String,Object>
案例如下:
public class User {
private Integer id;
private String age;
User(Integer id, String age) {
this.id = id;
this.age = age;
}
}
List<User> userList = new ArrayList<User>() {{
add(new User(1, "1111"));
add(new User(1, "1111"));
add(new User(2, "2222"));
}};
// 方式一(不推荐):遇到重复的 id 值。 会抛异常 java.lang.IllegalStateException: Duplicate key User
Map<Integer, User> maps = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
// 方式二:(推荐)
Map<Integer, User> maps = userList.stream().collect(Collectors.toMap(User::getId, Function.identity(), (key1, key2) -> key2));
2):================START=======================
测试数据如下:
public class TestStreamModel implements Serializable {
private int id;
private String name;
private int grade;
private int classes;
private double score;
public TestStreamModel(int id, String name, int grade, int classes, double score) {
this.id = id;
this.name = name;
this.grade = grade;
this.classes = classes;
this.score = score;
}
get|set...省略
@Override
public String toString() {
return "TestStreamModel{" +
"id=" + id +
", name='" + name + '\'' +
", grade=" + grade +
", classes=" + classes +
", score=" + score +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TestStreamModel that = (TestStreamModel) o;
return id == that.id &&
grade == that.grade &&
classes == that.classes &&
Double.compare(that.score, score) == 0 &&
Objects.equals(name, that.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name, grade, classes, score);
}
}
// 初始化数据
List<TestStreamModel> list = new ArrayList<TestStreamModel>() {{
add(new TestStreamModel(1, "李四", 1, 1, 60));
add(new TestStreamModel(2, "张三", 1, 1, 80));
add(new TestStreamModel(3, "王二麻子", 1, 2, 90));
add(new TestStreamModel(4, "王五", 1, 3, 59.5));
add(new TestStreamModel(5, "小红", 2, 2, 99));
add(new TestStreamModel(6, "小白", 2, 1, 88.8));
add(new TestStreamModel(7, "小黑", 2, 2, 45));
add(new TestStreamModel(8, "小明", 1, 1, 79.5));
add(new TestStreamModel(8, "小明", 1, 1, 79.5));
}};
测试数据
2-1):去重-去除重复对象(每个属性的值都一样的),需要注意的是要先重写对象 TestStreamModel 的 equals 和 hashCode 方法
System.out.println("集合数量:" + list.size() + "-->每个属性的值都一样的-->去重前:" + list);
List<TestStreamModel> distinctList = list.stream().distinct().collect(Collectors.toList());
System.out.println("集合数量:" + distinctList.size() + "-->每个属性的值都一样的-->去重后:" + distinctList);
2-2):去重,去除重复对象(根据对象其中一个属性进行去重)
ArrayList<TestStreamModel> collect = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(TestStreamModel::getId))), ArrayList::new));
2-3):排序,按id升续排列,如果要降续则改成:(a, b) -> b.getId() - a.getId(); a和b都是变量名(可以按自己意愿取名字),都是list中的对象的实例
List<TestStreamModel> sortList = list.stream().sorted((a, b) -> a.getId() - b.getId()).collect(Collectors.toList());
2-4):过滤,按照自己的需求来筛选list中的数据,比如我筛选出不及格的(小于60分)的人,t为实例
List<TestStreamModel> filterList = list.stream().filter(t -> t.getScore() < 60).collect(Collectors.toList());
2-5):Map, 提取对象中的某一元素,例子中我取的是每个人的name,注意list中类型对应,如果取的是id或者班级,就应该是integer类型
List<String> mapList = list.stream().map(t -> t.getName()).collect(Collectors.toList());
2-6):统计,统计所有人分数的和, 主要我设置的分数属性是double类型的,所以用mapToDouble,如果是int类型的,则需要用mapToInt
double sum = list.stream().mapToDouble(t -> t.getScore()).sum();
int count = list.stream().mapToInt(t -> t.getId()).sum();
2-7):分组, 按照字段中某个属性将list分组
Map<Integer, List<TestStreamModel>> map = list.stream().collect(Collectors.groupingBy(t -> t.getGrade()));
System.out.println("按年级分组" + map);
/*然后再对map处理,这样就方便取出自己要的数据*/
for (Map.Entry<Integer, List<TestStreamModel>> entry : map.entrySet()) {
System.out.println("key:" + entry.getKey());
System.out.println("value:" + entry.getValue());
}
2-8):多重分组,先按年级分组,再按班级分组
Map<Integer/*年级id*/, Map<Integer/*班级id*/, List<TestStreamModel>>> groupMap = list.stream().collect(Collectors.groupingBy(t -> t.getGrade(), Collectors.groupingBy(t -> t.getClasses())));
System.out.println("按照年级再按班级分组:" + groupMap);
System.out.println("取出一年级一班的list:" + groupMap.get(1).get(1));
2-9):多重分组,一般多重分组后都是为了统计,比如说统计每个年级,每个班的总分数
Map<Integer/*年级id*/, Map<Integer/*班级id*/, Double>> sumMap = list.stream().collect(Collectors.groupingBy(t -> t.getGrade(), Collectors.groupingBy(t -> t.getClasses(), Collectors.summingDouble(t -> t.getScore()))));
System.out.println(sumMap);
System.out.println("取出一年级一班的总分:" + sumMap.get(1).get(1));
2-10):多重分组,一般多重分组后都是为了统计,比如说统计每个年级,每个班的总分数
Map<Integer/*年级*/, Map<Integer/*班级*/, Long/*人数*/>> integerMap = list.stream().filter(t -> t.getScore() >= 60).collect(Collectors.groupingBy(t -> t.getGrade(), Collectors.groupingBy(t -> t.getClasses(), Collectors.counting())));
System.out.println("取出一年级一班及格人数:" + integerMap.get(1).get(1));
2-11):逗号拼接,去重 将每个ID以逗号方式拼接 & 对象重写 equals和hashCode
String dou = list.stream().distinct().map(mark -> mark.getId().toString()).filter(x -> !ObjectUtils.isEmpty(x)).collect(Collectors.joining(","));
System.out.println("逗号拼接,将每个ID以逗号方式拼接:={}"+dou);
2-12):limit 返回前几个元素信息 获取大于50前三位学生信息
Collections.sort(list, Comparator.comparing(TestStreamModel::getScore).reversed());// 倒序排列,删除 reversed()为正序
List<TestStreamModel> models = list.stream().filter(a -> a.getScore() > 50).limit(3).collect(Collectors.toList());
System.out.println("limit 获取大于50分的前三位学生:={}"+models);
2-13):skip 获取跳过几个元素后的信息 获取大于50前三位学生信息
Collections.sort(list, Comparator.comparing(TestStreamModel::getScore).reversed());// 倒序排列,删除 reversed()为正序
List<TestStreamModel> model = list.stream().filter(a -> a.getScore() > 50).skip(3).collect(Collectors.toList());
System.out.println("limit 获取大于50分的前三位学生:={}"+model);
=====================END========================
3-1):flatMap
flatMap与map的区别在于* flatMap是将一个流中的每个值都转成一个个流,然后再将这些流扁平化成为一个流 。
举例说明,假设我们有一个字符串数组String[] strs = {"java8", "is", "easy", "to", "use"};
我们希望输出构成这一数组的所有非重复字符,那么我们可能首先会想到如下实现:
String[] strs = {"java8", "java8", "is", "easy", "to", "use"};
List<String[]> distinctStrs = Arrays.stream(strs)
.map(str -> str.split("")) // 映射成为Stream<String[]>
.distinct()
.collect(Collectors.toList());
System.out.println("映射处理flatMap:操作之后的数据为{}:");
distinctStrs.stream().forEach(ex -> {
System.out.println(Arrays.stream(ex).collect(Collectors.joining(",")));
});
返回结果:
j,a,v,a,8
j,a,v,a,8
i,s
e,a,s,y
t,o
u,s,e
distinct只有对于一个包含多个字符的流进行操作才能达到我们的目的,即对Stream<String>进行操作。此时flatMap就可以达到我们的目的:
List<String> dis = Arrays.stream(strs)
.map(str -> str.split("")) // 映射成为Stream<String[]>
.flatMap(Arrays::stream) // 扁平化为Stream<String>
.distinct()
.collect(Collectors.toList());
System.out.println("映射处理flatMap:操作之后的数据为{}:");
dis.stream().forEach(s1 -> System.out.print(s1)); 返回结果:jav8iseytou
4-1):allMatch : 查询所有学生成绩是否都大于 44 分
boolean isAdult = list.stream().allMatch(student -> student.getScore() >= 44);// 满足返回 true
System.out.println("查找 allMatch:" + isAdult);
4-2):anyMatch :查询所有学生是否有成绩是否都大于 44 分
boolean hasWhu = list.stream().anyMatch(student -> student.getScore() >= 98);// 满足返回 false
System.out.println("查找 anyMatch:" + hasWhu);
4-3):noneMatch :查询所有学生是否不存在大于98分的
boolean noneCs = list.stream().noneMatch(student -> student.getScore() >= 98); // 不存在返回 true ,否则 false
System.out.println("查找 noneMathch:" + noneCs);
4-4):findFirst : 查询满足条件排在第一位的学生信息
TestStreamModel findFirst = list.stream().filter(student -> student.getScore() >= 60).findFirst().orElse(new TestStreamModel());
System.out.println("查找 findFirst:" + findFirst);
4-5):findAny : 查询满足条件随机一个的学生信息
TestStreamModel findAny = list.stream().filter(student -> student.getScore() >= 60).findAny().orElse(new TestStreamModel());
System.out.println("查找 findAny:" + findAny);
5-1): list 对象 根据时间排序
public class TestObject implements Serializable {
private Date startTime;
private Integer id;
public TestObject(Date startTime, Integer id) {
this.startTime = startTime;
this.id = id;
}
public TestObject() {
}
}
List<TestObject> objectList = new ArrayList<TestObject>() {{
add(new TestObject(DateUtils.parseDate("2019-10-10 10:10:10", DateUtils.DEFAULT_TIME_FORMAT), 1));
add(new TestObject(DateUtils.parseDate("2019-10-11 10:10:10", DateUtils.DEFAULT_TIME_FORMAT), 2));
add(new TestObject(DateUtils.parseDate("2019-10-12 10:10:10", DateUtils.DEFAULT_TIME_FORMAT), 3));
add(new TestObject(DateUtils.parseDate("2019-10-09 10:10:10", DateUtils.DEFAULT_TIME_FORMAT), 4));
add(new TestObject(DateUtils.parseDate("2019-10-04 10:10:10", DateUtils.DEFAULT_TIME_FORMAT), 5));
add(new TestObject(DateUtils.parseDate("2019-10-22 10:10:10", DateUtils.DEFAULT_TIME_FORMAT), 6));
}};
测试数据
倒序:
// 倒序
Collections.sort(objectList, new Comparator<TestObject>() {
@Override
public int compare(TestObject o1, TestObject o2) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date dt1 = o1.getStartTime();
Date dt2 = o2.getStartTime();
if (dt1.getTime() < dt2.getTime()) {
return 1;
} else if (dt1.getTime() > dt2.getTime()) {
return -1;
} else {
return 0;
}
} catch (Exception e) {
System.err.println("排列时间报错" + e.getMessage() + e);
}
return 0; }
});
System.out.println("倒序:={}"+ JSON.toJSONString(objectList));
正序:
// 正序
Collections.sort(objectList, new Comparator<TestObject>() {
@Override
public int compare(TestObject o1, TestObject o2) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date dt1 = o1.getStartTime();
Date dt2 = o2.getStartTime();
if (dt1.getTime() > dt2.getTime()) {
return 1;
} else if (dt1.getTime() < dt2.getTime()) {
return -1;
} else {
return 0;
}
} catch (Exception e) {
System.err.println("排列时间报错" + e.getMessage() + e);
}
return 0; }
});
System.out.println("正序:={}"+ JSON.toJSONString(objectList));
好记性-烂笔头:JDK8流操作的更多相关文章
- jdk8 流操作
二.流 2.1 流介绍 流是Java API的新成员,它允许你以声明性方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现).就现在来说,你可以把它们看成遍历数据集的高级迭代器.此外,流还可以 ...
- 好记性-烂笔头:controller-接收参数方式及注意事项
长时间未使用的传参方式很容易遗忘 或 记忆混乱,虽然都很简单 但往往都是一些小细节打败了你. 小编决定要把他们记录下来. 1):@RequestBody 接收参数 及 注意事项 注意事项: @Requ ...
- JDK8 Steam流操作
原文:https://github.com/niumoo/jdk-feature/blob/master/src/main/java/net/codingme/feature/jdk8/Jdk8Str ...
- 【烂笔头】git常用命令篇
前言 常言道,好记性不如烂笔头,更何况笔者的记性也不是太好,于是就有了这篇“烂笔头”系列之一的git命令记录.本篇主要记录了笔者在工作当中使用过的相关命令,以方便平时查看,同时也供同行们参考.当然,读 ...
- 【java多线程】java8的流操作api和fork/join框架
原文:https://blog.csdn.net/u011001723/article/details/52794455/ 一.测试一个案例,说明java8的流操作是并行操作 1.代码 package ...
- Common lang一些边界方法总结(好记性不如烂笔头,需要慢慢积累).一定要利用好现有的轮子,例如Apache common与Google Guava
好记性真是不如烂笔头啊!!!! 如下代码: List<String> list = new ArrayList<String>(); list.add("1" ...
- 还看不懂同事的代码?超强的 Stream 流操作姿势还不学习一下
Java 8 新特性系列文章索引. Jdk14都要出了,还不能使用 Optional优雅的处理空指针? Jdk14 都要出了,Jdk8 的时间处理姿势还不了解一下? 还看不懂同事的代码?Lambda ...
- 超强的Lambda Stream流操作
原文:https://www.cnblogs.com/niumoo/p/11880172.html 在使用 Stream 流操作之前你应该先了解 Lambda 相关知识,如果还不了解,可以参考之前文章 ...
- Node学习笔记(一):stream流操作
NodeJs中谈及较多的可能就是Stream模块了,先写一个简单的ajax回调 $.post("index.php",{data:'aaa',order:'ccc'},functi ...
随机推荐
- 【Mood】在COVID-19疫情中
看完网课(这还得从一只蝙蝠说起...),本来准备刷几道题. 还是来记录下这次事件吧. 2月1号,病毒感染人数破万. 接下来4天(今日6号)疫情走向爆发期. 每日平均新增发病人数达到了3000~4000 ...
- 记一次手机与PC同步开发Android项目
目录 -1 前言 0.0 流程简介 1.0 AS创建项目并上传GitHub 2.0 AIDE克隆GitHub项目 能力不足时曲线救国 > 3.0 termux编译AIDE目录下的项目文件 3.1 ...
- PKI详解
预备: 一.密码基元 二.密钥管理 三.PKI本质是把非对称密钥管理标准化 PKI 是 Public Key Infrastructure 的缩写,其主要功能是绑定证书持有者的身份和相关的密钥对(通过 ...
- fsLayuiPlugin联动表格使用(一)
简单联动表格使用 点击主表格,加载副表格数据, 演示地址:http://fslayuiplugin.fallsea.com/views/linkageDatagrid/index.html 联动表格配 ...
- vue 不用npm下载安装包 该如何引用js
公司电脑不让用npm ,vue的项目要使用moment.js, 用了各种script 引用,总是报错 正确的方式应该为: import {moment} from ‘moment.js ’ 不可以全 ...
- c++中比较好用的黑科技
切入正题,上黑科技 一.黑科技函数(常用的我就不写了,例如sort函数) 1.next_permutation(a+1,a+1+n) a[1-n]全排列 2.reverse(a+1,a+1+n) 将a ...
- def跨域+jwt
1.跨域 由于浏览器具有“同源策略”的限制.如果在同一个域下发送ajax请求,浏览器的同源策略不会阻止.如果在不同域下发送ajax,浏览器的同源策略会阻止. 总结 域相同,永远不会存在跨域. crm, ...
- flask连接数据库的URI书写格式
1. MySQL mysql://username:password@hostname/database 2. PostgreSQL postgresql://username:password@ho ...
- [项目分享]JSP+Servlet+JDBC实现的云端汽修后台管理系统
本文存在视频版本,请知悉 项目简介 项目来源于:https://gitee.com/chenlinSir/CloudDemo-servlet 难度等级:简单 基于JSP+Servlet+Jdbc的云端 ...
- Android UI性能测试——使用 Gfxinfo 衡量性能
Android官方文档翻译 原文地址:https://developer.android.com/training/testing/performance参考:https://www.jianshu. ...