0
点赞
收藏
分享

微信扫一扫

`List` 中存在重复的键处理方式

当使用 Java 8 的 Stream API 将 List 转换为 Map 时,如果 List 中存在重复的键,直接使用 Collectors.toMap 方法会抛出 IllegalStateException 异常。不过,有多种方法可以处理这种情况,下面为你详细介绍:

1. 保留现有值

若遇到重复键,选择保留已存在于 Map 中的值。可通过 Collectors.toMap 方法的第三个参数来实现。

示例代码

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

class Person {
    private int id;
    private String name;

    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Person{id=" + id + ", name='" + name + "'}";
    }
}

public class KeepExistingValue {
    public static void main(String[] args) {
        List<Person> personList = new ArrayList<>();
        personList.add(new Person(1, "Alice"));
        personList.add(new Person(1, "Bob"));

        Map<Integer, Person> personMap = personList.stream()
               .collect(Collectors.toMap(Person::getId, person -> person, (existing, replacement) -> existing));

        personMap.forEach((key, value) -> System.out.println(key + ": " + value));
    }
}

代码解释

Collectors.toMap 方法里,(existing, replacement) -> existing 表明当出现重复键时,保留现有的值。

2. 替换现有值

若遇到重复键,选择用新的值替换 Map 中已存在的值。同样使用 Collectors.toMap 方法的第三个参数。

示例代码

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

class Person {
    private int id;
    private String name;

    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Person{id=" + id + ", name='" + name + "'}";
    }
}

public class ReplaceExistingValue {
    public static void main(String[] args) {
        List<Person> personList = new ArrayList<>();
        personList.add(new Person(1, "Alice"));
        personList.add(new Person(1, "Bob"));

        Map<Integer, Person> personMap = personList.stream()
               .collect(Collectors.toMap(Person::getId, person -> person, (existing, replacement) -> replacement));

        personMap.forEach((key, value) -> System.out.println(key + ": " + value));
    }
}

代码解释

(existing, replacement) -> replacement 表示当出现重复键时,用新的值替换现有的值。

3. 合并值

当遇到重复键时,把重复键对应的值合并为一个新的值。

示例代码

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

class Person {
    private int id;
    private String name;

    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Person{id=" + id + ", name='" + name + "'}";
    }
}

public class MergeValues {
    public static void main(String[] args) {
        List<Person> personList = new ArrayList<>();
        personList.add(new Person(1, "Alice"));
        personList.add(new Person(1, "Bob"));

        Map<Integer, String> personNameMap = personList.stream()
               .collect(Collectors.toMap(Person::getId, Person::getName, (name1, name2) -> name1 + ", " + name2));

        personNameMap.forEach((key, value) -> System.out.println(key + ": " + value));
    }
}

代码解释

(name1, name2) -> name1 + ", " + name2 意味着当出现重复键时,把对应的名字用逗号连接起来。

4. 将重复键的值存储在集合中

若希望保留所有重复键对应的值,可以把这些值存储在一个集合(如 ListSet)里。

示例代码

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

class Person {
    private int id;
    private String name;

    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Person{id=" + id + ", name='" + name + "'}";
    }
}

public class StoreValuesInList {
    public static void main(String[] args) {
        List<Person> personList = new ArrayList<>();
        personList.add(new Person(1, "Alice"));
        personList.add(new Person(1, "Bob"));

        Map<Integer, List<Person>> personMap = personList.stream()
               .collect(Collectors.groupingBy(Person::getId));

        personMap.forEach((key, value) -> System.out.println(key + ": " + value));
    }
}

代码解释

Collectors.groupingBy 方法会把具有相同键的元素分组到一个 List 中,最终返回一个 Map,键是分组的依据,值是对应的元素列表。

举报

相关推荐

0 条评论