java8 lambda表达式和流方式操作结合
部门组织:OrgInfo.java
@Data
public class OrgInfo{
private String orgCode;
private String orgName;
}
人员:Person.java
@Data
public class Person{
private String id;
private String name;
private int age;
private String phoneNumber;
private String orgCode;
private String jobCode;
}
1、分组:
List里面的对象元素,以某个属性来分组,例如,以orgCode分组,将orgCode相同的放在一起:
//获取所有人员列表
List<Person> list = getAllPerson();
//List 以orgCode分组
Map<String, List<Person>> map = list.stream().collect(Collectors.groupingBy(Person::getOrgCode));
或者这样写:
//List 以orgCode分组
Map<String, List<Person>> map = list.stream().collect(Collectors.groupingBy(t->t.getOrgCode()));
2、过滤Filter:
从集合中过滤出来符合条件的元素:
//获取所有人员列表
List<Person> list = getAllPerson();
//过滤出orgCode为1001的组织人员:
List<Person> resultList = list.stream().filter(a -> "1001".equals(a.getOrgCode())).collect(Collectors.toList());
//过滤出orgCode为1001,并且年龄大于30的员工
List<Person> resultList = list.stream().filter(a -> "1001".equals(a.getOrgCode()) && a.getAge() > 30).collect(Collectors.toList());
3、List<Object> 转List<String>
//获取所有人员列表
List<Person> list = getAllPerson();
//获取人员的ID列表
List<String> idList = list.stream().map(t->t.getId()).collect(Collectors.toList());
4、List<Object1> 转 List<Objcect2>
人员Person2.java
@Data
public class Person2{
private String id;
private String name;
private int age;
private String phoneNumber;
private String orgCode;
private String jobCode;
private Date createTime;//新增创建时间
}
将集合List< Person > 转换成List< Person2 >
//获取所有人员列表
List<Person> list = getAllPerson();
//对象转换,toPerson2是一个转换对象的方法;
List<Person2> person2List = list.stream().map(this::toPerson2).collect(Collectors.toList());
toPerson2()方法:
private Person2 toPerson2(Person person){
Person2 person2 = new Person2();
person2.setId(person.getId());
...//省略部分属性的设置
person2.setCreateTime(new Date());
return person2;
}
第二种方法:
//获取所有人员列表
List<Person> list = getAllPerson();
List<Person2> students = list.stream().map(person -> {
Person2 person2 = new Person2();
person2.setId(person.getId());
...//省略部分属性的设置
person2.setCreateTime(new Date());
return person2;
}).collect(Collectors.toList());
5、List< Objcet > 转map
List<OrgInfo> list = getAllOrgInfoList(); //本地组织
Map<String,String> map = list.stream().collect(Collectors.toMap(OrgInfo::getOrgCode, OrgInfo::getOrgName));
当集合对象中有重复的key,会报错,解决办法如下:
/**
* List -> Map
* 需要注意的是:
* toMap 如果集合对象有重复的key,会报错Duplicate key ....
* person1,person2的orgCode都为1001。
* 可以用 (k1,k2)->k1 来设置,如果有重复的key,则保留key1,舍弃key2
*/
Map<String, Person> personMap = list.stream().collect(Collectors.toMap(Person::getOrgCode, a -> a,(k1,k2)->k1));
6、List转Set
获取去重后的orgCode,
List<OrgInfo> list = getAllOrgInfoList(); //本地组织
Set<String> orgCodeSet = list.stream().map(t->t.getOrgCode()).collect(Collectors.toSet());
7.求和
将集合中的数据按照某个属性求和:
//计算 总年龄
Integer totalAge = list.stream().map(Person::getAge).reduce(0, (a,b)->{
a += b;
return a;
});
//简要说明一下: reduce中 0:表示初始值, a变量代表初始值,b变量代表List中下一个元素,两者相加得到值存在a中返回,以此得到一个求和的目的。其他用法可以自己搜索reduce的用法。
例2:
Student.java
@Data
public class Student {
private String id;
private BigDecimal socre;
}
public static void main(String[] args) {
Student student = new Student();
student.setId("1");
student.setSocre(BigDecimal.valueOf(95.5));
Student student2 = new Student();
student2.setId("1");
student2.setSocre(BigDecimal.valueOf(98.5));
Student student3 = new Student();
student3.setId("1");
student3.setSocre(BigDecimal.valueOf(92.5));
List<Student> list = new ArrayList<>();
list.add(student);
list.add(student2);
list.add(student3);
BigDecimal totalScore = list.stream().map(Student::getSocre).reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println(totalScore);
}
//结果:286.5
例3:
public static void main(String[] args) {
// System.out.println(LocalDateTime.now());
Student student = new Student();
student.setId("1");
student.setName("小明");
student.setSocre(BigDecimal.valueOf(95.5));
student.setAge(23);
Student student2 = new Student();
student2.setId("2");
student2.setSocre(BigDecimal.valueOf(98.5));
student2.setAge(32);
Student student3 = new Student();
student3.setId("3");
student3.setSocre(BigDecimal.valueOf(92.5));
student3.setAge(43);
List<Student> list = new ArrayList<>();
list.add(student);
list.add(student2);
list.add(student3);
int sum = list.stream().mapToInt(Student::getAge).sum();
System.out.println("age:"+sum);
}
//结果:age:98
8、求最大值和最小值
获取年龄最大的和最小的学生。
Student.java
@Data
public class Student {
private String id;
private BigDecimal socre;
private int age;
}
public static void main(String[] args) {
Student student = new Student();
student.setId("1");
student.setSocre(BigDecimal.valueOf(95.5));
student.setAge(23);
Student student2 = new Student();
student2.setId("1");
student2.setSocre(BigDecimal.valueOf(98.5));
student2.setAge(32);
Student student3 = new Student();
student3.setId("1");
student3.setSocre(BigDecimal.valueOf(92.5));
student3.setAge(43);
List<Student> list = new ArrayList<>();
list.add(student);
list.add(student2);
list.add(student3);
BigDecimal totalScore = list.stream().map(Student::getSocre).reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println(totalScore);
Optional<Student> minAgeStudent = list.stream().collect(Collectors.minBy(Comparator.comparingInt(Student::getAge)));
minAgeStudent.ifPresent(System.out::println);
Optional<Student> maxAgeStudent = list.stream().collect(Collectors.maxBy(Comparator.comparingInt(Student::getAge)));
maxAgeStudent.ifPresent(System.out::println);
}
//运行结果:
//Student(id=1, socre=95.5, age=23)
//Student(id=1, socre=92.5, age=43)
9、去重
public static void main(String[] args) {
// System.out.println(LocalDateTime.now());
Student student = new Student();
student.setId("1");
student.setSocre(BigDecimal.valueOf(95.5));
student.setAge(23);
Student student2 = new Student();
student2.setId("1");
student2.setSocre(BigDecimal.valueOf(98.5));
student2.setAge(32);
Student student3 = new Student();
student3.setId("1");
student3.setSocre(BigDecimal.valueOf(92.5));
student3.setAge(43);
List<Student> list = new ArrayList<>();
list.add(student);
list.add(student2);
list.add(student3);
List<Student> studentList = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(()->new TreeSet<>(Comparator.comparingLong(t->Long.valueOf(t.getId())))),ArrayList::new));
}
//结果:[Student(id=1, socre=95.5, age=23)]
10、List多字段排序,第一个字段降序,第二个字段升序
public static void main(String[] args) {
// System.out.println(LocalDateTime.now());
Student student = new Student();
student.setId("1");
student.setName("小明");
student.setSocre(BigDecimal.valueOf(95.5));
student.setAge(23);
Student student2 = new Student();
student2.setId("2");
student2.setSocre(BigDecimal.valueOf(98.5));
student2.setAge(32);
Student student3 = new Student();
student3.setId("3");
student3.setSocre(BigDecimal.valueOf(92.5));
student3.setAge(43);
List<Student> list = new ArrayList<>();
list.add(student);
list.add(student2);
list.add(student3);
System.out.println(list);
List<Student> list2 =list.stream().sorted(Comparator.comparing(Student::getSocre).reversed().thenComparing(Student::getAge)).collect(Collectors.toList());
System.out.println(list2);
}
//结果:
//排序前
//[Student(id=1, name=小明, socre=95.5, age=23), Student(id=2, name=null, socre=98.5, age=32), Student(id=3, name=null, socre=92.5, age=43)]
//排序后
//[Student(id=2, name=null, socre=98.5, age=32), Student(id=1, name=小明, socre=95.5, age=23), Student(id=3, name=null, socre=92.5, age=43)]
11、应用场景:
(1)获取新增的组织
从第三方同步组织,获取新增的组织
调用第三方接口得到的结果集合List<OrgInfo1> ,对象字段与OrgInfo字段不完全相同。
List<OrgInfo1> list1 = 调用第三方接口得到的结果集合;
List<OrgInfo> list = getAllOrgInfoList(); //本地组织
//筛选差集(获取到新增的组织)
List<OrgInfo1> distinctByUniqueList = list1.stream().filter(item -> !list.stream().map(e -> e.getOrgCode()).collect(Collectors.toList()).contains(item.getOrgCode())).collect(Collectors.toList());
(2)获取指定组织下每个岗位(jobCode)的第一个人员。
//获取所有人员列表
List<Person> list = getAllPerson();
//获取1001组织,按jobCode分组,取每组的第一条。
Map<String, List<Person>> map = list.stream().filter(t->"1001".equals(t.getOrgCode())).collect(Collectors.groupingBy(Person::getJobCode, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0))));
(3)排班去重
当(人员、排班日期、班组、班次)一样的记录视为一条记录,做过滤。
排班信息:Schedule.java
@Data
public class Schedule{
private String scheduleId;
//人员
private String personCode;
//排班日期
private String scheduleDate;
//班组
private String groupId;
//班次
private String shiftId;
private Date createTime;
}
//获取所有排班
List<Schedule> list = getAllScheduleList();
List<Schedule> resultList = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(()->new TreeSet<>(Comparator.comparing(f->f.getScheduledDate() + f.getPersonCode() + f.getShiftId() +f.getGruopId()))), ArrayList::new));