2015-08-31 11 views
109
Map<String, String> phoneBook=people.stream() 
            .collect(toMap(Person::getName, Person::getAddress)); 

Ricevo un'eccezione chiave duplicata quando si verificano duplicati.Ignora duplicati durante la produzione di mappe utilizzando i flussi

È possibile ignorare per aggiungere i valori da mappare quando si verificano i duplicati?

Quando c'è un duplicato, deve semplicemente continuare ignorando quella chiave duplicata.

+5

Basta fornire una [funzione di unire] (https://docs.oracle.com/javase/8/docs/api/java/util/ stream/Collectors.html # toMap-java.util.function.Function-java.util.function.Function-java.util.function.BinaryOperator-) che dice '(vecchio, nuovo) -> vecchio'. –

+0

Se è possibile utilizzarlo, HashSet ignorerà la chiave, se già esiste. – sahitya

+0

@ capitan-aryabhatta. È possibile avere valori chiave nell'hashset – Patan

risposta

204

Ciò è possibile utilizzando il parametro di mergeFunctionCollectors.toMap(keyMapper, valueMapper, mergeFunction):

Map<String, String> phoneBook = 
    people.stream() 
      .collect(Collectors.toMap(
      Person::getName, 
      Person::getAddress, 
      (address1, address2) -> { 
       System.out.println("duplicate key found!"); 
       return address1; 
      } 
     )); 

mergeFunction è una funzione che opera su due valori associati con la stessa chiave. adress1 corrisponde al primo indirizzo incontrato durante la raccolta degli elementi e adress2 corrisponde al secondo indirizzo incontrato: questo lambda dice semplicemente di mantenere il primo indirizzo e ignora il secondo.

+0

Grazie mille. Potresti aiutarmi se è possibile registrare le informazioni quando si verifica una chiave duplicata. – Patan

+2

@Patan Ho modificato il mio post per aggiungere una dichiarazione di stampa quando viene trovato un duplicato – Tunaki

+1

Sono confuso, perché i valori duplicati ** (non le chiavi) non sono consentiti? E come consentire valori duplicati? –

43

Come detto in JavaDocs:

Se i tasti mappati contiene duplicati (secondo Object.equals(Object)), un IllegalStateException viene generata quando viene eseguita l'operazione raccolta. Se i tasti mappati possono avere duplicati , utilizzare invece toMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction).

Quindi è necessario utilizzare toMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction). Fornisci semplicemente la funzione di unione che determinerà quale dei duplicati è necessario inserire nella mappa. Per esempio, se non si cura che uno, basta chiamare

Map<String, String> phoneBook = people.stream() 
    .collect(Collectors.toMap(Person::getName, Person::getAddress, (p1, p2) -> p1)); 
+0

Sembra che "toMap" non sia riconosciuto ... – bashan

+1

Usa 'Collectors.toMap' o fai un'importazione statica – alaster

Problemi correlati