构建一个User实体类供演示
代码语言:javascript复制public class Users {
/**
* ID
*/
private Long id;
/**
* 用户名
*/
private String name;
/**
* 年龄
*/
private int age;
/**
* 工号
*/
private String jobNumber;
/**
* 性别
*/
private String sex;
/**
* 注册时间
*/
private Date entryDate;
/**
* 成员组织
*/
private BigDecimal familyMemberQuantity;
private Long userId;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getJobNumber() {
return jobNumber;
}
public void setJobNumber(String jobNumber) {
this.jobNumber = jobNumber;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getEntryDate() {
return entryDate;
}
public void setEntryDate(Date entryDate) {
this.entryDate = entryDate;
}
public BigDecimal getFamilyMemberQuantity() {
return familyMemberQuantity;
}
public void setFamilyMemberQuantity(BigDecimal familyMemberQuantity) {
this.familyMemberQuantity = familyMemberQuantity;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
@Override
public String toString() {
return "Users{"
"id=" id
", name='" name '''
", age=" age
", jobNumber='" jobNumber '''
", sex='" sex '''
", entryDate=" DateFormatUtils.format(entryDate, "yyyy-MM-dd HH:mm:ss")
", familyMemberQuantity=" familyMemberQuantity
'}';
}
}
一、根据字段分组得到多个List集合
构建一个产生Users的静态法
代码语言:javascript复制 /**
* 生产虚拟用户
*
* @return
*/
public static List<Users> produceUser() {
List<Users> usersList = new ArrayList<>();
for (int i = 1; i <= 10; i ) {
Users users = new Users();
users.setId(Long.valueOf(i));
users.setName("kobe" i);
users.setAge(15 new Random().nextInt(5));
users.setJobNumber("jobNumber" i);
if (i % 2 == 0) {
users.setSex("男");
} else {
users.setSex("女");
}
users.setEntryDate(new Date());
users.setFamilyMemberQuantity(new BigDecimal(i));
usersList.add(users);
}
return usersList;
}
利用Java8 特性,根据对象的某个属性进行分组
代码语言:javascript复制@Test
public void groupByGender() {
List<Users> list = produceUser();
// 根据性别进行分组
Map<String, List<Users>> collect = list.stream().collect(Collectors.groupingBy(Users::getSex));
Set<Map.Entry<String, List<Users>>> entries = collect.entrySet();
entries.forEach(item -> {
// 性别 男 / 女
String gender = item.getKey();
// 男集合 / 女集合
List<Users> usersList = item.getValue();
System.out.println(gender);
usersList.forEach(user -> System.out.println(user));
});
}
输出结果如下
二、集合求和
2.1 根据对象中的某个字段求和
代码语言:javascript复制 /**
* 根据年龄字段求总和
*/
@Test
public void getSumByStream() {
List<Users> list = produceUser();
int sum = list.stream().mapToInt(Users::getAge).sum();
System.out.println("共计:" list.size() "个用户,所有年龄总和为:" sum);
// 求最大年龄
Integer integer = list.stream().map(Users::getAge).max(Integer::compareTo).get();
System.out.println(integer);
// 得到最大年龄对象
Users users = list.stream().max(Comparator.comparingInt(Users::getAge)).get();
System.out.println(users);
// 求平均年龄
System.out.println(list.stream().mapToInt(Users::getAge).average().getAsDouble());
// 求最大年龄
System.out.println(list.stream().mapToInt(Users::getAge).max().getAsInt());
}
输出结果如下
2.2 List<数值型> 求和
代码语言:javascript复制 /**
* 根据List求和
*/
@Test
public void getListSumByJava8() {
List<Integer> listInt = new ArrayList();
List<Double> listDoub = new ArrayList();
for (int i = 0; i < 500; i ) {
listInt.add(new Random().nextInt(1000));
listDoub.add(new Random().nextDouble());
}
System.out.println("=======数值型Integer求和======");
Integer integer = listInt.stream().reduce(Integer::sum).orElse(0);
System.out.println(integer);
System.out.println("=======数值型Double求和======");
Double integer1 = listDoub.stream().reduce(Double::sum).orElse(0.00);
System.out.println(integer1);
// 取最大值
System.out.println(listInt.stream().reduce(Integer::max).orElse(0));
System.out.println(listInt.stream().mapToInt(Integer::valueOf).max().getAsInt());
// 取最小值
System.out.println(listInt.stream().reduce(Integer::min).orElse(0));
// 取平均值
System.out.println(listInt.stream().mapToInt(Integer::valueOf).average().getAsDouble());
}
输出结果如下
三、遍历List集合
代码语言:javascript复制 /**
* 遍历对象
*/
@Test
public void traverseByJava8(){
List<Users> list = produceUser();
list.forEach(System.out::println);
}
输出结果如下
四、过滤List集合
代码语言:javascript复制 /**
* 过滤对象
*/
@Test
public void filterByJava8() {
List<Users> list = produceUser();
System.out.println("原始数据为:");
System.out.println("==============过滤后的数据为===============");
list.forEach(System.out::println);
//筛选出年龄大于3岁小于8岁的对象
List<Users> collect = list.stream().filter(s -> s.getAge() > 13 && s.getAge() < 18).collect(Collectors.toList());
System.out.println("过滤结束后的数据为:");
collect.forEach(System.out::println);
}
输出结果如下
五、获取List中的最大最小值
5.1 根据特定需求中的某个字段求最大最小
代码语言:javascript复制 /**
* 求最大最小值,根据业务类型选择合适的类型值
*/
@Test
public void maxOrMinByJava8() {
List<Users> list = produceUser();
//根据mapTO**得到最大最小 ---写法一
double asDouble = list.stream().mapToDouble(Users::getAge).max().getAsDouble();
System.out.println("将最大值转换为Double类型进行展示,最大为:" asDouble);
double asDouble1 = list.stream().mapToDouble(Users::getAge).min().getAsDouble();
System.out.println("将最小值转换为Double类型进行展示,最小为:" asDouble1);
int asInt = list.stream().mapToInt(Users::getAge).max().getAsInt();
System.out.println("将最大值转换为Int类型进行展示,最大为:" asInt);
//根据map得到最大最小 ---写法二(推荐)
Integer integer = list.stream().map(Users::getAge).max(Integer::compareTo).get();
System.out.println("将最大值转换为字段对应类型进行展示,最大为:" integer);
Integer integer1 = list.stream().map(Users::getAge).min(Integer::compareTo).get();
System.out.println("将最小值转换为字段对应类型进行展示,最小为:" integer1);
}
输出结果如下
5.2 根据特定需求中的某个字段求平均值
代码语言:javascript复制 /**
* 求最大最小值,根据业务类型选择合适的类型值
*/
@Test
public void avgByJava8() {
List<Users> list = produceUser();
double avgAge = list.stream().mapToDouble(Users::getAge).average().getAsDouble();
System.out.println("平均年龄为:" avgAge);
}
输出结果如下
六、根据需求将List转为Map
代码语言:javascript复制 /**
* List -> Map
* 需要注意的是:
* toMap 如果集合对象有重复的key,会报错Duplicate key ....
* user1,user2的id都为1。
* 可以用 (k1,k2)->k1 来设置,如果有重复的key,则保留key1,舍弃key2
*/
@Test
public void mapToListByJava8() {
List<Users> list = produceUser();
Map<Long, Users> map = list.stream().collect(Collectors.toMap(Users::getId, a -> a, (k1, k2) -> k1));
for (Map.Entry<Long, Users> entry : map.entrySet()) {
Long key = entry.getKey();
System.out.println("map中的key是:" key);
System.out.println("map中的value是:" entry.getValue().toString());
}
// 根据ID和年龄获得map
Map<Long, Integer> collect = list.stream().collect(Collectors.toMap(Users::getId, item -> Optional.ofNullable(item.getAge()).orElse(0)
, (k1, k2) -> k1));
System.out.println(collect.toString());
}
输出结果如下
七、List排序
代码语言:javascript复制 /**
* 排序(单字段/多字段排序)
*/
@Test
public void sortByJava8() {
List<Users> list = produceUser();
System.out.println("============未排序的数据=============");
System.out.println(list.toString());
try {
//单字段排序,根据名字排序
System.out.println("============单字段排序,根据名字排序=============");
list.sort(Comparator.comparing(Users::getName));
System.out.println(list.toString());
//多字段排序,根据年龄再根据-->名字排序
System.out.println("============多字段排序,根据年龄再根据-->名字排序=============");
list.sort(Comparator.comparing(Users::getAge, (o1, o2) -> o2 - o1).thenComparing(Users::getName));
System.out.println(list.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
输出结果如下
八、List去重
代码语言:javascript复制 /**
* 去重
*/
@Test
public void distinctByJava8() {
List<String> numList = new ArrayList();
numList.add("kevin");
numList.add("kevin");
numList.add("kevin1");
numList.add("kevin2");
numList.add("kevin1");
numList.add("kevin2");
System.out.println("===========未去重的数据============");
System.out.println(numList.toString());
System.out.println("===========去重后的数据============");
List<String> collect = numList.stream().distinct().collect(Collectors.toList());
System.out.println(collect.toString());
}
输出结果如下
九、List的合并
首先了解下交集并集差集的概念,分别有三个区域A,B,C
9.1 List的合并之—>并集
代码语言:javascript复制 /**
* 得到两个集合的并集
*/
@Test
public void listByJava8() {
List<String> list1 = new ArrayList();
list1.add("aaa");
list1.add("bbb");
list1.add("ccc");
list1.add("aaa1");
List<String> list2 = list1;
list2.add("ddd");
list2.add("aaa");
list2.add("eee");
list2.add("ccc");
list2.add("fff");
list2.add("aaa1");
list2.add("aaa2");
//根据整个对象是否一致来去重合并得到并集
System.out.println("==========并集: 集合A{1, 2, 3} 和集合B {2, 3, 4} 的并集是 {1, 2, 3, 4}==========");
System.out.println("---->并集写法一 [去重]");
System.out.println("============并集举例一:根据List去重特性合并多个Lits============");
List<String> collect = Stream.of(list1, list2).flatMap(Collection::stream).distinct().collect(Collectors.toList());
System.out.println(collect.toString());
System.out.println("---->并集写法二 ");
System.out.println("============并集举例二:根据List得到并集============");
List<String> collect1 = list1.stream().filter(s -> list2.contains(s)).distinct().collect(Collectors.toList());
System.out.println(collect1);
System.out.println("==========交集: 集合A {1,2,3} 和集合B {2,3,4} 的交集为 {2,3}。即{1,2,3}∩{2,3,4}={2,3}==========");
}
输出结果如下
9.2 List的合并之—>交集(即两个或多个list重复的元素的集合)
代码语言:javascript复制 /**
* 得到两个集合的交集
*/
@Test
public void listBingByJava8() {
System.out.println("==========交集: 集合A {1,2,3} 和集合B {2,3,4} 的交集为 {2,3}。即{1,2,3}∩{2,3,4}={2,3}==========");
List<String> list1 = new ArrayList();
list1.add("aaa");
list1.add("bbb");
list1.add("ccc");
list1.add("aaa1");
List<String> list2 = list1;
list2.add("ddd");
list2.add("aaa");
list2.add("eee");
list2.add("ccc");
list2.add("fff");
list2.add("aaa1");
list2.add("aaa2");
//合并List
List<String> collect = list1.stream().filter(s -> list2.contains(s)).collect(Collectors.toList());
System.out.println("============多个List合并后的元数据===========");
System.out.println(collect);
// 获得元素出现频率的 Map,键为元素,值为元素出现的次数
List<String> collect1 = collect.stream().collect(Collectors.toMap(a -> a, a -> 1, (a, b) -> a b))
// Set<Entry>转换为Stream<Entry>
.entrySet().stream()
// 过滤出元素出现次数大于 1 的 entry
.filter(entry -> entry.getValue() > 1)
// 获得 entry 的键(重复元素)对应的 Stream
.map(entry -> entry.getKey())
// 转化为 List并去重
.distinct().collect(Collectors.toList());
System.out.println("========合并后得到处理得到重复的数据========");
System.out.println(collect1);
}
输出结果如下