স্রোত ব্যবহার করে মানচিত্র তৈরি করার সময় সদৃশগুলি উপেক্ষা করুন


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

আমি java.lang.IllegalStateException: Duplicate keyযখন একটি সদৃশ উপাদান পাওয়া যায়।

মানচিত্রে মান যুক্ত করার ক্ষেত্রে কি এই ধরনের ব্যতিক্রম উপেক্ষা করা সম্ভব?

যখন সদৃশ থাকে তখন কেবল সেই নকল কী উপেক্ষা করে চালিয়ে যাওয়া উচিত।


আপনি যদি এটি ব্যবহার করতে পারেন তবে হ্যাশসেট কীটি উপেক্ষা করবে, যদি এটি ইতিমধ্যে বিদ্যমান থাকে।
সাহিত্যে

@ অধিনায়ক-aryabhatta। হ্যাশসেটে কী কী মূল মান পাওয়া সম্ভব
পাতান

উত্তর:


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
সংঘর্ষের ঘটনা ঘটলে কি এই প্রবেশটিকে সম্পূর্ণ উপেক্ষা করা সম্ভব? মূলত, যদি আমি কখনও সদৃশ কীগুলির মুখোমুখি হই তবে আমি চাই না সেগুলি মোটে যুক্ত করা হোক। উপরের উদাহরণে, আমি আমার মানচিত্রে ঠিকানা 1 বা ঠিকানা 2 চাই না।
djkelly99

5
@ হেন্দি ইরাওয়ান: সদৃশ মানগুলি অনুমোদিত। একত্রীকরণ ফাংশনটি একই কী রয়েছে এমন দুটি মানের (বা মার্জ) মধ্যে নির্বাচন করা ।
রিকোলা

3
@ djkelly99 আসলে আপনি যা করতে পারেন, আপনাকে কেবল আপনার রিম্যাপিং ফাংশনটি রিটার্ন করতে হবে nullটু-ম্যাপ ডকটি দেখুন যা ডকটিকে মার্জ করার জন্য নির্দেশ করে যাতে বলা হয় যে রিম্যাপিং ফাংশনটি শূন্য হয়, ম্যাপিংটি সরানো হবে।
রিকোলা

98

যেমন জাভাডক্সে বলা হয়েছে :

যদি ম্যাপ করা কীগুলিতে ডুপ্লিকেট থাকে (সেই অনুযায়ী 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

@ অ্যালাস্টার উত্তরটি আমাকে অনেক সাহায্য করে, তবে যদি কেউ তথ্যটি গোছানোর চেষ্টা করে তবে আমি একটি অর্থপূর্ণ তথ্য যুক্ত করতে চাই।

যদি আপনার কাছে উদাহরণস্বরূপ, প্রতিটির জন্য দুটি 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

অন্য কেউ এই সমস্যাটি পাওয়ার জন্য কিন্তু মানচিত্রে ডুপ্লিকেট কীগুলি প্রবাহিত না করে নিশ্চিত করুন যে আপনার কী-ম্যাপার ফাংশন নাল মানগুলি ফিরিয়ে দিচ্ছে না

এটি ট্র্যাক করে রাখা খুব বিরক্তিকর কারণ ত্রুটিটি "ডুপ্লিকেট কী 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 ব্যবহার করে একটি কাস্টম ফিল্টার সঞ্চালন করুন llow

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

ধরে নিই আপনার কাছে লোক রয়েছে বস্তুর তালিকা List

  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)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.