package com.lyc.collections;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.LongSummaryStatistics;
import java.util.Map;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* lambda表达式测试
*
* @author lyc
* @date 2021/8/5
*/
public class LycLambdaCollections {
/**
* 1、遍历list集合
*
* @param list
*/
public static void foreachColl(List<Employee> list) {
System.out.println("--------------------------------------------------------------");
list.forEach(employee -> {
System.out.println(employee.toString());
});
}
/**
* 2、获取集合中对象的某一个属性的集合
*/
public static void getOnlyIdList(List<Employee> list) {
System.out.println("getOnlyIdList result===========================");
List<Long> idList = list.stream().map(employee -> employee.getId()).collect(Collectors.toList());
System.out.println("firstMethod employee -> employee.getId():");
System.out.println(idList.toString());
System.out.println("");
System.out.println("secondMethod Employee::getId:");
List<Long> idListTwo = list.stream().map(Employee::getId).collect(Collectors.toList());
System.out.println(idListTwo);
}
/**
* 3、获取集合中对象的某一个属性的集合并对属性做类型转换
*
* @param list
*/
public static void getOneFiledWithDeal(List<Employee> list) {
List<Long> deptNoList = list.stream().map(employee -> employee.getDeptNo()).map(Long::valueOf).collect(Collectors.toList());
System.out.println(deptNoList.toString());
}
/**
* 4、将数组元素做其他处理后转成list集合
*
* @param list
*/
public static void getOneFiledFromArray(List<Employee> list) {
List<String> nameList = list.stream().map(employee -> employee.getName()).collect(Collectors.toList());
String str = String.join(",", nameList);
List<String> upperNameList = Arrays.stream(str.split(",")).map(String::toUpperCase).collect(Collectors.toList());
System.out.println(upperNameList.toString());
}
/**
* 5、将集合对象按<集合中对象的某个属性、对象本身>转成map----->简单分组,key为对象一个属性值,值为对象本身
*
* @param list
*/
public static void groupByIdForObjectMap(List<Employee> list) {
Map<Long, Employee> map = list.stream().collect(Collectors.toMap(Employee::getId, employee -> employee));
System.out.println(map);
}
/**
* 6、将集合对象按<集合中对象的某个属性、集合中对象的另一个个属性>转map----->简单分组2,key为对象一个属性值,值为对象的某一个属性值
*
* @param list
*/
public static void groupByIdForOneFiledMap(List<Employee> list) {
Map<Long, String> map = list.stream().collect(Collectors.toMap(Employee::getId, Employee::getName));
System.out.println(map);
}
/**
* 7、将集合对象按<集合中对象的某个属性、集合中对象的另一个个属性>转map----->简单分组3,key为对象一个属性值,值为对象的某一个属性值
* (这种场景存在key重复的需要指定用哪个覆盖哪个)
*
* @param list
*/
public static void groupByRepeatNameForOneFiledMap(List<Employee> list) {
// 保留前面的元素
Map<String, Long> map1 = list.stream().collect(Collectors.toMap(Employee::getName, Employee::getId, (k1, k2) -> k1));
System.out.println(map1);
// 用后面的元素覆盖
Map<String, Long> map2 = list.stream().collect(Collectors.toMap(Employee::getName, Employee::getId, (k1, k2) -> k2));
System.out.println(map2);
}
/**
* 8、将集合对象按<对象的某个属性、List<对象本身>>转map------>复杂分组,key为对象一个属性值,值为对象集合
*
* @param list
*/
public static void groupByIdForListObjectMap(List<Employee> list) {
Map<String, List<Employee>> map = list.stream().collect(Collectors.groupingBy(Employee::getDeptNo));
System.out.println(map);
}
/**
* 9、将集合对象按<对象的某个属性、List<对象的某个属性>>转map------>复杂分组2,key为对象一个属性值,值为对象的一个属性值集合
*
* @param list
*/
public static void groupByIdForOneFiledListMap(List<Employee> list) {
Map<String, List<Long>> map = list.stream().collect(Collectors.groupingBy(Employee::getDeptNo, Collectors.mapping(Employee::getId, Collectors.toList())));
System.out.println(map);
}
/**
* 10、将集合对象按<对象的某个属性、List<对象的某个属性>>转map------>复杂分组3,key为对象一个属性值,值为对象的一个属性值集合
* (这个写法需要保证key唯一,使用场景是将唯一key的对象其他多个属性合并为集合)
*
* @param list
*/
public static void groupByIdForManyFiledListMap(List<Employee> list) {
Map<Long, List<Long>> map = list.stream().collect(Collectors.toMap(Employee::getId, employee -> Arrays.asList(employee.getId(), 2L)));
System.out.println(map);
}
/**
* 11、求所有的薪资总和,返回一个值------>求和
*
* @param list
*/
public static void sumAll(List<Employee> list) {
// 先将list转成stream流
// 获取salary
// 自定义计算salary总和
// 第一个参数表示求和的初始值、第二个参数表示上一步求和的中间值以及本次要计算的值(subNum,salary) 实现就是将求和的中间值与本次的值相加
Long totalSum = list.stream().map(Employee::getSalary).reduce(0L, (subNum, salary) -> (subNum + salary));
System.out.println(totalSum);
Long totalSum2 = list.stream().map(Employee::getSalary).reduce(0L, Long::sum);
System.out.println(totalSum2);
Long totalSum3 = list.stream().mapToLong(Employee::getSalary).sum();
System.out.println(totalSum3);
// 测试备份下BigDecimal类型的求和
BigDecimal totalQty = list.stream().map(p -> p.getTestQty().multiply(p.getTestQty())).reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println(totalSum3);
}
/**
* 12、将集合中的对象按某个属性分组,并对每个分组中对象的另一个属性求和------>分组并求和
*
* @param list
*/
public static void sumGroupById(List<Employee> list) {
Map<String, LongSummaryStatistics> map = list.stream().collect(Collectors.groupingBy(Employee::getDeptNo, Collectors.summarizingLong(Employee::getSalary)));
System.out.println(map);
Map<String, Long> map2 = list.stream().collect(Collectors.groupingBy(Employee::getDeptNo, Collectors.summingLong(Employee::getSalary)));
System.out.println(map2);
Map<String, Long> map3 = list.stream().collect(Collectors.groupingBy(Employee::getDeptNo, Collectors.reducing(0L, Employee::getSalary, Long::sum)));
System.out.println(map3);
}
/**
* 13、求集合中的对象按某个属性最小值------>求最小值
*
* @param list
*/
public static void minAll(List<Employee> list) {
Long min = list.stream().mapToLong(Employee::getSalary).min().getAsLong();
System.out.println(min);
Long min2 = list.stream().min(Comparator.comparing(Employee::getSalary)).get().getSalary();
System.out.println(min2);
Long min3 = list.stream().collect(Collectors.minBy(Comparator.comparing(Employee::getSalary))).get().getSalary();
System.out.println(min3);
}
/**
* 14、将集合中的对象按某个属性分组,并对每个分组中对象的另一个属性求最小值------>分组并求最小值
*
* @param list
*/
public static void minGroupBy(List<Employee> list) {
Map<String, Employee> map = list.stream()
.collect(Collectors.toMap(Employee::getDeptNo, Function.identity(), BinaryOperator.minBy(Comparator.comparing(Employee::getSalary))));
System.out.println(map);
}
/**
* 15、将集合中的对象按多个条件过滤,返回过滤后的对象集合------>多条件过滤
* 年龄小于30且薪资大于6000的
*
* @param list
*/
public static void filterByCondition(List<Employee> list) {
list = list.stream().filter(employee -> employee.getAge() < 30 && employee.getSalary() > 6000).collect(Collectors.toList());
foreachColl(list);
}
/**
* 16、按一个条件正序排列------>正序排
* 按年龄从小到达排序
*
* @param list
*/
public static void sortOneConditionNature(List<Employee> list) {
List<Employee> list1 = list.stream().sorted((o1, o2) -> o1.getAge() - o2.getAge()).collect(Collectors.toList());
foreachColl(list1);
List<Employee> list2 = list.stream().sorted(Comparator.comparing(Employee::getAge)).collect(Collectors.toList());
foreachColl(list2);
}
/**
* 17、按多个条件都正序排列------>正序正序排 【两个都正不加reversed()】
* 按年龄从小到达排序,再按薪水从小到大排序
*
* @param list
*/
public static void sortTwoConditionAllNature(List<Employee> list) {
List<Employee> list1 = list.stream().sorted((o1, o2) -> {
int flag = o1.getAge() - o2.getAge();
if (flag == 0) {
flag = (int) (o1.getSalary() - o2.getSalary());
}
return flag;
}).collect(Collectors.toList());
foreachColl(list1);
List<Employee> list2 = list.stream().sorted(Comparator.comparing(Employee::getAge).thenComparing(Employee::getSalary)).collect(Collectors.toList());
foreachColl(list2);
}
/**
* 18、按一个条件倒序排列----->倒序排
* 按年龄从大到小排序
*
* @param list
*/
public static void sortOneConditionReverse(List<Employee> list) {
List<Employee> list1 = list.stream().sorted((o1, o2) -> o2.getAge() - o1.getAge()).collect(Collectors.toList());
foreachColl(list1);
List<Employee> list2 = list.stream().sorted(Comparator.comparing(Employee::getAge,Comparator.reverseOrder())).collect(Collectors.toList());
foreachColl(list2);
List<Employee> list3 = list.stream().sorted(Comparator.comparing(Employee::getAge).reversed()).collect(Collectors.toList());
foreachColl(list3);
}
/**
* 19、按多个条件都倒序排列---->倒序倒序排 【两个都倒序在最后面加一个reversed()即可】
* 按年龄从大到小排序,再按薪水从大到小排
*
* @param list
*/
public static void sortTwoConditionAllReverse(List<Employee> list) {
List<Employee> list1 = list.stream().sorted((o1, o2) -> {
int flag = o2.getAge() - o1.getAge();
if (flag == 0) {
flag = (int) (o2.getSalary() - o1.getSalary());
}
return flag;
}).collect(Collectors.toList());
foreachColl(list1);
List<Employee> list2 = list.stream().sorted(Comparator.comparing(Employee::getAge, Comparator.reverseOrder()).thenComparing(Employee::getSalary, Comparator.reverseOrder()))
.collect(Collectors.toList());
foreachColl(list2);
List<Employee> list3 = list.stream().sorted(Comparator.comparing(Employee::getAge).thenComparing(Employee::getSalary).reversed()).collect(Collectors.toList());
foreachColl(list3);
}
/**
* 20、按多个条件先正序排再倒序排---->先正序后倒序【先正加reversed(),后倒加reversed()】
* 按年龄从小到大,再按薪水从大到小排序
*
* @param list
*/
public static void sortTwoConditionOneNatureOneReverse(List<Employee> list) {
List<Employee> list1 = list.stream().sorted(Comparator.comparing(Employee::getAge).thenComparing(Employee::getSalary,Comparator.reverseOrder())).collect(Collectors.toList());
foreachColl(list1);
List<Employee> list2 = list.stream().sorted(Comparator.comparing(Employee::getAge).reversed().thenComparing(Employee::getSalary).reversed()).collect(Collectors.toList());
foreachColl(list2);
}
/**
* 21、按多个条件先倒序排再正序排---->先倒序后正序【先倒序的加reserved(),后正序的不加】
* 按年龄从大到小,再按薪水从小到大排序
*
* @param list
*/
public static void sortTwoConditionOneReverseOneNature(List<Employee> list) {
List<Employee> list1 = list.stream().sorted(Comparator.comparing(Employee::getAge,Comparator.reverseOrder()).thenComparing(Employee::getSalary)).collect(Collectors.toList());
foreachColl(list1);
List<Employee> list2 = list.stream().sorted(Comparator.comparing(Employee::getAge).reversed().thenComparing(Employee::getSalary)).collect(Collectors.toList());
foreachColl(list2);
}
/**
* 22、取集合元素的某几个值去重后转集合----->抽取对象多个值转集合去重
* 求所有人的地址集合,去重
*
* @param list
*/
public static void getMultiToSet(List<Employee> list) {
List<String> list1 = list.stream().flatMap(e -> Stream.of(e.getFmAddress(), e.getToAddress())).distinct().collect(Collectors.toList());
System.out.println(list1);
}
/**
* 23、根据集合元素的某些信息组装新对象---->对象A组装对象B返回
* 抽取用户ID、姓名、部门信息返回简单对象DTO
*
* @param list
*/
public static void getNewList(List<Employee> list) {
List<SimpleEmpDto> list1 = list.stream().map(e -> {
SimpleEmpDto dto = new SimpleEmpDto();
dto.setId(e.getId());
dto.setName(e.getName());
dto.setDeptNo(e.getDeptNo());
return dto;
}).collect(Collectors.toList());
list1.forEach(dto -> System.out.println(dto));
}
public static void main(String[] args) {
List<Employee> list = EmployeeFactory.buildEmployByChain();
foreachColl(list);
//getOnlyIdList(list);
//getOneFiledWithDeal(list);
//getOneFiledFromArray(list);
//groupByIdForObjectMap(list);
//groupByIdForOneFiledMap(list);
//groupByRepeatNameForOneFiledMap(list);
//groupByIdForListObjectMap(list);
//groupByIdForOneFiledListMap(list);
//groupByIdForManyFiledListMap(list);
//sumAll(list);
//sumGroupById(list);
//minAll(list);
//minGroupBy(list);
//filterByCondition(list);
//sortOneConditionNature(list);
//sortTwoConditionAllNature(list);
//sortOneConditionReverse(list);
//sortTwoConditionAllReverse(list);
//sortTwoConditionOneNatureOneReverse(list);
//sortTwoConditionOneReverseOneNature(list);
//getMultiToSet(list);
//getNewList(list);
}
}
/**
* 雇员Bean
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
class Employee implements Serializable {
private static final long serialVersionUID = -3966543324371928911L;
/**
* 编号
*/
private Long id;
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 薪水
*/
private Long salary;
/**
* 生日
*/
private Date birthday;
/**
* 爱好
*/
private List<String> favorites;
/**
* 所属部门编号(数字类型的)
*/
private String deptNo;
/**
* 从哪来
*/
private String fmAddress;
/**
* 到哪去
*/
private String toAddress;
/**
* 测试BigDecimal类型的属性计算
*/
private BigDecimal testQty;
@Override
public String toString() {
return "Employee{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + ", salary=" + salary + ", birthday="
+ (null == birthday ? "" : DateUtils.formatToStringDefault(birthday)) + ", favorites=" + favorites + ", deptNo='" + deptNo + '\'' + '}';
}
}
/**
* 简单雇员Bean
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
class SimpleEmpDto implements Serializable {
private static final long serialVersionUID = 8479182105142615840L;
/**
* 编号
*/
private Long id;
/**
* 姓名
*/
private String name;
/**
* 所属部门编号(数字类型的)
*/
private String deptNo;
@Override
public String toString() {
return "SimpleEmpDto{" + "id=" + id + ", name='" + name + '\'' + ", deptNo='" + deptNo + '\'' + '}';
}
}
/**
* 构建测试数据
*/
class EmployeeFactory {
public static List<Employee> buildEmployByChain(){
List<Employee> list = new ArrayList<Employee>();
list.add(Employee.builder().id(1L).name("yangsan").age(20).salary(3000L)
.birthday(DateUtils.parseToDate("2001-01-01",DateUtils.single_format))
.deptNo("1").favorites(Arrays.asList("film","music")).fmAddress("中国").toAddress("中国").build());
list.add(Employee.builder().id(2L).name("lisi").age(18).salary(3000L)
.birthday(DateUtils.parseToDate("2003-01-01",DateUtils.single_format))
.deptNo("3").favorites(Arrays.asList("play","music")).fmAddress("中国").toAddress("美国").build());
list.add(Employee.builder().id(3L).name("wangwu").age(45).salary(7000L)
.birthday(DateUtils.parseToDate("1976-01-01",DateUtils.single_format))
.deptNo("2").favorites(Arrays.asList("swim","sing")).fmAddress("法国").toAddress("意大利").build());
list.add(Employee.builder().id(4L).name("huangbo").age(30).salary(5000L)
.birthday(DateUtils.parseToDate("1991-01-01",DateUtils.single_format))
.deptNo("3").favorites(Arrays.asList("running","read")).fmAddress("日本").toAddress("韩国").build());
list.add(Employee.builder().id(5L).name("yilong").age(25).salary(4000L)
.birthday(DateUtils.parseToDate("1996-01-01",DateUtils.single_format))
.deptNo("1").favorites(Arrays.asList("bike","code")).fmAddress("朝鲜").toAddress("中国").build());
list.add(Employee.builder().id(6L).name("xiayu").age(34).salary(5500L)
.birthday(DateUtils.parseToDate("1987-01-01",DateUtils.single_format))
.deptNo("3").favorites(Arrays.asList("game","music")).fmAddress("巴基斯坦").toAddress("中国").build());
list.add(Employee.builder().id(7L).name("yangsanqi").age(29).salary(8000L)
.birthday(DateUtils.parseToDate("1992-01-01",DateUtils.single_format))
.deptNo("1").favorites(Arrays.asList("shopping","music")).fmAddress("中国").toAddress("英国").build());
list.add(Employee.builder().id(8L).name("yangsanba").age(18).salary(2000L)
.birthday(DateUtils.parseToDate("2003-01-01",DateUtils.single_format))
.deptNo("1").favorites(Arrays.asList("eating","music")).fmAddress("俄罗斯").toAddress("法国").build());
return list;
}
}
java8之lambda表达式的23种使用总结
最新推荐文章于 2025-05-16 16:37:48 发布