文
章
目
录
章
目
录
List集合中一般有很多实体对象,每个对象都有自己的属性,有时我们需要将具备某个相同属性的对象进行分组处理,传统写法比较好理解也容易实现,但代码量比较大不太优美,而且要多次循环,而Java8给我们提供了新方法,一行代码搞定分组,不仅让潘老师体会到了什么叫优雅地写代码,更体会到了要与时俱进,不然写的代码真是越来越out了!下面,潘老师来对比下这两种实现方式的差距。
一、前期准备
首先我们新建一个User类,代码如下:
public class User {
private String name;
private String sex;
private String grade;
public User(String name, String sex,String grade) {
this.name = name;
this.sex = sex;
this.grade = grade;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
@Override
public String toString() {
return "User{" + "name='" + name + '\'' + ", sex='" + sex + '\'' + ", grade='" + grade + '\'' + '}';
}
}
二、传统写法
我们先使用传统写法将List集合中的User按照sex属性进行分组:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Test {
public static void main(String[] args) {
List<User> users = new ArrayList<>();
users.add(new User("小明","男","1班"));
users.add(new User("小红","女","1班"));
users.add(new User("小张","男","2班"));
users.add(new User("小兰","女","1班"));
users.add(new User("小紫","女","2班"));
Map<String,List<User>> userMap = new HashMap<>();
for (User user : users) {
String name = user.getName();
if (userMap.containsKey(name)) {
userMap.get(name).add(user);
}else {
List<User> list = new ArrayList<>();
list.add(user);
userMap.put(name,list);
}
}
System.out.println(userMap);
}
}
三、优雅写法
1、我们先根据sex来分组,代替上面的传统写法:
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Test {
public static void main(String[] args) {
List<User> users = new ArrayList<>();
users.add(new User("小明","男","1班"));
users.add(new User("小红","女","1班"));
users.add(new User("小张","男","2班"));
users.add(new User("小兰","女","1班"));
users.add(new User("小紫","女","2班"));
// 核心代码(返回Map集合,key就是分组的属性,value就是分组后的集合)
Map<String, List<User>> userMap = users.stream().collect(Collectors.groupingBy(User::getSex));
System.out.println(userMap);
}
}
输出结果:
{女=[User{name=’小红’, sex=’女’, grade=’1班’}, User{name=’小兰’, sex=’女’, grade=’1班’}, User{name=’小紫’, sex=’女’, grade=’2班’}], 男=[User{name=’小明’, sex=’男’, grade=’1班’}, User{name=’小张’, sex=’男’, grade=’2班’}]}
2、groupBy还支持嵌套分组,我们可以实现先根据sex分组,对分组后的每个List数据再根据grade分组,其代码如下:
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Test {
public static void main(String[] args) {
List<User> users = new ArrayList<>();
users.add(new User("小明","男","1班"));
users.add(new User("小红","女","1班"));
users.add(new User("小张","男","2班"));
users.add(new User("小兰","女","1班"));
users.add(new User("小紫","女","2班"));
// 核心代码(返回Map集合,也是嵌套的,最外层key就是sex,内层map的key是grade)
Map<String,Map<String,List<User>>> userMap = users.stream().collect(Collectors.groupingBy(User::getSex,Collectors.groupingBy(User::getGrade)));
System.out.println(userMap);
}
输出结果:
{女={2班=[User{name=’小紫’, sex=’女’, grade=’2班’}], 1班=[User{name=’小红’, sex=’女’, grade=’1班’}, User{name=’小兰’, sex=’女’, grade=’1班’}]}, 男={2班=[User{name=’小张’, sex=’男’, grade=’2班’}], 1班=[User{name=’小明’, sex=’男’, grade=’1班’}]}}
好了,以后再也不用再为集合分组闹心了,也就一行代码的事儿!
Java8的Stream是新特性,除了collect还有很多对集合高阶操作的方法,具体的可以参考:菜鸟教程 Java8 Stream





