背景
在技术群里有人抛出这么一个问题:
请教一个问题。如何优雅地对一个List进行多维度分组? 比如有一个List orders,然后需要按照订单的字段1,字段2, 字段3,......,字段N进行分组,最终分组结果希望是List<List>这种形式。也就是说最终的这个list会被划分成字段1的取值种类数 乘以 字段2的取值种类数 乘以 ...... 乘以字段N的取值种类数,这么多部分。
如果大家碰到这样的需求, 要如何写代码?
我的实现
// 把具体分组维度放到list中
List<Function<Order, String>> list = new ArrayList<>();
list.add(Order::getCompany);
list.add(Order::getId);
final List<List<Order>> results = new ArrayList<>();
for (Function<Order, String> function : list) {
Map<String, List<Order>> map = original.stream().collect(Collectors.groupingBy(function));
List<Order> temp = new ArrayList<>();
for (Map.Entry<String, List<Order>> entry : map.entrySet()) {
List<Order> value = entry.getValue();
temp.add(value.get(0));
}
results.add(temp);
}
大家是否还有更优雅的实现方式?
最后
附完整Demo
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
new Main().group();
}
public void group() {
List<Order> original = new ArrayList<>();
Order order = new Order();
order.setId("1");
order.setCompany("111");
original.add(order);
order = new Order();
order.setId("2");
order.setCompany("222");
original.add(order);
order = new Order();
order.setId("1");
order.setCompany("333");
original.add(order);
order = new Order();
order.setId("3");
order.setCompany("222");
original.add(order);
List<Function<Order, String>> list = new ArrayList<>();
list.add(Order::getCompany);
list.add(Order::getId);
final List<List<Order>> results = new ArrayList<>();
for (Function<Order, String> function : list) {
Map<String, List<Order>> map = original.stream().collect(Collectors.groupingBy(function));
List<Order> temp = new ArrayList<>();
for (Map.Entry<String, List<Order>> entry : map.entrySet()) {
List<Order> value = entry.getValue();
temp.add(value.get(0));
}
results.add(temp);
}
results.forEach(System.out::println);
}
static class Order {
private String id;
private String company;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCompany() {
return company;
}
public void setCompany(String conpany) {
this.company = conpany;
}
@Override
public String toString() {
return "Order{" +
"id='" + id + '\'' +
", company='" + company + '\'' +
'}';
}
}
}