এটি একটি আছে কি সম্ভব HashMap
আগমন সমস্ত কী সেট পাওয়া যায় না জন্য ডিফল্ট মান?
এটি একটি আছে কি সম্ভব HashMap
আগমন সমস্ত কী সেট পাওয়া যায় না জন্য ডিফল্ট মান?
উত্তর:
[হালনাগাদ]
অন্যান্য উত্তর এবং মন্তব্যকারীদের দ্বারা উল্লিখিত হিসাবে, জাভা 8 হিসাবে আপনি কেবল কল করতে পারেন Map#getOrDefault(...)
।
[মূল]
এমন কোনও মানচিত্রের বাস্তবায়ন নেই যা হুবহু এটি করে তবে এটি হ্যাশম্যাপকে প্রসারিত করে নিজের বাস্তবায়ন করা তুচ্ছ হবে:
public class DefaultHashMap<K,V> extends HashMap<K,V> {
protected V defaultValue;
public DefaultHashMap(V defaultValue) {
this.defaultValue = defaultValue;
}
@Override
public V get(Object k) {
return containsKey(k) ? super.get(k) : defaultValue;
}
}
(v == null)
করার (v == null && !this.containsKey(k))
ক্ষেত্রে আপনি শর্তটি এ থেকে সামঞ্জস্য করতে চাইতে পারেন null
। আমি জানি, এটি কেবল একটি কর্নার কেস তবে লেখক এটির মধ্যে চলে যেতে পারে।
!this.containsValue(null)
। এটি থেকে subtly পৃথক !this.containsKey(k)
। containsValue
সমাধান যদি কিছু ব্যর্থ হবে অন্যান্য চাবি স্পষ্টভাবে মান অ্যাসাইন করা হয়েছে null
। উদাহরণস্বরূপ: map = new HashMap(); map.put(k1, null); V v = map.get(k2);
এই ক্ষেত্রে, v
এখনও null
, সঠিক হবে?
জাভা 8-এ, Map.getOrDefault ব্যবহার করুন । এটি কীটি নেয় এবং যদি কোনও মেলানো কী না পাওয়া যায় তবে ফিরে আসতে মানটি লাগে।
getOrDefault
খুব সুন্দর, তবে প্রত্যেকবার মানচিত্রটি অ্যাক্সেস করার সময় ডিফল্ট সংজ্ঞা প্রয়োজন। কোনও ডিফল্ট মান একবারে সংজ্ঞায়িত করার সাথে মানগুলির স্থিতিশীল মানচিত্র তৈরি করার সময় পঠনযোগ্যতা সুবিধাও পাওয়া যায়।
private static String get(Map map, String s) { return map.getOrDefault(s, "Error"); }
আপনি যদি চক্রটিকে পুনর্সামকরণের মতো মনে করেন না, যেমন কমন্স'স ডিফল্টম্যাপ ব্যবহার করুন ,
Map<String, String> map = new DefaultedMap<>("[NO ENTRY FOUND]");
String surname = map.get("Surname");
// surname == "[NO ENTRY FOUND]"
আপনি যদি প্রথম স্থানে মানচিত্র তৈরির দায়িত্বে না থাকেন তবে আপনি কোনও বিদ্যমান মানচিত্রেও পাস করতে পারেন।
জাভা 8 ইন্টারফেসে একটি দুর্দান্ত কম্পিউটআইফএবসেন্ট ডিফল্ট পদ্ধতি চালু করেছে Map
যা অলস-গণিত মান সঞ্চয় করে এবং তাই মানচিত্রের চুক্তি ভঙ্গ করে না:
Map<Key, Graph> map = new HashMap<>();
map.computeIfAbsent(aKey, key -> createExpensiveGraph(key));
উত্স: http://blog.javabien.net/2014/02/20/loadingcache-in-java-8-without-guava/
দাবি অস্বীকারকারী : এই উত্তরটি ওপি যা বলেছিল ঠিক তার সাথে মেলে না তবে কিছু ক্ষেত্রে প্রশ্নের শিরোনামের সাথে মিলে যাওয়া কার্যকর হতে পারে যখন কী সংখ্যা সীমিত থাকে এবং বিভিন্ন মানকে ক্যাশে করা লাভজনক হবে। এটি বিপুল ক্ষেত্রে প্রচুর কী এবং একই ডিফল্ট মান হিসাবে ব্যবহার করা উচিত নয় কারণ এটি অযথা মেমোরি নষ্ট করে।
আপনি কি ঠিক কোনও স্থির পদ্ধতি তৈরি করতে পারবেন না যা ঠিক এটি করে?
private static <K, V> V getOrDefault(Map<K,V> map, K key, V defaultValue) {
return map.containsKey(key) ? map.get(key) : defaultValue;
}
আপনি কেবলমাত্র নতুন ক্লাস তৈরি করতে পারেন যা হ্যাশম্যাপ উত্তরাধিকার সূত্রে প্রাপ্ত এবং getDefault পদ্ধতি যুক্ত করতে পারে। এখানে একটি নমুনা কোড রয়েছে:
public class DefaultHashMap<K,V> extends HashMap<K,V> {
public V getDefault(K key, V defaultValue) {
if (containsKey(key)) {
return get(key);
}
return defaultValue;
}
}
আমি মনে করি যে এড স্টাব তার মন্তব্যে নির্দিষ্ট কারণগুলির কারণে এবং আপনার মানচিত্র ইন্টারফেসের চুক্তিটি ভঙ্গ করবেন (সম্ভবত এটি কিছুটা কঠিন-সন্ধানের দিকে পরিচালিত করতে পারে ) কারণ আপনার বাস্তবায়নে আপনার (কে কী) পদ্ধতিটি ওভাররাইড করা উচিত নয় বাগ)।
get
পদ্ধতিটি ওভাররাইড না করার একটি বিষয় পেয়েছেন । অন্যদিকে - আপনার সমাধানটি ইন্টারফেসের মাধ্যমে শ্রেণিটি ব্যবহারের অনুমতি দেয় না, যা প্রায়শই হতে পারে।
ব্যবহার করুন:
myHashMap.getOrDefault(key, defaultValue);
এটি ডিফল্টরূপে এটি করে। এটি ফিরে আসে null
।
HashMap
ঠিকঠাক হলে কেবল এই কার্যকারিতার জন্য সাবক্লাসে আমার কাছে কিছুটা নির্বোধ মনে null
হয়।
NullObject
প্যাটার্ন ব্যবহার করেন তবে এটি ঠিক নয় , যদিও বা আপনার কোড জুড়ে নাল-চেকগুলি ছড়িয়ে দিতে চান না - এমন একটি ইচ্ছা যা আমি পুরোপুরি বুঝতে পারি।
জাভা 8+ এ
Map.getOrDefault(Object key,V defaultValue)
আমি লাজিমেপকে বেশ সহায়ক বলে মনে করেছি।
যখন মানচিত্রটিতে অস্তিত্ব নেই এমন কী দিয়ে get (অবজেক্ট) পদ্ধতিটি কল করা হয়, তখন কারখানাটি অবজেক্ট তৈরি করতে ব্যবহৃত হয়। অনুরোধ করা কীটি ব্যবহার করে তৈরি করা বস্তুটি মানচিত্রে যুক্ত করা হবে।
এটি আপনাকে এরকম কিছু করতে দেয়:
Map<String, AtomicInteger> map = LazyMap.lazyMap(new HashMap<>(), ()->new AtomicInteger(0));
map.get(notExistingKey).incrementAndGet();
get
প্রদত্ত কীটির জন্য একটি ডিফল্ট মান তৈরি করার কল । আপনি কারখানার যুক্তি দিয়ে কীভাবে ডিফল্ট মান তৈরি করবেন তা নির্দিষ্ট করে দিন LazyMap.lazyMap(map, factory)
। উপরের উদাহরণে মানচিত্রটি AtomicInteger
0 মান সহ নতুনতে সূচিত হয় ।
List<String>
- গ্রহণযোগ্য উত্তরটি ব্যবহার করে আমি কারখানার একটি (বলার চেয়ে) পরিবর্তে প্রতিটি নতুন কীর জন্য একই তালিকাটি ব্যবহার করার ঝুঁকি নিয়ে থাকি new ArrayList<String>()
।
সরাসরি নয়, তবে ক্লাসের গেট পদ্ধতিটি পরিবর্তন করতে আপনি প্রসারিত করতে পারেন। উদাহরণটি ব্যবহারের জন্য এখানে প্রস্তুত: http://www.java2s.com/ কোড / জাভা / সংগ্রহগুলি- ডেটা- স্ট্রাকচার / এক্সটেন্ডেড ভার্সনফজাওটিল হ্যাশম্যাপট্যাটপ্রোভিডেসনেট এক্সেটেডজেডডাওডাওক্যাটিটিংডেফাল্টালুএইচটিএম
/**
* Extension of TreeMap to provide default value getter/creator.
*
* NOTE: This class performs no null key or value checking.
*
* @author N David Brown
*
* @param <K> Key type
* @param <V> Value type
*/
public abstract class Hash<K, V> extends TreeMap<K, V> {
private static final long serialVersionUID = 1905150272531272505L;
/**
* Same as {@link #get(Object)} but first stores result of
* {@link #create(Object)} under given key if key doesn't exist.
*
* @param k
* @return
*/
public V getOrCreate(final K k) {
V v = get(k);
if (v == null) {
v = create(k);
put(k, v);
}
return v;
}
/**
* Same as {@link #get(Object)} but returns specified default value
* if key doesn't exist. Note that default value isn't automatically
* stored under the given key.
*
* @param k
* @param _default
* @return
*/
public V getDefault(final K k, final V _default) {
V v = get(k);
return v == null ? _default : v;
}
/**
* Creates a default value for the specified key.
*
* @param k
* @return
*/
abstract protected V create(final K k);
}
ব্যবহারের উদাহরণ:
protected class HashList extends Hash<String, ArrayList<String>> {
private static final long serialVersionUID = 6658900478219817746L;
@Override
public ArrayList<Short> create(Short key) {
return new ArrayList<Short>();
}
}
final HashList haystack = new HashList();
final String needle = "hide and";
haystack.getOrCreate(needle).add("seek")
System.out.println(haystack.get(needle).get(0));
আমার জেএসএনের একটি সার্ভার থেকে প্রাপ্ত ফলাফলগুলি পড়তে হবে যেখানে আমি ক্ষেত্রগুলি উপস্থিত থাকার গ্যারান্টি দিতে পারি না। আমি ক্লাস org.json.simple.JSONObject ব্যবহার করছি যা হ্যাশম্যাপ থেকে প্রাপ্ত। আমি নিযুক্ত কিছু সহায়ক কার্যাদি এখানে রয়েছে:
public static String getString( final JSONObject response,
final String key )
{ return getString( response, key, "" ); }
public static String getString( final JSONObject response,
final String key, final String defVal )
{ return response.containsKey( key ) ? (String)response.get( key ) : defVal; }
public static long getLong( final JSONObject response,
final String key )
{ return getLong( response, key, 0 ); }
public static long getLong( final JSONObject response,
final String key, final long defVal )
{ return response.containsKey( key ) ? (long)response.get( key ) : defVal; }
public static float getFloat( final JSONObject response,
final String key )
{ return getFloat( response, key, 0.0f ); }
public static float getFloat( final JSONObject response,
final String key, final float defVal )
{ return response.containsKey( key ) ? (float)response.get( key ) : defVal; }
public static List<JSONObject> getList( final JSONObject response,
final String key )
{ return getList( response, key, new ArrayList<JSONObject>() ); }
public static List<JSONObject> getList( final JSONObject response,
final String key, final List<JSONObject> defVal ) {
try { return response.containsKey( key ) ? (List<JSONObject>) response.get( key ) : defVal; }
catch( ClassCastException e ) { return defVal; }
}
মিশ্র জাভা / কোটলিন প্রকল্পগুলিতে কোটলিনের মানচিত্র.বিহীন ডেফল্ট বিবেচনা করে ।