java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java Stream集合

Java8 Stream API中实现集合list转map的多种方式

作者:codingPower

这篇文章介绍了如何使用Java8的StreamAPI对QuotaDto对象列表进行操作,包括字段提取、映射、组装成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());

优化点

使用 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()));
}

修正

4. List转Map(类型安全版)

List<Map<String, String>> lists = new ArrayList<>(); // 统一泛型类型
//(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")));

修正

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(";"));

优化

使用 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());

优化

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 组合多个字段的比较,避免字符串拼接可能导致的键冲突。

最佳实践总结

通过遵循这些原则,可以大幅提升代码的健壮性和可读性。

到此这篇关于Java8 Stream API中实现集合list转map的多种方式的文章就介绍到这了,更多相关Java Stream list转map内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文