Java8?Stream?API中實(shí)現(xiàn)集合list轉(zhuǎn)map的多種方式
自定義一個(gè)對(duì)象:
public class QuotaDto{
private Long id;
private String quotaId;
private String quotaName;
private String reportDate;
private String email;
}
List<QuotaDto> quotaDtolists = new ArrayList<>();
1. 提取對(duì)象字段集合
List<String> quotaNames = quotaDtolists.stream()
.map(QuotaDto::getQuotaName)
.filter(Objects::nonNull) // 過濾null值
.collect(Collectors.toList());
優(yōu)化點(diǎn):
使用 filter(Objects::nonNull) 避免 null 元素進(jìn)入列表。
2. List轉(zhuǎn)Map(唯一鍵)
// 方式1:對(duì)象為Value(處理重復(fù)鍵)
Map<String, QuotaDto> quotaMap1 = quotaDtolists.stream()
.collect(Collectors.toMap(
QuotaDto::getQuotaId,
Function.identity(),
(v1, v2) -> v2 // 鍵沖突時(shí)保留新值
));
// 方式2:提取字段為Value
Map<String, String> quotaMap2 = quotaDtolists.stream()
.collect(Collectors.toMap(
QuotaDto::getQuotaId,
QuotaDto::getQuotaName,
(oldVal, newVal) -> newVal
));
關(guān)鍵點(diǎn):
必須提供合并函數(shù) ((v1, v2) -> ...),否則重復(fù)鍵會(huì)拋出 IllegalStateException。
3. 枚舉類轉(zhuǎn)Map(修正版)
public enum QuotaEnum {
TYPE_A("A"), TYPE_B("B");
private final String value;
QuotaEnum(String value) { this.value = value; }
public String getValue() { return value; } // 正確方法名
// 枚舉轉(zhuǎn)Map
private static final Map<String, QuotaEnum> VALUE_MAP = Arrays.stream(values())
.collect(Collectors.toMap(QuotaEnum::getValue, Function.identity()));
}
修正:
- 方法名
getvalue→getValue(遵循駝峰命名)。 - 使用
Arrays.stream()替代Stream.of()(更直觀)。
4. List轉(zhuǎn)Map(類型安全版)
List<Map<String, String>> lists = new ArrayList<>(); // 統(tǒng)一泛型類型
//(v1,v2)->v2 沖突解決函數(shù),當(dāng)兩個(gè)不同的map對(duì)象具有相同的“userid”鍵值。保留第二個(gè)遇到的值V2
Map<String, String> collect = lists.stream()
.collect(Collectors.toMap(
map -> map.getOrDefault("userid", ""),
map -> map.getOrDefault("orgid", ""),
(v1, v2) -> v2
));
//以某個(gè)字段為key
Map<String,List<QuotaDto>> quotaMap= quotaDtolists.stream().collect(Collectors.groupingBy(QuotaDto::getQuotaName));
//list<map> 轉(zhuǎn) map
Map<String,List<Map<String,String>>> quotaMap= maps.stream().collect(Collectors.groupingBy(map->map.get("userId")));
修正:
- 統(tǒng)一列表中的
Map泛型為<String, String>,避免類型不匹配。 - 使用
getOrDefault防止null值導(dǎo)致的NullPointerException。
5. 元素拼接(防Null版)
String emailAddress = quotaDtolists.stream()
.map(quota -> Optional.ofNullable(quota.getEmail())
.map(email -> email.toUpperCase() + "@qq.com")
.orElse("")) // 處理null或空郵件
.filter(str -> !str.isEmpty())
.collect(Collectors.joining(";"));
//簡單版
String emailAddress=quotaDtolists.stream().map(Quota-Quota.getEmail().toUpperCase()+"@qq.com").collect(Collectors.joining(";"));
優(yōu)化:
使用 Optional 安全處理 null,并過濾空字符串。
6. 聚合操作(安全版)
List<Integer> list = Arrays.asList(1, 2, 3);
// 最大值(避免NoSuchElementException)
Integer maxValue = list.stream()
.max(Integer::compare)
.orElse(0); // 默認(rèn)值
Integer maxValue2 = list.stream().collect(Collectors.collectingAndThen(Collectors.maxBy((a, b) -> a - b), Optional::get));
// 最小值
Integer minValue = list.stream()
.min(Integer::compare)
.orElse(0);
Integer minValue2 = list.stream().collect(Collectors.collectingAndThen(Collectors.minBy((a, b) -> a - b), Optional::get));
// 求和(直接使用sum()更高效)
int sumValue = list.stream().mapToInt(Integer::intValue).sum();
Integer sumValue2 = list.stream().collect(Collectors.summingInt(item -> item));
// 平均值
Double avg = list.stream()
.mapToInt(Integer::intValue)
.average()
.orElse(0.0);
Double avg2 = list.stream().collect(Collectors.averagingDouble(x -> x));
// 求匯總數(shù)
long count= quotaDtolists.stream().filter(Quota-> Quota.getId()>1).collect(Collectors.counting());
優(yōu)化:
- 直接使用
max()、min()、sum()等終端操作,代碼更簡潔。 - 避免使用復(fù)雜的
collectingAndThen,除非需要額外處理。
7. 多字段去重(可靠版)
ArrayList<QuotaDto> uniqueList = quotaDtolists.stream()
.collect(Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(
Comparator.comparing(QuotaDto::getId)
.thenComparing(QuotaDto::getQuotaName)
)),
ArrayList::new
));
//方法二
ArrayList<QuotaDto> collect = quotaDtolists.stream().collect(Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(
Comparator.comparing(q -> q.getId()+";"+q.getQuotaName()))), ArrayList::new));
修正:
使用 thenComparing 組合多個(gè)字段的比較,避免字符串拼接可能導(dǎo)致的鍵沖突。
最佳實(shí)踐總結(jié)
- 空值處理:始終考慮字段可能為
null的情況,使用filter或Optional防御。 - 類型安全:統(tǒng)一集合的泛型類型,避免
ClassCastException。 - 鍵沖突處理:在
toMap中始終提供合并函數(shù),明確沖突解決策略。 - 避免魔法字符串:如
map.get("userid")可替換為常量,提高可維護(hù)性。 - 優(yōu)先內(nèi)置方法:如
sum()、average()比Collectors.summingInt更簡潔。 - 使用組合比較器:多字段去重時(shí),避免拼接字符串,采用
thenComparing。
通過遵循這些原則,可以大幅提升代碼的健壯性和可讀性。
到此這篇關(guān)于Java8 Stream API中實(shí)現(xiàn)集合list轉(zhuǎn)map的多種方式的文章就介紹到這了,更多相關(guān)Java Stream list轉(zhuǎn)map內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 教你用java?stream對(duì)集合中的對(duì)象按指定字段進(jìn)行分組并統(tǒng)計(jì)
- Java8 Stream中對(duì)集合數(shù)據(jù)進(jìn)行快速匹配和賦值的代碼示例
- Java集合Stream流操作的基本使用教程分享
- Java8 實(shí)現(xiàn)stream將對(duì)象集合list中抽取屬性集合轉(zhuǎn)化為map或list
- Java8 使用 stream().sorted()對(duì)List集合進(jìn)行排序的操作
- Java8處理集合的優(yōu)雅姿勢(shì)之Stream
- Java8中利用stream對(duì)map集合進(jìn)行過濾的方法
相關(guān)文章
java經(jīng)典問題:連個(gè)字符串互為回環(huán)變位
連個(gè)字符串互為回環(huán)變位經(jīng)常出現(xiàn)在java程序員面試中,這個(gè)是考驗(yàn)程序員的解題思路和方法的最經(jīng)典的一題,小編為大家詳細(xì)分析一下,一起來學(xué)習(xí)吧。2017-11-11
Spring WebFlux實(shí)現(xiàn)參數(shù)校驗(yàn)的示例代碼
請(qǐng)求參數(shù)校驗(yàn),在實(shí)際的應(yīng)用中很常見,網(wǎng)上的文章大部分提供的使用注解的方式做參數(shù)校驗(yàn)。本文主要介紹 Spring Webflux Function Endpoint 使用 Spring Validation 來校驗(yàn)請(qǐng)求的參數(shù)。感興趣的可以了解一下2021-08-08
Spring boot按日切分spring boot的nohup.out日志文件的方法
過大的日志文件維護(hù)起來存在諸多問題,所以最好是能夠按日或按大小切分日志文件,下面小編給大家?guī)砹薙pring boot按日切分spring boot的nohup.out日志文件的方法,一起看看吧2018-08-08
idea git設(shè)置Local Changes窗口過程(代碼/文件變更顯示)
本文介紹了在IDEA中,當(dāng)代碼有變更但未顯示LocalChanges窗口時(shí),可以通過設(shè)置取消勾選“Usenon-modalcommitinterface”選項(xiàng)來解決該問題2026-04-04
Java中的字節(jié)流InputStream和OutputStream詳解
這篇文章主要介紹了Java中的字節(jié)流InputStream和OutputStream詳解,繼承自InputStream的流都是用于向程序中輸入數(shù)據(jù),且數(shù)據(jù)的單位為字節(jié)8bit,我們看到的具體的某一些管道,凡是以InputStream結(jié)尾的管道,都是以字節(jié)的形式向我們的程序輸入數(shù)據(jù),需要的朋友可以參考下2023-10-10
Java的stream流多個(gè)字段排序的實(shí)現(xiàn)
本文主要介紹了Java的stream流多個(gè)字段排序的實(shí)現(xiàn),主要是兩種方法,第一種是固定多個(gè)字段排序和第二種動(dòng)態(tài)字段進(jìn)行排序,具有一定的參考價(jià)值,感興趣的可以了解一下2023-10-10

