web-dev-qa-db-ja.com

Collectors.toMap()関数で重複キーを処理する

Personオブジェクトで(キー、値)が(名前、住所)になるマップを作成しています:

Map<String, String> myMap = persons.stream.collect(Collector.toMap(person.getName(), person.getAddress(), (address1, address2) -> address1));

キーが重複する状況では、2つ目の住所をマップに追加するのをスキップして、名前もログに記録したいと思います。重複したアドレスをスキップすると、mergeFunctionを使用して既に行うことができますが、このmergeFunctionで必要な名前をログに記録するには、次のようなpersonオブジェクトを使用します。

(address1, address2) -> {
                           System.out.println("duplicate "+person.name() + " is found!");
                           return address1;
                        }

Personオブジェクトをこのマージ関数に渡して行き詰まっています。

6
Bali

これはpeekを使用した別の可能性です

import Java.util.*;
import Java.util.stream.*;

class App {
    public static void main(String[] args) {
        List<Person> persons = Arrays.asList(new Person("foo", "bar"), new Person("baz", "qux"), new Person("foo", "zuz"));

        Set<String> names = new HashSet<>();
        Map<String, String> nameAddress = persons.stream().peek(p -> {
            if (names.contains(p.getName())) {
                System.out.println("Duplicate key being skipped: " + p);
            } else {
                names.add(p.getName());
            }
        }).collect(Collectors.toMap(person -> person.getName(), person -> person.getAddress(), (addr1, addr2) -> addr1));

    }
}

class Person {
    String name;
    String address;

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

    public String getName() {
        return name;
    }

    public String getAddress() {
        return address;
    }

    @Override
    public String toString() {
        return name + " " + address;
    }
}

上記のスニペットの出力は次のようになります。

Duplicate key being skipped: foo zuz
1
Koray Tugay