首页 > 编程知识 正文

Java8特性lambda表达式之Collection常见操作

时间:2023-05-03 19:32:11 阅读:188548 作者:2084

现在越来越多的公司开始使用jdk8了,jdk8有许多新特性,其中一个特性便是流式处理,进而有好多对于集合的便利操作

我自己也是刚开始熟悉jdk8,便在此记录一些基本的关于集合的操作 至于一些理论上的东西我就不写了,某度一大堆,因为一点点介绍每段的含义来路也不是一篇博客就能写完的,我只会简单说一下每段的意思,废话不多说,上代码

先创建一下的练习会用到的类

    

package com.chunying.lambda;/** * @author chunying */public class Student { private final String name; private final Integer age; private final Gender gender; public Student(String name, Integer age , Gender gender) { this.name = name; this.age = age; this.gender = gender; } public String getName() { return name; } public Integer getAge() { return age; } public Gender getGender() { return gender; } public enum Gender{MALE , FEMALE};}package com.chunying.lambda;import java.util.Arrays;import java.util.List;/** * @author chunying */public class LambdaDemo { List<Student> data = Arrays.asList( new Student("lcdyx" ,23 , Student.Gender.MALE), new Student("xfdbz" ,24 , Student.Gender.MALE), new Student("超级的枫叶" ,24 , Student.Gender.FEMALE), new Student("rydgs" ,23 , Student.Gender.FEMALE) );}

这里我创建了一个学生类以及学生类的集合,以下的所有操作都将通过它们来完成

首先第一个:获取所有男性的学生集合

如果没有jdk8我们会怎样写呢?

@Testpublic void fun1() { //所有男性集合 List<Student> result = new ArrayList<>(); for(Student student : data) { if(student.getGender().equals(Student.Gender.MALE)) { result.add(student); } } System.out.println(result);}

需要遍历集合,一个一个去判断是否符合我们的条件,如果数据量比较大,或者判断条件比较多,那么可能在单线程情况下就会比较慢。多线程:就要和synchronized打交道,烦不胜烦,一不注意没处理好就会出问题

jdk8帮我们解决了这个问题

我们先看代码

@Testpublic void fun2() { List<Student> result = data.stream() .filter(student -> student.getGender().equals(Student.Gender.MALE)) .collect(Collectors.toList()); System.out.println(result);}

首先lambda表达式的基础我就不说了,我会在其他文章补充,这里不是重点,这个结果和上面是一样的

首先stream()方法,将集合变成了流,

fileter()方法,过滤到我们所需要的,

最后collect(Collectors.toList())将得到的流对象转换为集合。

第二个:将所有的学生按照年纪分组,并且获取到所有的年纪的集合

首先还是看没有jdk8怎么做

@Testpublic void fun3() { List<Integer> allAges = new ArrayList<>(); Map<Integer , List<Student>> studentByAge = new HashMap<>(); for(Student student : data) { Integer age = student.getAge(); if(!allAges.contains(age)) { allAges.add(age); } List<Student> temp = studentByAge.get(age); if(temp == null) { temp = new ArrayList<>(); temp.add(student); studentByAge.put(age , temp); }else { temp.add(student); } } System.out.println(allAges); System.out.println(studentByAge);}

其中temp集合是完全没有用的中间计算集合。非常麻烦而且不易读

我们看jdk8怎么做

@Testpublic void fun4() { List<Integer> allAges = data.stream().map(Student::getAge) .distinct() .collect(Collectors.toList()); Map<Integer , List<Student>> studentByAge = data.stream().collect(Collectors.groupingBy(Student::getAge)); System.out.println(allAges); System.out.println(studentByAge);}

先看获取年纪,通过map()方法获取到所有的年纪,distinct()去重,collect转换成集合

分组这边,比较上面这里仅仅一行代码,通过groupingBy()把所有的学生按照年纪分组即可。

第三个:所有学生按照姓名分组(假设没有重名的)

首先还是看没有jdk8怎么做。

@Testpublic void fun5() { Map<String , Student> studentByName = new HashMap<>(); for(Student student : data) { studentByName.put(student.getName() , student); }}

接下来看jdk8

@Testpublic void fun6() { Map<String , Student> studentByName = data.stream().collect(Collectors.toMap(Student::getName , student->student));}

这里用到了toMap()方法,不多解释了

第四个:集合遍历

jdk8之前集合遍历,单列集合都可以通过for(Object o : data){}来遍历,底层无非还是iterator。

map就麻烦了,一种是通过拿到keySet再去拿每一个值,一种是通过entrySet拿到每一个entry对象,再去获取键值。操作很不方便 

直接看jdk8的结合遍历

@Testpublic void fun6() { Map<String , Student> studentByName = data.stream().collect(Collectors.toMap(Student::getName , student->student)); data.forEach(student -> { System.out.println(student); }); studentByName.forEach((name , student)-> { System.out.println(name + "-" + student); });}怎么样是不是方便了很多?

第五个:排序以及类型转换

jdk8以前的排序大多是通过Comparator来排序,每次要定义排序规则或者比较器,很不方便

我们看jdk8

@Testpublic void fun7() { //将所有学生按照年级排序并返回学生集合 List<Student> result = data.stream() .sorted(Comparator.comparing(Student::getAge)) .collect(Collectors.toList()); System.out.println(result);}

是不是很方便的。

常用的操作就这些,我就先记录到这里。



版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。