धाराओं का उपयोग करके मानचित्र का निर्माण करते समय डुप्लिकेट को अनदेखा करें


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

java.lang.IllegalStateException: Duplicate keyजब एक डुप्लिकेट तत्व पाया जाता है तो मुझे मिलता है।

क्या मानचित्र में मूल्यों को जोड़ने पर इस तरह के अपवाद को अनदेखा करना संभव है?

जब डुप्लिकेट होता है तो बस उस डुप्लिकेट कुंजी को अनदेखा करके जारी रखना चाहिए।


यदि आप इसका उपयोग कर सकते हैं, तो हैशसेट कुंजी को अनदेखा कर देगा, अगर यह पहले से मौजूद है।
sahitya

@ कप्तान-आर्यभट्ट। क्या हैशसेट में प्रमुख मान संभव है
पाटन

जवाबों:


448

यह संभव mergeFunctionहै Collectors.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एक फ़ंक्शन है जो एक ही कुंजी से जुड़े दो मूल्यों पर काम करता है। adress1तत्वों को एकत्रित करते समय पहले पता से adress2मेल खाती थी और दूसरे पते से मेल खाती थी: यह मेमना सिर्फ पहला पता रखने के लिए कहता है और दूसरे की उपेक्षा करता है।


5
मैं भ्रमित हूं, डुप्लिकेट मान (चाबियाँ नहीं) की अनुमति क्यों नहीं है? और डुप्लिकेट मानों को कैसे अनुमति दें?
हेंडी इरावन

क्या उस कुंजी को पुनः प्राप्त करने का कोई तरीका है जिसके लिए टक्कर होती है? यहाँ का जवाब: stackoverflow.com/questions/40761954/...
Guillaume

2
क्या इस प्रविष्टि को पूरी तरह से अनदेखा करना संभव है अगर कोई झड़प हो? असल में, अगर मुझे कभी डुप्लिकेट कुंजियों का सामना करना पड़ता है, तो मैं नहीं चाहता कि उन्हें बिल्कुल जोड़ा जाए। उपरोक्त उदाहरण में, मुझे अपने मानचित्र में address1 या address2 नहीं चाहिए।
djkelly99

5
@ हेंडी इरावन: डुप्लिकेट मानों की अनुमति है। मर्जिंग फ़ंक्शन को दो मानों के बीच (या मर्ज) चुना जाता है जिनके पास एक ही कुंजी है
रिकोला

3
@ djkelly99 वास्तव में आप कर सकते हैं, आपको बस अपना रीमैपिंग फंक्शन रिटर्न करना होगा null। देखें toMap डॉक कि इंगित मर्ज दस्तावेज़ कि राज्यों remapping समारोह रिटर्न शून्य हैं, मानचित्रण निकाल दिया जाता है।
रिकोला

98

जैसा कि JavaDocs में कहा गया है :

यदि मैप की गई कुंजियों में डुप्लिकेट (अनुसार Object.equals(Object)) हैं, IllegalStateExceptionतो संग्रह कार्रवाई किए जाने पर एक फेंक दिया जाता है। यदि मैप की गई कुंजी में डुप्लिकेट हो सकते हैं, तो toMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction)इसके बजाय उपयोग करें ।

इसलिए आपको toMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction)इसके बजाय उपयोग करना चाहिए । बस एक मर्ज फ़ंक्शन प्रदान करें , जो यह निर्धारित करेगा कि कौन से डुप्लिकेट को मानचित्र में रखा गया है।

उदाहरण के लिए, यदि आपको कोई परवाह नहीं है, तो बस कॉल करें

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

8

@Alaster जवाब मुझे बहुत मदद करता है, लेकिन अगर कोई व्यक्ति सूचनाओं को समूह बनाने की कोशिश कर रहा है तो मैं एक अर्थपूर्ण जानकारी जोड़ना चाहूंगा।

यदि आप हैं, उदाहरण के प्रति, दो Ordersएक ही साथ codeलेकिन अलग quantityसे हर एक के लिए उत्पादों की, और अपनी इच्छा है योग मात्रा में, आप कर सकते हैं:

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));

परिणाम:

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

1

वस्तुओं द्वारा समूहीकरण के लिए

Map<Integer, Data> dataMap = dataList.stream().collect(Collectors.toMap(Data::getId, data-> data, (data1, data2)-> {LOG.info("Duplicate Group For :" + data2.getId());return data1;}));

1

किसी और के लिए यह समस्या हो रही है, लेकिन मानचित्र में डुप्लिकेट कुंजियों के बिना स्ट्रीम किया जा रहा है, सुनिश्चित करें कि आपका keyapper फ़ंक्शन शून्य मान नहीं लौटा रहा है

यह नीचे ट्रैक करने के लिए बहुत कष्टप्रद है क्योंकि त्रुटि "डुप्लीकेट कुंजी 1" कहेगी जब 1 वास्तव में मूल्य है में कुंजी के बजाय प्रविष्टि का होता है।

मेरे मामले में, मेरे की-मैपर फ़ंक्शन ने भिन्न मानचित्र में मानों को देखने का प्रयास किया, लेकिन स्ट्रिंग में एक टाइपो के कारण अशक्त मान लौट रहे थे।

final Map<String, String> doop = new HashMap<>();
doop.put("a", "1");
doop.put("b", "2");

final Map<String, String> lookup = new HashMap<>();
doop.put("c", "e");
doop.put("d", "f");

doop.entrySet().stream().collect(Collectors.toMap(e -> lookup.get(e.getKey()), e -> e.getValue()));

0

ऑब्जेक्ट को समूहीकृत करते समय मुझे इस तरह की समस्या का सामना करना पड़ा है, मैंने हमेशा उन्हें एक सरल तरीके से हल किया: java.util का उपयोग करके एक कस्टम फ़िल्टर निष्पादित करें। अपनी पसंद की किसी भी विशेषता के साथ डुप्लिकेट ऑब्जेक्ट को हटाने के लिए bellow के रूप में देखें

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));

आशा है कि यह किसी को भी एक ही समस्या होने में मदद करता है!


-1

आप लोगों को मान लिया है कि वस्तु की सूची है

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

अब आपको दो चरणों की आवश्यकता है:

1)

people =removeDuplicate(people);

2)

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

यहाँ डुप्लिकेट को हटाने की विधि है

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;

      }

पूरा उदाहरण यहाँ जोड़ रहा हूँ

 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 + "]";
    }

}

परिणाम:

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)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.