পেয়ারা আমাদের জাভা প্রকারের জন্য দুর্দান্ত কারখানার পদ্ধতি সরবরাহ করে Maps.newHashMap()
।
তবে জাভা মানচিত্রের জন্য কি নির্মাতারা রয়েছেন?
HashMap<String,Integer> m = Maps.BuildHashMap.
put("a",1).
put("b",2).
build();
পেয়ারা আমাদের জাভা প্রকারের জন্য দুর্দান্ত কারখানার পদ্ধতি সরবরাহ করে Maps.newHashMap()
।
তবে জাভা মানচিত্রের জন্য কি নির্মাতারা রয়েছেন?
HashMap<String,Integer> m = Maps.BuildHashMap.
put("a",1).
put("b",2).
build();
উত্তর:
যেহেতু জাভা 9 Map
ইন্টারফেসে রয়েছে:
Map.of(k1,v1, k2,v2, ..)
Map.ofEntries(Map.entry(k1,v1), Map.entry(k2,v2), ..)
। এই কারখানা পদ্ধতির সীমাবদ্ধতা হ'ল:
null
কী এবং / অথবা মান হিসাবে গুলি ধরে রাখতে পারে না (যদি আপনাকে নালগুলি সঞ্চয় করতে হয় তবে অন্য উত্তরগুলি একবার দেখুন)আমাদের যদি পরিবর্তনীয় মানচিত্রের প্রয়োজন হয় (যেমন হাশম্যাপ) আমরা এর অনুলিপি-নির্মাতা ব্যবহার করতে পারি এবং এটির মাধ্যমে তৈরি করা মানচিত্রের সামগ্রীটি অনুলিপি করতে দিতে পারিMap.of(..)
Map<Integer, String> map = new HashMap<>( Map.of(1,"a", 2,"b", 3,"c") );
null
মানগুলিকে অনুমতি দেয় না যা ব্যবহারের ক্ষেত্রে নির্ভর করে সমস্যা হতে পারে।
Map.of(k1,v1, k2,v2, ...)
নিরাপদে ব্যবহার করা যেতে পারে যখন আমাদের অনেক মান নেই। বৃহত্তর মানগুলির জন্য Map.ofEntries(Map.entry(k1,v1), Map.entry(k2,v2), ...)
আমাদের আরও পঠনযোগ্য কোড দেয় যা ত্রুটির প্রবণতা কম (যদি না আমি আপনাকে ভুল বুঝি)।
হ্যাশম্যাপসের জন্য এ জাতীয় কোনও জিনিস নেই তবে আপনি একজন নির্মাতার সাথে একটি ইমটুটেবল ম্যাপ তৈরি করতে পারেন:
final Map<String, Integer> m = ImmutableMap.<String, Integer>builder().
put("a", 1).
put("b", 2).
build();
এবং যদি আপনার কোনও পরিবর্তনীয় মানচিত্রের প্রয়োজন হয় তবে আপনি কেবল এটি হ্যাশম্যাপ কনস্ট্রাক্টরকে খাওয়ান।
final Map<String, Integer> m = Maps.newHashMap(
ImmutableMap.<String, Integer>builder().
put("a", 1).
put("b", 2).
build());
ImmutableMap
null
মান সমর্থন করে না । তাই সেখানে এই পদ্ধতির সীমাবদ্ধতা হল: আপনি আপনার সেট করতে পারে না মান HashMap
থেকে null
।
new HashMap
স্থির Maps.newHashMap
পদ্ধতির পরিবর্তে জাভা কনস্ট্রাক্টর ব্যবহারে কোনও ভুল আছে কি ?
একেবারে বিল্ডার নয়, তবে একটি ইনিশিয়ালাইজার ব্যবহার করছেন:
Map<String, String> map = new HashMap<String, String>() {{
put("a", "1");
put("b", "2");
}};
map instanceof HashMap
মিথ্যা না? একটি দুর্দান্ত-ধারণা হিসাবে মনে হচ্ছে।
map.getClass()==HashMap.class
মিথ্যা প্রত্যাবর্তন করবে। তবে এটি যাইহোক একটি নির্বোধ পরীক্ষা। HashMap.class.isInstance(map)
পছন্দ করা উচিত, এবং এটি সত্য ফিরে আসবে।
এটি গ্রহণ করা উত্তরের মতো, তবে আমার দৃষ্টিতে কিছুটা ক্লিনার:
ImmutableMap.of("key1", val1, "key2", val2, "key3", val3);
উপরোক্ত পদ্ধতির বেশ কয়েকটি প্রকরণ রয়েছে এবং এগুলি স্থির, অপরিবর্তনীয়, পরিবর্তনীয় মানচিত্র তৈরির জন্য দুর্দান্ত great
এখানে একটি খুব সহজ ...
public class FluentHashMap<K, V> extends java.util.HashMap<K, V> {
public FluentHashMap<K, V> with(K key, V value) {
put(key, value);
return this;
}
public static <K, V> FluentHashMap<K, V> map(K key, V value) {
return new FluentHashMap<K, V>().with(key, value);
}
}
তারপর
import static FluentHashMap.map;
HashMap<String, Integer> m = map("a", 1).with("b", 2);
Https://gist.github.com/culmat/a3bcc646fa4401641ac6eb01f3719065 দেখুন
একটি সাধারণ মানচিত্র নির্মাতা লিখতে তুচ্ছ:
public class Maps {
public static <Q,W> MapWrapper<Q,W> map(Q q, W w) {
return new MapWrapper<Q, W>(q, w);
}
public static final class MapWrapper<Q,W> {
private final HashMap<Q,W> map;
public MapWrapper(Q q, W w) {
map = new HashMap<Q, W>();
map.put(q, w);
}
public MapWrapper<Q,W> map(Q q, W w) {
map.put(q, w);
return this;
}
public Map<Q,W> getMap() {
return map;
}
}
public static void main(String[] args) {
Map<String, Integer> map = Maps.map("one", 1).map("two", 2).map("three", 3).getMap();
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
}
}
তুমি ব্যবহার করতে পার:
HashMap<String,Integer> m = Maps.newHashMap(
ImmutableMap.of("a",1,"b",2)
);
এটি উত্কৃষ্ট এবং পাঠযোগ্য নয়, তবে কাজটি করে।
Map<String, Integer> map = ImmutableMap.of("a", 1, "b", 2);
, উত্তম?
HashMap
পরিবর্তনীয়; কোনও বিল্ডারের দরকার নেই।
Map<String, Integer> map = Maps.newHashMap();
map.put("a", 1);
map.put("b", 2);
ImmutableSet
। আপনি যদি সত্যিই এটি পরিবর্তনীয় হতে চান তবে আপনি এটি স্ট্র্যাটিক ক্ষেত্রের ক্ষেত্রে কনস্ট্রাক্টর বা একটি উদাহরণ ইনিশিয়াল ব্লক বা একটি স্ট্যাটিক ইনিশিয়ালাইজার ব্লকে এটি সূচনা করতে পারেন।
ImmutableMap
স্পষ্টত সেখানে বলা উচিত ছিল ।
{{init();}}
( কনস্ট্রাক্টারে নয়, যেহেতু অন্য নির্মাণকারীরা এটি ভুলে যেতে পারে)। এবং এটি দুর্দান্ত যে এটি ধরণের পারমাণবিক ক্রিয়া। মানচিত্রটি যদি অস্থির হয় তবে কোনও বিল্ডারের সাথে এটি অন্তর্নিহিত করা নিশ্চিত করুন এটি সর্বদা হয় null
বা চূড়ান্ত অবস্থায় থাকে, কখনও অর্ধেক ভরা হয় না।
আপনি গ্রহগ্রহের সংগ্রহগুলিতে সাবলীল এপিআই ব্যবহার করতে পারেন :
Map<String, Integer> map = Maps.mutable.<String, Integer>empty()
.withKeyValue("a", 1)
.withKeyValue("b", 2);
Assert.assertEquals(Maps.mutable.with("a", 1, "b", 2), map);
এখানে একটি ব্লগ আরও বিশদ এবং উদাহরণ সহ ।
দ্রষ্টব্য: আমি গ্রহগ্রাহ সংগ্রহের প্রতিশ্রুতিবদ্ধ।
কিছুক্ষণ আগে আমারও একই রকম প্রয়োজন ছিল। এটি পেয়ারার সাথে কিছুই করার নয় তবে আপনি Map
সাবলীল নির্মাতা ব্যবহার করে পরিষ্কারভাবে নির্মাণ করতে সক্ষম হবার জন্য এই জাতীয় কিছু করতে পারেন ।
মানচিত্র প্রসারিত একটি বেস ক্লাস তৈরি করুন।
public class FluentHashMap<K, V> extends LinkedHashMap<K, V> {
private static final long serialVersionUID = 4857340227048063855L;
public FluentHashMap() {}
public FluentHashMap<K, V> delete(Object key) {
this.remove(key);
return this;
}
}
তারপরে আপনার প্রয়োজন অনুসারে এমন পদ্ধতিতে সাবলীল নির্মাতা তৈরি করুন:
public class ValueMap extends FluentHashMap<String, Object> {
private static final long serialVersionUID = 1L;
public ValueMap() {}
public ValueMap withValue(String key, String val) {
super.put(key, val);
return this;
}
... Add withXYZ to suit...
}
তারপরে আপনি এটিকে এভাবে প্রয়োগ করতে পারেন:
ValueMap map = new ValueMap()
.withValue("key 1", "value 1")
.withValue("key 2", "value 2")
.withValue("key 3", "value 3")
এটি এমন কিছু যা আমি সবসময় চেয়েছিলাম, বিশেষত টেস্ট ফিক্সচার সেটআপ করার সময়। অবশেষে, আমি সিদ্ধান্ত নিয়েছি যে আমার নিজস্ব একটি সহজ সাবলীল নির্মাতারা যেকোন মানচিত্রের বাস্তবায়ন তৈরি করতে পারে - https://gist.github.com/samshu/b471f5a2925fa9d9b718795d8bbdfe42#file-mapbuilder-java
/**
* @param mapClass Any {@link Map} implementation type. e.g., HashMap.class
*/
public static <K, V> MapBuilder<K, V> builder(@SuppressWarnings("rawtypes") Class<? extends Map> mapClass)
throws InstantiationException,
IllegalAccessException {
return new MapBuilder<K, V>(mapClass);
}
public MapBuilder<K, V> put(K key, V value) {
map.put(key, value);
return this;
}
public Map<K, V> build() {
return map;
}
আমি এখানে একটি লিখেছি
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;
public class MapBuilder<K, V> {
private final Map<K, V> map;
/**
* Create a HashMap builder
*/
public MapBuilder() {
map = new HashMap<>();
}
/**
* Create a HashMap builder
* @param initialCapacity
*/
public MapBuilder(int initialCapacity) {
map = new HashMap<>(initialCapacity);
}
/**
* Create a Map builder
* @param mapFactory
*/
public MapBuilder(Supplier<Map<K, V>> mapFactory) {
map = mapFactory.get();
}
public MapBuilder<K, V> put(K key, V value) {
map.put(key, value);
return this;
}
public Map<K, V> build() {
return map;
}
/**
* Returns an unmodifiable Map. Strictly speaking, the Map is not immutable because any code with a reference to
* the builder could mutate it.
*
* @return
*/
public Map<K, V> buildUnmodifiable() {
return Collections.unmodifiableMap(map);
}
}
আপনি এটি এর মতো ব্যবহার করুন:
Map<String, Object> map = new MapBuilder<String, Object>(LinkedHashMap::new)
.put("event_type", newEvent.getType())
.put("app_package_name", newEvent.getPackageName())
.put("activity", newEvent.getActivity())
.build();
জাভা 8 ব্যবহার করে:
এটি জাভা -9 এর একটি পদ্ধতির Map.ofEntries(Map.entry(k1,v1), Map.entry(k2,v2), ...)
public class MapUtil {
import static java.util.stream.Collectors.toMap;
import java.util.AbstractMap.SimpleEntry;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Stream;
private MapUtil() {}
@SafeVarargs
public static Map<String, Object> ofEntries(SimpleEntry<String, Object>... values) {
return Stream.of(values).collect(toMap(Entry::getKey, Entry::getValue));
}
public static SimpleEntry<String, Object> entry(String key, Object value) {
return new SimpleEntry<String, Object>(key, value);
}
}
ব্যবহারবিধি:
import static your.package.name.MapUtil.*;
import java.util.Map;
Map<String, Object> map = ofEntries(
entry("id", 1),
entry("description", "xyz"),
entry("value", 1.05),
entry("enable", true)
);
ইনসকোর-জাভা হ্যাশম্যাপ তৈরি করতে পারে।
Map<String, Object> value = U.objectBuilder()
.add("firstName", "John")
.add("lastName", "Smith")
.add("age", 25)
.add("address", U.arrayBuilder()
.add(U.objectBuilder()
.add("streetAddress", "21 2nd Street")
.add("city", "New York")
.add("state", "NY")
.add("postalCode", "10021")))
.add("phoneNumber", U.arrayBuilder()
.add(U.objectBuilder()
.add("type", "home")
.add("number", "212 555-1234"))
.add(U.objectBuilder()
.add("type", "fax")
.add("number", "646 555-4567")))
.build();
// {firstName=John, lastName=Smith, age=25, address=[{streetAddress=21 2nd Street,
// city=New York, state=NY, postalCode=10021}], phoneNumber=[{type=home, number=212 555-1234},
// {type=fax, number=646 555-4567}]}