在SQL中經(jīng)常會(huì)用到分組,我們也常常遇到一些組合分組的場(chǎng)景。
java8分組 傳統(tǒng)寫法(單個(gè)字段分組)
場(chǎng)景:根據(jù) 城市 進(jìn)行分組
使用的是方法引用:User::getCity 來完成分組
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Demo2 {
public static void main(String[] args) {
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// data list
List<User> userList = Arrays.asList(
User.builder().id(123456).name("Zhang, San").city("ShangHai").sex("man").birthDay(LocalDateTime.parse("2022-07-01 12:00:00", df)).build(),
User.builder().id(777777).name("Zhang, San").city("ShangHai").sex("woman").birthDay(LocalDateTime.parse("2022-07-01 12:00:00", df)).build(),
User.builder().id(888888).name("Li, Si").city("ShangHai").sex("man").birthDay(LocalDateTime.parse("2022-07-01 12:00:00", df)).build(),
User.builder().id(999999).name("Zhan, San").city("HangZhou").sex("woman").birthDay(LocalDateTime.parse("2022-07-01 12:00:00", df)).build(),
User.builder().id(555555).name("Li, Si").city("NaJin").sex("man").birthDay(LocalDateTime.parse("2022-07-01 12:00:00", df)).build()
);
Map<String, List<User>> groupMap = userList.stream()
.collect(Collectors.groupingBy(User::getCity));
groupMap.forEach((k, v) -> {
System.out.println(k);
System.out.println(v);
});
}
}
java8分組 傳統(tǒng)寫法(多個(gè)字段分組)
場(chǎng)景:根據(jù) 城市,性別進(jìn)行分組
一般的寫法會(huì)是下面的這種寫法,通過lambda表達(dá)式將key的生成邏輯傳入進(jìn)去:u -> u.getCity() + “|” + u.getSex() 來實(shí)現(xiàn)分組的效果。
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Demo2 {
public static void main(String[] args) {
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// data list
List<User> userList = Arrays.asList(
User.builder().id(123456).name("Zhang, San").city("ShangHai").sex("man").birthDay(LocalDateTime.parse("2022-07-01 12:00:00", df)).build(),
User.builder().id(777777).name("Zhang, San").city("ShangHai").sex("woman").birthDay(LocalDateTime.parse("2022-07-01 12:00:00", df)).build(),
User.builder().id(888888).name("Li, Si").city("ShangHai").sex("man").birthDay(LocalDateTime.parse("2022-07-01 12:00:00", df)).build(),
User.builder().id(999999).name("Zhan, San").city("HangZhou").sex("woman").birthDay(LocalDateTime.parse("2022-07-01 12:00:00", df)).build(),
User.builder().id(555555).name("Li, Si").city("NaJin").sex("man").birthDay(LocalDateTime.parse("2022-07-01 12:00:00", df)).build()
);
Map<String, List<User>> groupMap = userList.stream()
.collect(Collectors.groupingBy(u -> u.getCity() + "|" + u.getSex()));
groupMap.forEach((k, v) -> {
System.out.println(k);
System.out.println(v);
});
}
}
分析:多個(gè)分組條件 與 單個(gè)分組條件 兩種寫法
單個(gè)條件的分組用的比較多,userList.stream().collect(Collectors.groupingBy(User::getCity));
這種方法引用的方式看起來很清爽。
在我們遇到多個(gè)字段的分組的時(shí)候,我并不太想使用前面那種傳統(tǒng)的寫法①。
我在想,既然單個(gè)字段的分組寫法是:
userList.stream().collect(Collectors.groupingBy(User::getCity));
那么多個(gè)字段的寫法可否是下面這種( 類推 ),傳入多個(gè)方法引用!
userList.stream().collect(Collectors.groupingBy(User::getCity,User::getSex));
很可惜 jdk 類庫中Collectors 沒有提供這種寫法
因?yàn)閖dk沒有提供這種寫法,于是自己就想寫了一個(gè)Util來幫助我們使用多個(gè)方法引用的方式完成組合分組
MyBeanUtil groupingBy(userList, User::getSex, User::getCity);文章來源:http://www.zghlxwxcb.cn/news/detail-418542.html
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
public class MyBeanUtil {
public static void main(String[] args) {
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// data list
List<User> userList = Arrays.asList(
User.builder().id(123456).name("Zhang, San").city("ShangHai").sex("man").birthDay(LocalDateTime.parse("2022-07-01 12:00:00", df)).build(),
User.builder().id(777777).name("Zhang, San").city("ShangHai").sex("woman").birthDay(LocalDateTime.parse("2022-07-01 12:00:00", df)).build(),
User.builder().id(888888).name("Li, Si").city("ShangHai").sex("man").birthDay(LocalDateTime.parse("2022-07-01 12:00:00", df)).build(),
User.builder().id(999999).name("Zhan, San").city("HangZhou").sex("woman").birthDay(LocalDateTime.parse("2022-07-01 12:00:00", df)).build(),
User.builder().id(555555).name("Li, Si").city("NaJin").sex("man").birthDay(LocalDateTime.parse("2022-07-01 12:00:00", df)).build()
);
// 進(jìn)行分組,根據(jù)名字和城市分組
Map<String, List<User>> groupMap = groupingBy(userList, User::getSex, User::getCity);
//打印分組結(jié)果
groupMap.forEach((k, v) -> {
System.out.println(k);
System.out.println(v);
});
}
/**
* 將數(shù)據(jù)分組,根據(jù)方法引用(bean的get方法)
*
* @param list 為分組的數(shù)據(jù)
* @param functions get方法數(shù)組
*/
@SafeVarargs
public static <T, R> Map<String, List<T>> groupingBy(List<T> list, Function<T, R>... functions) {
return list.stream().collect(Collectors.groupingBy(t -> groupingBy(t, functions)));
}
/**
* 分組工具根據(jù)函數(shù)式接口使用分組,將數(shù)據(jù)根據(jù)分組結(jié)果進(jìn)行拆分
*/
@SafeVarargs
public static <T, R> String groupingBy(T t, Function<T, R>... functions) {
if (functions == null || functions.length == 0) {
throw new NullPointerException("functions數(shù)組不可以為空");
} else if (functions.length == 1) {
return functions[0].apply(t).toString();
} else {
return Arrays.stream(functions).map(fun -> fun.apply(t).toString()).reduce((str1, str2) -> str1 + "|" + str2).get();
}
}
}
再度優(yōu)化
依然不是很滿足這種寫法,因?yàn)檫@種寫法需要借助 Util 類,不夠接地氣!
更希望是下面這種接地氣的寫法:能夠完全集成在jdk類庫中
點(diǎn)擊下方鏈接,查看原文對(duì)于jdk源代碼修改的寫法
再度優(yōu)化,修改源碼文章來源地址http://www.zghlxwxcb.cn/news/detail-418542.html
到了這里,關(guān)于java根據(jù)分組函數(shù)GroupingBy進(jìn)行多個(gè)條件組合分組的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!