Java8?Stream?API中實現(xiàn)集合list轉map的多種方式
自定義一個對象:
public class QuotaDto{
private Long id;
private String quotaId;
private String quotaName;
private String reportDate;
private String email;
}
List<QuotaDto> quotaDtolists = new ArrayList<>();
1. 提取對象字段集合
List<String> quotaNames = quotaDtolists.stream()
.map(QuotaDto::getQuotaName)
.filter(Objects::nonNull) // 過濾null值
.collect(Collectors.toList());
優(yōu)化點:
使用 filter(Objects::nonNull) 避免 null 元素進入列表。
2. List轉Map(唯一鍵)
// 方式1:對象為Value(處理重復鍵)
Map<String, QuotaDto> quotaMap1 = quotaDtolists.stream()
.collect(Collectors.toMap(
QuotaDto::getQuotaId,
Function.identity(),
(v1, v2) -> v2 // 鍵沖突時保留新值
));
// 方式2:提取字段為Value
Map<String, String> quotaMap2 = quotaDtolists.stream()
.collect(Collectors.toMap(
QuotaDto::getQuotaId,
QuotaDto::getQuotaName,
(oldVal, newVal) -> newVal
));
關鍵點:
必須提供合并函數 ((v1, v2) -> ...),否則重復鍵會拋出 IllegalStateException。
3. 枚舉類轉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; } // 正確方法名
// 枚舉轉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轉Map(類型安全版)
List<Map<String, String>> lists = new ArrayList<>(); // 統(tǒng)一泛型類型
//(v1,v2)->v2 沖突解決函數,當兩個不同的map對象具有相同的“userid”鍵值。保留第二個遇到的值V2
Map<String, String> collect = lists.stream()
.collect(Collectors.toMap(
map -> map.getOrDefault("userid", ""),
map -> map.getOrDefault("orgid", ""),
(v1, v2) -> v2
));
//以某個字段為key
Map<String,List<QuotaDto>> quotaMap= quotaDtolists.stream().collect(Collectors.groupingBy(QuotaDto::getQuotaName));
//list<map> 轉 map
Map<String,List<Map<String,String>>> quotaMap= maps.stream().collect(Collectors.groupingBy(map->map.get("userId")));
修正:
- 統(tǒng)一列表中的
Map泛型為<String, String>,避免類型不匹配。 - 使用
getOrDefault防止null值導致的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); // 默認值
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));
// 求匯總數
long count= quotaDtolists.stream().filter(Quota-> Quota.getId()>1).collect(Collectors.counting());
優(yōu)化:
- 直接使用
max()、min()、sum()等終端操作,代碼更簡潔。 - 避免使用復雜的
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 組合多個字段的比較,避免字符串拼接可能導致的鍵沖突。
最佳實踐總結
- 空值處理:始終考慮字段可能為
null的情況,使用filter或Optional防御。 - 類型安全:統(tǒng)一集合的泛型類型,避免
ClassCastException。 - 鍵沖突處理:在
toMap中始終提供合并函數,明確沖突解決策略。 - 避免魔法字符串:如
map.get("userid")可替換為常量,提高可維護性。 - 優(yōu)先內置方法:如
sum()、average()比Collectors.summingInt更簡潔。 - 使用組合比較器:多字段去重時,避免拼接字符串,采用
thenComparing。
通過遵循這些原則,可以大幅提升代碼的健壯性和可讀性。
到此這篇關于Java8 Stream API中實現(xiàn)集合list轉map的多種方式的文章就介紹到這了,更多相關Java Stream list轉map內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring WebFlux實現(xiàn)參數校驗的示例代碼
請求參數校驗,在實際的應用中很常見,網上的文章大部分提供的使用注解的方式做參數校驗。本文主要介紹 Spring Webflux Function Endpoint 使用 Spring Validation 來校驗請求的參數。感興趣的可以了解一下2021-08-08
Spring boot按日切分spring boot的nohup.out日志文件的方法
過大的日志文件維護起來存在諸多問題,所以最好是能夠按日或按大小切分日志文件,下面小編給大家?guī)砹薙pring boot按日切分spring boot的nohup.out日志文件的方法,一起看看吧2018-08-08
idea git設置Local Changes窗口過程(代碼/文件變更顯示)
本文介紹了在IDEA中,當代碼有變更但未顯示LocalChanges窗口時,可以通過設置取消勾選“Usenon-modalcommitinterface”選項來解決該問題2026-04-04
Java中的字節(jié)流InputStream和OutputStream詳解
這篇文章主要介紹了Java中的字節(jié)流InputStream和OutputStream詳解,繼承自InputStream的流都是用于向程序中輸入數據,且數據的單位為字節(jié)8bit,我們看到的具體的某一些管道,凡是以InputStream結尾的管道,都是以字節(jié)的形式向我們的程序輸入數據,需要的朋友可以參考下2023-10-10

