হ্যাশম্যাপে কী অস্তিত্ব চেক


309

হ্যাশম্যাপে কী অস্তিত্বের জন্য যাচাই করা সর্বদা প্রয়োজনীয়?

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

এটি একটি ভাল প্রোগ্রামিং অনুশীলন নাও হতে পারে তবে এটি আমাকে অ্যাক্সেসের সংখ্যা হ্রাস করতে সহায়তা করবে। নাকি আমি এখানে কিছু মিস করছি?

[ আপডেট ] হ্যাশম্যাপে আমার নাল মান নেই।


8
"সুতরাং এবং ব্যতিক্রম ঘটে" - কি ব্যতিক্রম? এটি java.util.HashMap থেকে হবে না ...
সার্জ

উত্তর:


513

আপনি কি কখনও একটি নাল মান সঞ্চয় করেন? যদি তা না হয় তবে আপনি কেবল এটি করতে পারেন:

Foo value = map.get(key);
if (value != null) {
    ...
} else {
    // No such key
}

অন্যথায়, আপনি যদি একটি নাল মান ফিরে পান তবে আপনি কেবল অস্তিত্বের জন্য পরীক্ষা করতে পারেন:

Foo value = map.get(key);
if (value != null) {
    ...
} else {
    // Key might be present...
    if (map.containsKey(key)) {
       // Okay, there's a key but the value is null
    } else {
       // Definitely no such key
    }
}

1
@ সামুয়েল: কেবল তখনই সম্ভব হয় যখন সম্ভব হয়। মানচিত্রে যদি আপনার স্পষ্টভাবে নাল মান না থাকে তবে কেবল getভাল, এবং আপনার যখন মানটির প্রয়োজন হয় তখন দুটি চেহারাও এড়িয়ে চলুন।
জন স্কিটি

যদিও এটি সম্ভবত উদাহরণ হিসাবে আরও স্পষ্ট, আপনি if(value!=null || map.containsKey(key))দ্বিতীয় অংশের জন্যও লিখতে পারেন । কমপক্ষে যদি আপনি একই জিনিসটি কোনওভাবেই করতে চান - কোনও পুনরাবৃত্তি কোড নেই। শর্ট সার্কিটের কারণে এটি কাজ করবে ।
কুল্লব

66

কীটি উপস্থিত রয়েছে তা যাচাই করে আপনি কিছু অর্জন করতে পারবেন না। এটি কোড HashMap:

@Override
public boolean containsKey(Object key) {
    Entry<K, V> m = getEntry(key);
    return m != null;
}

@Override
public V get(Object key) {
    Entry<K, V> m = getEntry(key);
    if (m != null) {
        return m.value;
    }
    return null;
}

এর জন্য ফেরতের মান get()আলাদা কিনা তা পরীক্ষা করে দেখুন null

এটি হ্যাশম্যাপ উত্স কোড।


সংস্থানসমূহ:


2
এই পদ্ধতির একটি নির্দিষ্ট বাস্তবায়ন দেখানোর কী লাভ?
jarnbjo

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

একটি ভাল লিঙ্কটি হ'ল গ্রেপকোড / ফাইল / রেপোসিটরি.grepcode.com/java/root/jdk/openjdk/… ( ওপেনজেডি কে খুব দৃ strongly়ভাবে সূর্যের কোড থেকে প্রাপ্ত) এবং দেখে মনে হচ্ছে যে আমি ভুল। আমি জাভা 5 এর সাথে জাভা 6 এর সাথে সংস্করণটি তুলনা করছি; তারা এই অঞ্চলে আলাদাভাবে কাজ করে (তবে উভয়ই সঠিক, যেমন আপনি পোস্ট করেছেন স্নিপেটগুলি)।
ডোনাল ফেলো

2
গৃহীত উত্তরে নির্দেশিত হিসাবে, এই স্নোভারটি সম্পূর্ণ ভুল। মানগুলির তুলনা করে কী কী অস্তিত্ব রয়েছে তা পরীক্ষা করে আপনি কিছু অর্জন করতে পারেন - আপনি বিদ্যমান কীগুলি থেকে অ-বিদ্যমান কীগুলি পৃথক করতে পারেন তবে মান হিসাবে ম্যাপ করা হয়েছে।
জোহানেস এইচ।

43

আরও ভাল উপায় হল containsKeyপদ্ধতি ব্যবহার করা HashMap। আগামীকাল কেউ মানচিত্রে শূন্যতা যুক্ত করবে। আপনার কী উপস্থিতি এবং কী এর নাল মানের মধ্যে পার্থক্য করা উচিত।


হ্যাঁ। বা পুরোপুরি স্টোর করা রোধ করতে হ্যাশম্যাপ সাবক্লাস করুন null
রবউউ

1
আদিম ধরণের জন্য 1+ মূল্য হিসাবে অপ্রয়োজনীয় cast
ালার

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

23

আপনি কি কোডটি পছন্দ করেছেন তার অর্থ?

if(map.containsKey(key)) doSomethingWith(map.get(key))

সব জায়গায় বেশি ? তারপরে আপনার map.get(key)খালি খালি নালাগুলি ফিরে এসেছে কিনা তা পরীক্ষা করা উচিত । যাইহোক, হ্যাশম্যাপ কী অনুপস্থিত কীগুলির জন্য ব্যতিক্রম ছুঁড়ে না, পরিবর্তে এটি বাতিল করে দেয়। containsKeyনাল মানগুলি সংরক্ষণ করার সময় নাল মান এবং অনুপস্থিত মানের মধ্যে পার্থক্য করার জন্য কেবলমাত্র ক্ষেত্রে প্রয়োজন হয় তবে এটি সাধারণত খারাপ অভ্যাস হিসাবে বিবেচিত হয়।


8

কেবল containsKey()স্বচ্ছতার জন্য ব্যবহার করুন । এটি দ্রুত এবং কোডটি পরিষ্কার এবং পঠনযোগ্য রাখে। সমগ্র বিন্দু HashMapগুলি যে কী লুকআপ দ্রুত, ঠিক নিশ্চিত হয় hashCode()এবং equals()সঠিকভাবে প্রয়োগ করা হয়।



3

computeIfAbsent()ক্লাসেও আপনি পদ্ধতিটি ব্যবহার করতে পারেন HashMap

নিম্নলিখিত উদাহরণে, mapকী (ব্যাঙ্ক অ্যাকাউন্টের নাম) এ প্রয়োগ করা লেনদেনের (পূর্ণসংখ্যার) একটি তালিকা সঞ্চয় করে। এর 2 টি লেনদেন যুক্ত করতে 100এবং 200আপনি checking_accountলিখতে পারেন:

HashMap<String, ArrayList<Integer>> map = new HashMap<>();
map.computeIfAbsent("checking_account", key -> new ArrayList<>())
   .add(100)
   .add(200);

এইভাবে কীটি checking_accountবিদ্যমান আছে কি নেই তা দেখার জন্য আপনাকে পরীক্ষা করতে হবে না।

  • এটি উপস্থিত না থাকলে লাম্বডা এক্সপ্রেশন দ্বারা একটি তৈরি এবং ফিরে আসবে।
  • যদি এটি বিদ্যমান থাকে, তবে কীটির মানটি ফিরে আসবে computeIfAbsent()

সত্যিই মার্জিত! 👍


0

আমি সাধারণত আইডিয়াম ব্যবহার করি

Object value = map.get(key);
if (value == null) {
    value = createValue(key);
    map.put(key, value);
}

এর অর্থ কীটি অনুপস্থিত থাকলে আপনি কেবলমাত্র দুবার মানচিত্রে আঘাত করবেন


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

0

জোন স্কিটির উত্তরটি একটি দক্ষ উপায়ে দুটি পরিস্থিতি ( nullমান সহ মানচিত্র নয় মানচিত্র null) ভালভাবে সম্বোধন করেছে ।

নম্বর এন্ট্রি এবং দক্ষতার উদ্বেগ সম্পর্কে, আমি কিছু যুক্ত করতে চাই।

আমার একটি 1.000 এন্ট্রি বলার সাথে একটি হ্যাশম্যাপ রয়েছে এবং আমি দক্ষতাটি উন্নত করতে চাই। যদি হ্যাশম্যাপটি খুব ঘন ঘন অ্যাক্সেস করা হয়ে থাকে তবে প্রতিটি অ্যাক্সেসে মূল অস্তিত্বের জন্য পরীক্ষা করা বড় ওভারহেডের দিকে নিয়ে যায়।

1.000 এন্ট্রি সহ একটি মানচিত্র একটি বিশাল মানচিত্র নয়।
পাশাপাশি 5.000 বা 10.000 এন্ট্রি সহ একটি মানচিত্র।
Mapএই জাতীয় মাত্রা দিয়ে দ্রুত পুনরুদ্ধার করার জন্য ডিজাইন করা হয়েছে।

এখন, এটি ধরে নেওয়া হয়েছে যে hashCode()মানচিত্র কীগুলি একটি ভাল বিতরণ সরবরাহ করে।

আপনি যদি কোনও Integerকী টাইপ হিসাবে ব্যবহার করতে পারেন তবে এটি করুন।
এর hashCode()পদ্ধতিটি অত্যন্ত দক্ষ কারণ সংঘর্ষগুলি অনন্য intমূল্যবোধগুলির পক্ষে সম্ভব নয় :

public final class Integer extends Number implements Comparable<Integer> {
    ...
    @Override
    public int hashCode() {
        return Integer.hashCode(value);
    }

    public static int hashCode(int value) {
        return value;
    }
    ...
}

যদি কীটির জন্য, আপনাকে অন্য একটি অন্তর্নির্মিত ধরণের ব্যবহার করতে হবে যেমন Stringউদাহরণস্বরূপ ব্যবহৃত হয় Map, আপনার কিছু সংঘর্ষ হতে পারে তবে 1 হাজার থেকে কয়েক হাজার অবজেক্টে Map, String.hashCode()পদ্ধতি হিসাবে আপনার খুব কম হওয়া উচিত একটি ভাল বিতরণ সরবরাহ করে।

আপনি যদি একটি কাস্টম প্রকার ব্যবহার করেন তবে ওভাররাইড hashCode()এবং equals()সঠিকভাবে এবং সামগ্রিকভাবে নিশ্চিত করুন যা hashCode()একটি ন্যায্য বিতরণ সরবরাহ করে।
আপনি এটি আইটেম রেফারেন্স 9 এর Java Effectiveউল্লেখ করতে পারেন।
এখানে একটি পোস্ট এখানে উপায় বিবরণ।

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