You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Java Streams修改匹配对象:为同名Person添加唯一后缀

解决方案

基本要求实现

代码实现

import java.util.AbstractMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class PersonStreamProcessor {
    public static void main(String[] args) {
        Stream<Person> personStream = Stream.of(
                new Person("Jeff Bezos", 12),
                new Person("Jeff Bezos", 165_345_678_910L),
                new Person("Jeff Bezos", 1_234),
                new Person("Jeff Bezos(1)", 1_234),
                new Person("Jeff Bezos(1)(2)", 42),
                new Person("Bill Gates", 130_000_000_000L)
        );

        Map<String, Double> result = personStream
                // 按原始名称分组
                .collect(Collectors.groupingBy(
                        Person::getName,
                        // 对每组生成唯一名称映射
                        Collectors.collectingAndThen(
                                Collectors.toList(),
                                list -> {
                                    AtomicInteger counter = new AtomicInteger(0);
                                    return list.stream()
                                            .map(p -> new AbstractMap.SimpleEntry<>(
                                                    // 第一个元素保留原名,后续添加带计数器的后缀
                                                    counter.incrementAndGet() == 1 ? p.name : p.name + "(" + counter.get() + ")",
                                                    p.netWorth
                                            ))
                                            .collect(Collectors.toMap(
                                                    AbstractMap.SimpleEntry::getKey,
                                                    AbstractMap.SimpleEntry::getValue
                                            ));
                                }
                        )
                ))
                // 合并所有分组结果
                .values()
                .stream()
                .flatMap(map -> map.entrySet().stream())
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

        // 输出结果
        result.forEach((k, v) -> System.out.printf("%s: %.0f%n", k, v));
    }
}

class Person {
    public String name;
    public double netWorth;

    public Person(String name, double netWorth) {
        this.name = name;
        this.netWorth = netWorth;
    }
}

思路说明

  1. 用Collectors.groupingBy按Person的原始名称分组,将同名元素归为一组;
  2. 对每组通过Collectors.collectingAndThen处理:先转成列表,再用AtomicInteger做计数器生成唯一名称,组内第一个元素保留原名,后续元素添加(计数器值)后缀;
  3. 最后合并所有分组的结果为一个全局Map,保证所有键唯一。

进阶要求实现(按净资产优先级分配名称)

代码实现

import java.util.AbstractMap;
import java.util.Comparator;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class PersonStreamProcessor {
    public static void main(String[] args) {
        Stream<Person> personStream = Stream.of(
                new Person("Jeff Bezos", 12),
                new Person("Jeff Bezos", 165_345_678_910L),
                new Person("Jeff Bezos", 1_234),
                new Person("Jeff Bezos(1)", 1_234),
                new Person("Jeff Bezos(1)(2)", 42),
                new Person("Bill Gates", 130_000_000_000L)
        );

        Map<String, Double> result = personStream
                .collect(Collectors.groupingBy(
                        Person::getName,
                        Collectors.collectingAndThen(
                                Collectors.toList(),
                                list -> list.stream()
                                        // 按净资产降序排序,高资产元素优先获得简洁名称
                                        .sorted(Comparator.comparingDouble(Person::getNetWorth).reversed())
                                        .map(p -> {
                                            AtomicInteger counter = new AtomicInteger(0);
                                            return new AbstractMap.SimpleEntry<>(
                                                    counter.incrementAndGet() == 1 ? p.name : p.name + "(" + counter.get() + ")",
                                                    p.netWorth
                                            );
                                        })
                                        .collect(Collectors.toMap(
                                                AbstractMap.SimpleEntry::getKey,
                                                AbstractMap.SimpleEntry::getValue
                                        ))
                                }
                        )
                ))
                .values()
                .stream()
                .flatMap(map -> map.entrySet().stream())
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

        result.forEach((k, v) -> System.out.printf("%s: %.0f%n", k, v));
    }
}

class Person {
    public String name;
    public double netWorth;

    public Person(String name, double netWorth) {
        this.name = name;
        this.netWorth = netWorth;
    }

    public double getNetWorth() {
        return netWorth;
    }
}

思路说明

在基本要求的逻辑上增加了组内排序步骤:对每组元素按净资产降序排列,让净资产最高的元素优先被处理,保留最简洁的原名,后续元素依次添加后缀,满足“高资产用简洁名称”的进阶要求。


内容的提问来源于stack exchange,提问作者Ievgen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 00:01:40