it-swarm.com.de

Ignorieren Sie Duplikate, wenn Sie eine Karte mit Streams erstellen

Map<String, String> phoneBook=people.stream()
                                    .collect(toMap(Person::getName, Person::getAddress));

Ich erhalte doppelte Schlüsselausnahmen, wenn Duplikate auftreten. 

Ist es möglich zu ignorieren, die Werte der Karte hinzuzufügen, wenn Duplikate auftreten?

Wenn es ein Duplikat gibt, sollte es einfach diesen doppelten Schlüssel ignorieren.

168
Patan

Dies ist mit dem Parameter mergeFunction von Collectors.toMap(keyMapper, valueMapper, mergeFunction) möglich:

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

mergeFunction ist eine Funktion, die zwei Werte bearbeitet, die demselben Schlüssel zugeordnet sind. adress1 entspricht der ersten Adresse, die beim Sammeln von Elementen gefunden wurde, und adress2 entspricht der zweiten Adresse: Dieses Lambda sagt nur, dass die erste Adresse erhalten bleiben soll, und ignoriert die zweite Adresse.

311
Tunaki

Wie gesagt in JavaDocs :

Wenn die zugeordneten Schlüssel Duplikate enthalten (gemäß Object.equals(Object)), wird eine IllegalStateException ausgegeben, wenn der Erfassungsvorgang wird durchgeführt. Wenn die zugeordneten Tasten möglicherweise .__ haben. Duplikate verwenden, verwenden Sie stattdessen toMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction).

Verwenden Sie daher stattdessen toMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction) . Stellen Sie einfach eine Merge-Funktion bereit, die bestimmt, welche der Duplikate in die Map eingefügt werden muss. Wenn Sie sich zum Beispiel nicht interessieren, rufen Sie einfach an

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

Ich habe ein solches Problem beim Gruppieren von Objekten festgestellt. Ich habe es immer auf einfache Weise gelöst: Führen Sie einen benutzerdefinierten Filter mit einem Java.util.Set aus, um doppelte Objekte mit einem beliebigen Attribut Ihrer Wahl zu entfernen

Set<String> uniqueNames = new HashSet<>();
Map<String, String> phoneBook = people
                  .stream()
                  .filter(person -> person != null && !uniqueNames.add(person.getName()))
                  .collect(toMap(Person::getName, Person::getAddress));

Hoffe, das hilft jedem, der das gleiche Problem hat!

0
Shessuky

Die Antwort von @alaster hilft mir sehr, aber ich möchte eine sinnvolle Information hinzufügen, wenn jemand versucht, die Informationen zu gruppieren.

Wenn Sie pro Beispiel zwei Orders mit derselben code aber unterschiedlichen quantity Produkten für jedes Produkt haben und Ihr Wunsch ist sum die Mengen, können Sie Folgendes tun:

List<Order> listQuantidade = new ArrayList<>();
listOrders.add(new Order("COD_1", 1L));
listOrders.add(new Order("COD_1", 5L));
listOrders.add(new Order("COD_1", 3L));
listOrders.add(new Order("COD_2", 3L));
listOrders.add(new Order("COD_3", 4L));

listOrders.collect(Collectors.toMap(Order::getCode, o -> o.getQuantity(), (o1, o2) -> o1 + o2));

Ergebnis:

{COD_3=4, COD_2=3, COD_1=9}
0
Dherik

Angenommen, Sie haben Personen, ist Objektliste 

  Map<String, String> phoneBook=people.stream()
                                        .collect(toMap(Person::getName, Person::getAddress));

Jetzt brauchst du zwei Schritte:

1) 

people =removeDuplicate(people);

2) 

Map<String, String> phoneBook=people.stream()
                                        .collect(toMap(Person::getName, Person::getAddress));

Hier ist eine Methode zum Entfernen von Duplikaten 

public static List removeDuplicate(Collection<Person>  list) {
        if(list ==null || list.isEmpty()){
            return null;
        }

        Object removedDuplicateList =
                list.stream()
                     .distinct()
                     .collect(Collectors.toList());
     return (List) removedDuplicateList;

      }

Vollständiges Beispiel hier hinzufügen

 package com.example.khan.vaquar;

import Java.util.Arrays;
import Java.util.Collection;
import Java.util.List;
import Java.util.Map;
import Java.util.stream.Collectors;

public class RemovedDuplicate {

    public static void main(String[] args) {
        Person vaquar = new Person(1, "Vaquar", "Khan");
        Person zidan = new Person(2, "Zidan", "Khan");
        Person zerina = new Person(3, "Zerina", "Khan");

        // Add some random persons
        Collection<Person> duplicateList = Arrays.asList(vaquar, zidan, zerina, vaquar, zidan, vaquar);

        //
        System.out.println("Before removed duplicate list" + duplicateList);
        //
        Collection<Person> nonDuplicateList = removeDuplicate(duplicateList);
        //
        System.out.println("");
        System.out.println("After removed duplicate list" + nonDuplicateList);
        ;

        // 1) solution Working code
        Map<Object, Object> k = nonDuplicateList.stream().distinct()
                .collect(Collectors.toMap(s1 -> s1.getId(), s1 -> s1));
        System.out.println("");
        System.out.println("Result 1 using method_______________________________________________");
        System.out.println("k" + k);
        System.out.println("_____________________________________________________________________");

        // 2) solution using inline distinct()
        Map<Object, Object> k1 = duplicateList.stream().distinct()
                .collect(Collectors.toMap(s1 -> s1.getId(), s1 -> s1));
        System.out.println("");
        System.out.println("Result 2 using inline_______________________________________________");
        System.out.println("k1" + k1);
        System.out.println("_____________________________________________________________________");

        //breacking code
        System.out.println("");
        System.out.println("Throwing exception _______________________________________________");
        Map<Object, Object> k2 = duplicateList.stream()
                .collect(Collectors.toMap(s1 -> s1.getId(), s1 -> s1));
        System.out.println("");
        System.out.println("k2" + k2);
        System.out.println("_____________________________________________________________________");
    }

    public static List removeDuplicate(Collection<Person> list) {
        if (list == null || list.isEmpty()) {
            return null;
        }

        Object removedDuplicateList = list.stream().distinct().collect(Collectors.toList());
        return (List) removedDuplicateList;

    }

}

// Model class
class Person {
    public Person(Integer id, String fname, String lname) {
        super();
        this.id = id;
        this.fname = fname;
        this.lname = lname;
    }

    private Integer id;
    private String fname;
    private String lname;

    // Getters and Setters

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getFname() {
        return fname;
    }

    public void setFname(String fname) {
        this.fname = fname;
    }

    public String getLname() {
        return lname;
    }

    public void setLname(String lname) {
        this.lname = lname;
    }

    @Override
    public String toString() {
        return "Person [id=" + id + ", fname=" + fname + ", lname=" + lname + "]";
    }

}

Ergebnisse :

Before removed duplicate list[Person [id=1, fname=Vaquar, lname=Khan], Person [id=2, fname=Zidan, lname=Khan], Person [id=3, fname=Zerina, lname=Khan], Person [id=1, fname=Vaquar, lname=Khan], Person [id=2, fname=Zidan, lname=Khan], Person [id=1, fname=Vaquar, lname=Khan]]

After removed duplicate list[Person [id=1, fname=Vaquar, lname=Khan], Person [id=2, fname=Zidan, lname=Khan], Person [id=3, fname=Zerina, lname=Khan]]

Result 1 using method_______________________________________________
k{1=Person [id=1, fname=Vaquar, lname=Khan], 2=Person [id=2, fname=Zidan, lname=Khan], 3=Person [id=3, fname=Zerina, lname=Khan]}
_____________________________________________________________________

Result 2 using inline_______________________________________________
k1{1=Person [id=1, fname=Vaquar, lname=Khan], 2=Person [id=2, fname=Zidan, lname=Khan], 3=Person [id=3, fname=Zerina, lname=Khan]}
_____________________________________________________________________

Throwing exception _______________________________________________
Exception in thread "main" Java.lang.IllegalStateException: Duplicate key Person [id=1, fname=Vaquar, lname=Khan]
    at Java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.Java:133)
    at Java.util.HashMap.merge(HashMap.Java:1253)
    at Java.util.stream.Collectors.lambda$toMap$58(Collectors.Java:1320)
    at Java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.Java:169)
    at Java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.Java:948)
    at Java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.Java:481)
    at Java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.Java:471)
    at Java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.Java:708)
    at Java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.Java:234)
    at Java.util.stream.ReferencePipeline.collect(ReferencePipeline.Java:499)
    at com.example.khan.vaquar.RemovedDuplicate.main(RemovedDuplicate.Java:48)
0
vaquar khan