ডুপ্লিকেট কীটি হ্যাশম্যাপে রাখলে কী ঘটে?


276

যদি আমি একই কী একাধিকবার HashMapএর putপদ্ধতিতে পাস করি তবে মূল মানটির কী হবে? এবং এমনকি যদি মানটি পুনরাবৃত্তি করে? আমি এটিতে কোনও ডকুমেন্টেশন পাইনি।

কেস 1: একটি কী এর জন্য ওভাররাইট করা মান

Map mymap = new HashMap();
mymap.put("1","one");
mymap.put("1","not one");
mymap.put("1","surely not one");
System.out.println(mymap.get("1"));

আমরা পেতে surely not one

কেস 2: সদৃশ মান

Map mymap = new HashMap();
mymap.put("1","one");
mymap.put("1","not one");
mymap.put("1","surely not one");
// The following line was added:
mymap.put("1","one");
System.out.println(mymap.get("1"));

আমরা পেতে one

তবে অন্যান্য মানগুলির কি হয়? আমি একজন ছাত্রকে বুনিয়াদি শেখাচ্ছিলাম এবং আমাকে এটি জিজ্ঞাসা করা হয়েছিল। কি Mapএকটি বালতি যেখানে সর্বশেষ মান উল্লেখ করা হয় (কিন্তু স্মৃতিতে) মত?


7
বিটিডাব্লু, এটি মাল্টি- হ্যাশম্যাপটি দেখানোর জন্য একটি দুর্দান্ত সুযোগ যা জাকার্তা সংগ্রহের ক্লাসের অংশ ( Commons.apache.org/colferences )। এটি আপনাকে যখন প্রয়োজন হবে একই সময়ে একই কী এর সাথে সংখ্যক মান যুক্ত করতে দেবে।
জন মুন্ছ

উত্তর:


303

সংজ্ঞা অনুসারে, putকমান্ডটি মানচিত্রে প্রদত্ত কীটির সাথে যুক্ত পূর্ববর্তী মানটিকে প্রতিস্থাপন করে (ধারণাগতভাবে আদিম প্রকারের জন্য অ্যারে সূচক ক্রিয়াকলাপের মতো)।

মানচিত্রটি কেবল তার মানটির রেফারেন্স ফেলে দেয়। যদি অন্য কোনও কিছুর অবজেক্টের কোনও রেফারেন্স না থাকে, তবে সেই বস্তু আবর্জনা সংগ্রহের জন্য যোগ্য হয়ে ওঠে। অতিরিক্তভাবে, জাভা প্রদত্ত কীটির সাথে যুক্ত পূর্ববর্তী কোনও মান (বা nullউপস্থিত না থাকলে) প্রদান করে, যাতে আপনি সেখানে কী ছিল তা নির্ধারণ করতে পারেন এবং প্রয়োজনে একটি রেফারেন্স বজায় রাখতে পারেন।

এখানে আরও তথ্য: হ্যাশম্যাপ ডক


এর জন্য ধন্যবাদ. জাভা ডকুমেন্টেশন যদিও এটি স্পষ্টভাবে উল্লেখ করা হয়নি পড়া। আমি অনুমান করছি ডকটির লেখক এটিকে সমস্ত হ্যাশ মানচিত্র প্রয়োগের স্বচ্ছ ধারণা বলে ধরে নিয়েছেন।
অ্যান্ড্রু এস

77

আপনি উত্তরটি ম্যাপ # পুটের (কে, ভি) জাভাডোকের মধ্যে খুঁজে পেতে পারেন (যা আসলে কিছু দেয়):

public V put(K key,
             V value)

এই মানচিত্রে নির্দিষ্ট কীটির সাথে নির্দিষ্ট মানটি সংযুক্ত করে (alচ্ছিক ক্রিয়াকলাপ)। যদি মানচিত্রে আগে এই কীটির জন্য ম্যাপিং থাকে তবে পুরানো মান নির্দিষ্ট মান দ্বারা প্রতিস্থাপিত হয়। (একটি মানচিত্রে mএকটি কীটির ম্যাপিং রয়েছে kএবং যদি m.containsKey(k)তা কেবল ফিরে আসে তবে তা বলা হয় true))

পরামিতি:
key - নির্দিষ্ট মানটির সাথে সম্পর্কিত হওয়া কী key
value- নির্দিষ্ট কীটির সাথে সম্পর্কিত হতে হবে মান।

রিটার্নস:
নির্দিষ্ট কীগুলির সাথে যুক্ত পূর্ববর্তী মান, বা nullযদি কোনও ম্যাপিং না থাকে key। (কোনও nullপ্রত্যাবর্তন এটিও নির্দেশ করতে পারে যে মানচিত্র পূর্বে nullউল্লিখিতগুলির সাথে সম্পর্কিত key, যদি বাস্তবায়ন nullমানগুলি সমর্থন করে ))

সুতরাং আপনি কল করার সময় যদি ফেরত মান বরাদ্দ না করেন তবে mymap.put("1", "a string")এটি কেবল অযৌক্তিক হয়ে যায় এবং এভাবে আবর্জনা সংগ্রহের জন্য যোগ্য।


3
ফিরে মান হয় পূর্ববর্তী মান (অথবা nullতাই হয়, হ্যাঁ, এই কি আমি বলতে চাচ্ছি হয়) শুধু javadoc উপরে নথিভুক্ত। এটি কি সত্যিই ভুল ব্যাখ্যা করা যায়?
পাসক্ল থিভেন্ট

এটি খুব সহায়ক।
রুট ট্র্যাভেলার

18

কীটির পূর্বের মানটি বাদ দিয়ে নতুনটির সাথে প্রতিস্থাপন করা হয়।

যদি আপনি সমস্ত মান একটি কী দেওয়া হয় তা রাখতে চান, আপনি এই জাতীয় কিছু বাস্তবায়নের বিবেচনা করতে পারেন:

import org.apache.commons.collections.MultiHashMap;
import java.util.Set;
import java.util.Map;
import java.util.Iterator;
import java.util.List;
public class MultiMapExample {

   public static void main(String[] args) {
      MultiHashMap mp=new MultiHashMap();
      mp.put("a", 10);
      mp.put("a", 11);
      mp.put("a", 12);
      mp.put("b", 13);
      mp.put("c", 14);
      mp.put("e", 15);
      List list = null;

      Set set = mp.entrySet();
      Iterator i = set.iterator();
      while(i.hasNext()) {
         Map.Entry me = (Map.Entry)i.next();
         list=(List)mp.get(me.getKey());

         for(int j=0;j<list.size();j++)
         {
          System.out.println(me.getKey()+": value :"+list.get(j));
         }
      }
   }
}

1
এই দ্রষ্টব্য চিত্রিত হয়। মাল্টিহ্যাশম্যাপটি অ্যাপাচি ডট কমস সংগ্রহগুলির অংশ এবং জাভা নয়।
উইকিমিক্স

17

এটি কী / মান বৈশিষ্ট্য এবং আপনার বেশ কয়েকটি মানের জন্য নকল কী থাকতে পারে না কারণ আপনি
যখন "1" এর মান পেতে চান তখন আপনার উদাহরণের মধ্যে কোনটি মূল্যের অন্তর্ভুক্ত যা প্রকৃত মানটি পেতে চাইবে যখন পেতে চান এটা ?!
প্রতিটি কারণের জন্য স্বতন্ত্র কী থাকার কারণগুলি কিন্তু আপনি জাভা স্ট্যান্ডার্ড লিব দ্বারা কৌশলটি পেতে পারেন:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class DuplicateMap<K, V> {

    private Map<K, ArrayList<V>> m = new HashMap<>();

    public void put(K k, V v) {
        if (m.containsKey(k)) {
            m.get(k).add(v);
        } else {
            ArrayList<V> arr = new ArrayList<>();
            arr.add(v);
            m.put(k, arr);
        }
    }

     public ArrayList<V> get(K k) {
        return m.get(k);
    }

    public V get(K k, int index) {
        return m.get(k).size()-1 < index ? null : m.get(k).get(index);
    }
}


এবং আপনি এটি এইভাবে ব্যবহার করতে পারেন:

    public static void main(String[] args) {
    DuplicateMap<String,String> dm=new DuplicateMap<>();
    dm.put("1", "one");
    dm.put("1", "not one");
    dm.put("1", "surely not one");
    System.out.println(dm.get("1"));
    System.out.println(dm.get("1",1));
    System.out.println(dm.get("1", 5));
}

এবং মুদ্রণের ফলাফল হ'ল:

[one, not one, surely not one]
not one
null

দুর্দান্ত উত্তর! ভাল করেছ. আপনি আক্ষরিকভাবে আমার প্রোগ্রামিং জীবন সংরক্ষণ করুন :)।
সুবিন বাবু

আমার কাছ থেকেও ধন্যবাদ! সাধারণ মানচিত্রের মতো একই কার্যকারিতা সম্পাদনের জন্য আমাকে এতে একটি "অপসারণ" পদ্ধতি যুক্ত করতে হয়েছিল তবে দুর্দান্ত কাজ করেছে!
জেগ্লাস

1
@ জেগ্লাস আপনার স্বাগতম বন্ধু, কিন্তু এটি প্রযুক্তিগত সমাধান নয়, আপনি জাভা স্ট্যান্ডার্ড লিব দ্বারা এটি করতে পারেন, প্রযুক্তিগত সমস্যায় আপনাকে অবশ্যই আপনার সমস্যার উপর নজর রাখতে হবে, যদি আপনার এই আচরণের দরকার হয় তবে আমি নিশ্চিত যে এটি সমাধান নয় কারণ কী / মান ধারণার, এবং অবশ্যই সমস্যাটি সম্পর্কে চিন্তাভাবনা করা উচিত এবং সমাধানের যৌক্তিক উপায় খুঁজে বের করতে হবে। যাইহোক আমার বিশদটি জাভা এবং উত্পাদনের ক্ষেত্রে মজাদার উপায়, মজাদার কাজের সাথে সমস্যা এবং সমাধানের পথ খুব আলাদা! যখন আপনি কী / মান আচরণটি আপনার সমস্যা না হয় এবং সেই জাতীয় ডেটা কাঠামো খুঁজে পাওয়া যায় তখন আপনি এটি ব্যবহার করতে পারেন।
java acm

13

এই মানচিত্রে নির্দিষ্ট কীটির সাথে নির্দিষ্ট মানটি সংযুক্ত করে। যদি মানচিত্রে আগে কীটির জন্য ম্যাপিং থাকে তবে পুরানো মানটি প্রতিস্থাপন করা হবে।


12

এটি মানকটিতে বিদ্যমান কীটির সাথে সম্পর্কিত কীটির প্রতিস্থাপন করে । এবং যদি একই নামের সাথে কোনও কী উপস্থিত না থাকে তবে এটি প্রদত্ত মান সহ একটি কী তৈরি করে। উদাহরণ:

Map mymap = new HashMap();
mymap.put("1","one");
mymap.put("1","two");

OUTPUT কী = "1", মান = "দুই"

সুতরাং, পূর্ববর্তী মানটি ওভাররাইট হয়ে যায়।


4

আপনার প্রশ্নের মানচিত্রটি বালতির মতো ছিল কিনা: না।

এটি name=valueজোড়া যুক্ত তালিকার মতো যেখানে nameস্ট্রিং হওয়ার দরকার নেই (যদিও এটি হতে পারে)।

একটি উপাদান পেতে, আপনি get () - পদ্ধতিতে আপনার কীটি পাস করুন যা আপনাকে বিনিময়ে বরাদ্দ করা অবজেক্ট দেয় gives

এবং একটি হ্যাশ মানচিত্রের অর্থ হ'ল আপনি যদি গেট -পদ্ধতিটি ব্যবহার করে আপনার অবজেক্টটি পুনরুদ্ধার করার চেষ্টা করছেন, তবে এটি আপনার সরবরাহ করা জিনিসটির সাথে আসল বস্তুর তুলনা করবে না, কারণ এটির তালিকাটি পুনরাবৃত্তি করতে হবে এবং কীটি তুলনা করতে হবে () আপনি বর্তমান উপাদান সরবরাহ করেছেন।

এটি অকার্যকর হবে। পরিবর্তে, আপনার বস্তুটি যা নিয়ে গঠিত তা বিবেচনাধীন, এটি উভয় বস্তু থেকে তথাকথিত হ্যাশকোড গণনা করে এবং সেগুলির সাথে তুলনা করে। intদুটি সম্পূর্ণ (সম্ভবত গভীরতর জটিল) বস্তুর পরিবর্তে দুটি তুলনা করা আরও সহজ । আপনি পূর্বনির্ধারিত দৈর্ঘ্যের (ইন্ট) সংক্ষিপ্তসার মতো হ্যাশকোডটি কল্পনা করতে পারেন, সুতরাং এটি অনন্য নয় এবং এর সংঘর্ষ রয়েছে। আপনি যে ডকুমেন্টেশনে লিঙ্কটি সন্নিবেশ করিয়েছেন তাতে হ্যাশকোডের নিয়মগুলি খুঁজে পেয়েছেন।

আপনি যদি এই সম্পর্কে আরও জানতে চান তবে আপনি javapractices.com এবং টেকনোফান্ডো.কম এর নিবন্ধগুলি একবার দেখে নিতে চান

শুভেচ্ছা


3

আমি সর্বদা ব্যবহৃত:

HashMap<String, ArrayList<String>> hashy = new HashMap<String, ArrayList<String>>();

যদি আমি একটি সনাক্তকারী কীতে একাধিক জিনিস প্রয়োগ করতে চাইতাম।

public void MultiHash(){
    HashMap<String, ArrayList<String>> hashy = new HashMap<String, ArrayList<String>>();
    String key = "Your key";

    ArrayList<String> yourarraylist = hashy.get(key);

    for(String valuessaved2key : yourarraylist){
        System.out.println(valuessaved2key);
    }

}

আপনি সর্বদা এই জাতীয় কিছু করতে এবং নিজেকে একটি গোলকধাঁধা তৈরি করতে পারেন!

public void LOOK_AT_ALL_THESE_HASHMAPS(){
    HashMap<String, HashMap<String, HashMap<String, HashMap<String, String>>>> theultimatehashmap = new HashMap <String, HashMap<String, HashMap<String, HashMap<String, String>>>>();
    String ballsdeep_into_the_hashmap = theultimatehashmap.get("firststring").get("secondstring").get("thirdstring").get("forthstring");
}

2

জেডিকে থেকে মানচিত্রগুলি সদৃশ কীগুলির দ্বারা ডেটা সঞ্চয় করার জন্য নয়।

  • সর্বোত্তম নতুন মানটি পূর্বেরগুলিকে ওভাররাইড করবে।

  • সবচেয়ে খারাপ পরিস্থিতি ব্যতিক্রম (যেমন আপনি যখন এটি স্ট্রিম হিসাবে সংগ্রহ করার চেষ্টা করেন):

কোনও সদৃশ নেই:

Stream.of("one").collect(Collectors.toMap(x -> x, x -> x))

ঠিক আছে. আপনি পাবেন: $ 2 ==> {এক = এক}

সদৃশ স্ট্রিম:

Stream.of("one", "not one", "surely not one").collect(Collectors.toMap(x -> 1, x -> x))

ব্যতিক্রম java.lang.IllegalStateException: সদৃশ কী 1 (মানগুলি একের সাথে একত্রিত করার চেষ্টা করা হয়নি) | কালেক্টর.ডুপ্লিকেটকীএক্সেপশন (কালেক্টরস.জভা অনুচ্ছেদ) | সংগ্রাহকগুলিতে mb ল্যাম্বদা K uniqKeysMapAccumulator $ 1 (সংগ্রাহক j জাভা 80৮৮০) | এ রিডিউসঅপ্স $ 3 রিডুকিংসিংক.অ্যাকসেপ্ট (রিডিউসওপস.জভা অনুষ্টে) | স্প্লিটরেটরে $ অ্যারেস্প্লিটরেটর.ফোরেচরাইমাইনিং (স্প্লিটেটর.জভা: ৯৮৪) | অ্যাবস্ট্রাক্ট পাইপলাইন.কপিআইন্টো (অ্যাবস্ট্রাক্ট পাইপলাইন.জভা ৪৪৮৪) | অ্যাবস্ট্রাক্ট পাইপলাইনে.রেপঅ্যান্ডকপিআইন্টো (অ্যাবস্ট্রাক্ট পাইপলাইন.জভা ৪৪74৪) | ReduceOps এ $ হ্রাসওপস.এভালুয়েটসেকিউশিয়াল (হ্রাস) অ্যাবস্ট্রাক্ট পাইপলাইন.ভালভেট (অ্যাবস্ট্রাক্ট পাইপলাইন.জভা রেকর্ড 34) | রেফারেন্সপাইপলাইন.কলেক্টে (রেফারেন্সপাইপলাইন.জভা.৫7878৮) | এ (# 4: 1)

সদৃশ কীগুলি ব্যবহার করার জন্য - অন্যান্য প্যাকেজ ব্যবহার করুন, যেমন: https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/ মাল্টিম্যাপ html

নকল কীগুলি নিয়ে কাজ করার মতো আরও অনেকগুলি বাস্তবায়ন রয়েছে। ওয়েবের জন্য এটি প্রয়োজনীয় (যেমন ডুপ্লিকেট করা কুকি কীগুলি, এইচটিপিপি শিরোনামগুলির একই ক্ষেত্র থাকতে পারে, ...)

শুভকামনা! :)


"ওভাররাইড" অপারেশন ব্যয়বহুল?
গৌরব

এটি কেবল জেডিকে ব্যবহার করে সমাধান করা যেতে পারে। Collectors.toMap()তৃতীয় যুক্তি রয়েছে - মার্জ ফাংশন। কেবলমাত্র আমরা গত ডুপ্লিকেট উপাদান ওভাররাইড করতে চাইলে: Stream.of("one", "two", "one").collect(Collectors.toMap(x -> x, x -> x, (key1, key2) -> key2))লিঙ্ক
একা দাঁড়িয়ে

এছাড়াও আপনার দ্বিতীয় কোড উদাহরণটি সঠিক নয়। এই ইনপুট: "one", "not one", "surely not one"সমস্ত স্ট্রিং আলাদা হওয়ার কারণে কোনও সদৃশ কী ত্রুটি তৈরি হবে না।
একা দাঁড়িয়ে থাকুন

হাই @ স্ট্যান্ড একা। দয়া করে ম্যাপিং ফাংশনটি (টু ম্যাপ) সাবধানতার সাথে পড়ুন।
উইটোল্ড কাকজুরবা

হাই @ উইটলডক্যাজুরবা পোস্ট করার আগে দয়া করে আপনার কোডটি সংকলন করুন।
একা দাঁড়িয়ে

1

বিটিডাব্লু, আপনি যদি কিছু শব্দার্থবিজ্ঞান চান তবে এই কীটি উপস্থিত না থাকলে কেবল রাখুন। আপনি ফাংশন concurrentHashMapদিয়ে ব্যবহার করতে পারেন putIfAbsent()। এটা দেখ:

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html#put(K,%20V)

concurrentHashMap থ্রেডটি উচ্চ কার্যকারিতা সহ নিরাপদ কারণ এটি থ্রুপুট উন্নত করতে " লক স্ট্রিপিং " প্রক্রিয়া ব্যবহার করে।


1

হ্যাঁ, এর অর্থ মান সহ সমস্ত 1 টি শেষ যুক্ত মানের সাথে ওভাররাইট করা হয়েছে এবং এখানে আপনি "অবশ্যই একটি নয়" যুক্ত করেছেন যাতে এটি কেবল "অবশ্যই একটি নয়" প্রদর্শিত হবে।

এমনকি যদি আপনি একটি লুপ দিয়ে প্রদর্শনের চেষ্টা করছেন তবে এটি কেবল একটি কী এবং মান একই ধরণের কী প্রদর্শন করবে।


0
         HashMap<Emp, Emp> empHashMap = new HashMap<Emp, Emp>();

         empHashMap.put(new Emp(1), new Emp(1));
         empHashMap.put(new Emp(1), new Emp(1));
         empHashMap.put(new Emp(1), new Emp());
         empHashMap.put(new Emp(1), new Emp());
         System.out.println(empHashMap.size());
    }
}

class Emp{
    public Emp(){   
    }
    public Emp(int id){
        this.id = id;
    }
    public int id;
    @Override
    public boolean equals(Object obj) {
        return this.id == ((Emp)obj).id;
    }

    @Override
    public int hashCode() {
        return id;
    }
}


OUTPUT : is 1

মানে হ্যাশ ম্যাপটি ডুপ্লিকেটগুলিকে মঞ্জুরি দেয় না, যদি আপনার সঠিকভাবে সমান ও হ্যাশকোড () পদ্ধতি থাকে।

হ্যাশসেট অভ্যন্তরীণভাবে হ্যাশম্যাপ ব্যবহার করে, উত্স ডকটি দেখুন

public class HashSet{
public HashSet() {
        map = new HashMap<>();
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.