এর মধ্যে কোনও পার্থক্য আছে কি?
List<Map<String, String>>
এবং
List<? extends Map<String, String>>
?
কোনও পার্থক্য না থাকলে ব্যবহার করে ? extendsকী লাভ ?
এর মধ্যে কোনও পার্থক্য আছে কি?
List<Map<String, String>>
এবং
List<? extends Map<String, String>>
?
কোনও পার্থক্য না থাকলে ব্যবহার করে ? extendsকী লাভ ?
উত্তর:
পার্থক্যটি হ'ল, উদাহরণস্বরূপ, এ
List<HashMap<String,String>>
ইহা একটি
List<? extends Map<String,String>>
কিন্তু না
List<Map<String,String>>
তাই:
void withWilds( List<? extends Map<String,String>> foo ){}
void noWilds( List<Map<String,String>> foo ){}
void main( String[] args ){
List<HashMap<String,String>> myMap;
withWilds( myMap ); // Works
noWilds( myMap ); // Compiler error
}
আপনি একটি মনে হবে ListএরHashMap করা একটি হওয়া উচিত Listএর Mapগুলি, কিন্তু একটি ভাল কারণ কেন এটা নয়:
ধরুন আপনি করতে পারেন:
List<HashMap<String,String>> hashMaps = new ArrayList<HashMap<String,String>>();
List<Map<String,String>> maps = hashMaps; // Won't compile,
// but imagine that it could
Map<String,String> aMap = Collections.singletonMap("foo","bar"); // Not a HashMap
maps.add( aMap ); // Perfectly legal (adding a Map to a List of Maps)
// But maps and hashMaps are the same object, so this should be the same as
hashMaps.add( aMap ); // Should be illegal (aMap is not a HashMap)
তাই এই হল কেন একজন Listএর HashMapকরা একটি করা উচিত হবে না Listএর Mapগুলি।
HashMapএকটি হল Mapপলিমরফিজম কারণে।
Listএর HashMapকরা একটি নয় Listএর Mapগুলি।
List<Map<String,String>> maps = hashMaps; এবং HashMap<String,String> aMap = new HashMap<String, String>();তবুও আপনি বৈধ maps.add(aMap);থাকাকালীন hashMaps.add(aMap);এটি বেআইনী দেখতে পাবেন । উদ্দেশ্যটি ভুল ধরণের সংযোজন রোধ করা, তবে এটি সঠিক ধরণের সংযোজন করতে দেয় না (সংকলক সংকলনের সময় "সঠিক" প্রকারটি নির্ধারণ করতে পারে না)
HashMap একটি তালিকাতে একটি যুক্ত করতে পারেন তবে আপনার দুটি উদাহরণই Mapবৈধ, যদি আমি সেগুলি সঠিকভাবে পড়ছি।
আপনি List<NavigableMap<String,String>>প্রথমটির মতো প্রকারের সাথে এক্সপ্রেশন নির্ধারণ করতে পারবেন না ।
(আপনি যদি জানতে চান তবে কেন আপনি এসও-তে আরও একটি জিলিয়ন প্রশ্ন দেখার List<String>জন্য নির্ধারণ করতে পারবেন না ))List<Object>
List<String>একটি উপপ্রকার নয় List<Object>? - দেখুন, উদাহরণস্বরূপ, stackoverflow.com/questions/3246137/...
? extends। তেমনি এটি সুপার / সাব টাইপস বা কো / বিপরীতে (যদি থাকে তবে) এর সাথে সম্পর্কও ব্যাখ্যা করে না।
অন্যান্য উত্তরে আমি যা অনুপস্থিত তা হ'ল এটি কীভাবে সাধারণভাবে সাধারণভাবে এবং জাভার সাথে সহ-বিপরীততা এবং সাব-এবং সুপারটাইপস (অর্থাৎ পলিমারফিজম) এর সাথে সম্পর্কিত to এটি ওপি দ্বারা ভালভাবে বুঝতে পারে, তবে কেবল ক্ষেত্রে, এটি এখানে যায়:
আপনি যদি একটি বর্গ থাকে তাহলে Automobile, তারপর Carএবং Truckতাদের উপশাখাকে হয়। যে কোনও গাড়িকে অটোমোবাইল প্রকারের একটি পরিবর্তনশীলকে বরাদ্দ করা যেতে পারে, এটি ওওতে সুপরিচিত এবং এটি পলিমারফিজম নামে পরিচিত। কোভারিয়েন্স জেনারিকস বা প্রতিনিধিদের সাথে দৃশ্যে এই একই নীতিটি ব্যবহার বোঝায়। জাভাতে কোন প্রতিনিধি নেই (এখনও), সুতরাং শব্দটি কেবল জেনেরিকের ক্ষেত্রে প্রযোজ্য।
আপনারা চিন্তাভাবনা না করেই কী কাজ করার প্রত্যাশা করবেন তা আমি প্রচলিত মানটিকে বহুগুণ হিসাবে বিবেচনা করি, কারণ:
List<Car> cars;
List<Automobile> automobiles = cars;
// You'd expect this to work because Car is-a Automobile, but
// throws inconvertible types compile error.
ত্রুটির কারণ অবশ্য সঠিক: List<Car> এটি উত্তরাধিকার সূত্রে প্রাপ্ত List<Automobile>হয় না এবং সুতরাং একে অপরের কাছে বরাদ্দ করা যায় না। কেবল জেনেরিক ধরণের পরামিতিগুলির উত্তরাধিকারসূত্রে সম্পর্ক রয়েছে। কেউ ভাবতে পারেন যে জাভা সংকলক কেবল সেখানে আপনার পরিস্থিতি সঠিকভাবে বুঝতে পারে না। তবে আপনি সংকলককে তাকে একটি ইঙ্গিত দিয়ে সহায়তা করতে পারেন:
List<Car> cars;
List<? extends Automobile> automobiles = cars; // no error
সহ-বৈকল্পিকের বিপরীতটি হল স্ববিরোধিতা। যেখানে অবিশ্বাস্যতায় প্যারামিটারের ধরণেরগুলির অবশ্যই একটি সাব-টাইপ সম্পর্ক থাকতে পারে, বিপরীতে তাদের অবশ্যই একটি সুপারটাইপ সম্পর্ক থাকতে পারে। এটিকে উত্তরাধিকারের উপরের দিকে আবদ্ধ হিসাবে বিবেচনা করা যেতে পারে: যে কোনও সুপারটাইপকে অনুমতি দেওয়া হয় এবং নির্দিষ্ট ধরণের সহ:
class AutoColorComparer implements Comparator<Automobile>
public int compare(Automobile a, Automobile b) {
// Return comparison of colors
}
এটি কালেকশনস.সোর্ট সহ ব্যবহার করা যেতে পারে :
public static <T> void sort(List<T> list, Comparator<? super T> c)
// Which you can call like this, without errors:
List<Car> cars = getListFromSomewhere();
Collections.sort(cars, new AutoColorComparer());
এমনকি আপনি এটি এমন তুলনাকারীর সাথেও কল করতে পারেন যা বস্তুর তুলনা করে এবং কোনও প্রকারের সাথে এটি ব্যবহার করতে পারে।
কিছুটা ওটি সম্ভবত, আপনি জিজ্ঞাসা করেননি, তবে এটি আপনার প্রশ্নের উত্তর বুঝতে সহায়তা করে। সাধারণভাবে, যখন আপনি পেতে কিছু, ব্যবহার সহভেদাংক এবং আপনি করা কিছু, ব্যবহার contravariance। স্ট্যাক ওভারফ্লো প্রশ্নের উত্তরে এটি সর্বোত্তমভাবে ব্যাখ্যা করা হয়েছে যে জাভা জেনেরিকগুলিতে কীভাবে বৈপরীত্য ব্যবহার করা হবে? ।
List<? extends Map<String, String>>আপনি ব্যবহার করুন extends, সুতরাং সমবায় জন্য নিয়ম প্রযোজ্য। এখানে আপনার কাছে মানচিত্রের একটি তালিকা রয়েছে এবং আপনি তালিকায় সংরক্ষণ করেন এমন প্রতিটি আইটেম অবশ্যই Map<string, string>এটির থেকে নেওয়া উচিত। বিবৃতিটি List<Map<String, String>>প্রাপ্ত হতে পারে না Map, তবে এটি অবশ্যই একটি Map ।
সুতরাং, নিম্নলিখিতগুলি কাজ করবে, কারণ TreeMapউত্তরাধিকার সূত্রে Map:
List<Map<String, String>> mapList = new ArrayList<Map<String, String>>();
mapList.add(new TreeMap<String, String>());
তবে এটি হবে না:
List<? extends Map<String, String>> mapList = new ArrayList<? extends Map<String, String>>();
mapList.add(new TreeMap<String, String>());
এবং এটি কোনওভাবেই কাজ করবে না, কারণ এটি আধ্যাত্মিক সীমাবদ্ধতা পূরণ করে না:
List<? extends Map<String, String>> mapList = new ArrayList<? extends Map<String, String>>();
mapList.add(new ArrayList<String>()); // This is NOT allowed, List does not implement Map
এটি সম্ভবত সুস্পষ্ট, তবে আপনি ইতিমধ্যে লক্ষ করেছেন যে extendsকীওয়ার্ডটি ব্যবহার করা কেবলমাত্র সেই প্যারামিটারের ক্ষেত্রেই প্রযোজ্য, বাকীগুলিতে নয়। অর্থাৎ, নিম্নলিখিতগুলি সংকলন করবে না:
List<? extends Map<String, String>> mapList = new List<? extends Map<String, String>>();
mapList.add(new TreeMap<String, Element>()) // This is NOT allowed
মনে করুন আপনি স্ট্রিং হিসাবে একটি কী সহ মানচিত্রে যে কোনও প্রকারের অনুমতি দিতে চান, আপনি extendপ্রতিটি ধরণের পরামিতি ব্যবহার করতে পারেন can উদাহরণস্বরূপ, ধরুন আপনি এক্সএমএল প্রসেস করেন এবং আপনি মানচিত্রে অ্যাট্রিকনড, এলিমেন্ট ইত্যাদি সঞ্চয় করতে চান তবে আপনি এর মতো কিছু করতে পারেন:
List<? extends Map<String, ? extends Node>> listOfMapsOfNodes = new...;
// Now you can do:
listOfMapsOfNodes.add(new TreeMap<Sting, Element>());
listOfMapsOfNodes.add(new TreeMap<Sting, CDATASection>());
List<? extends Map<String, String>> mapList = new ArrayList<? extends Map<String, String>>(); mapList.add(new TreeMap<String, String>());ফলাফল found: ? extends java.util.Map<java.lang.String,java.lang.String> required: class or interface without bounds। List<Map<String, String>> mapList = new ArrayList<Map<String, String>>(); mapList.add(new TreeMap<String, String>());পুরোপুরি কাজ করে। শেষ উদাহরণটি অবশ্যই স্পষ্টভাবে সঠিক।
আজ, আমি এই বৈশিষ্ট্যটি ব্যবহার করেছি, তাই এখানে আমার খুব তাজা বাস্তব জীবনের উদাহরণ। (আমি শ্রেণি এবং পদ্ধতির নামগুলি জেনেরিকগুলিতে পরিবর্তন করেছি যাতে তারা আসল বিন্দু থেকে বিভ্রান্ত হয় না))
আমি একটি পদ্ধতি যে একটি গ্রহণ করতে সেসব আছে Setএর Aযে বস্তু আমি প্রকৃতপক্ষে এই স্বাক্ষর সহ লিখেছিলেন:
void myMethod(Set<A> set)
তবে এটি আসলে এটির Setউপক্লাসগুলির সাথে কল করতে চায় A। তবে এটি অনুমোদিত নয়! (এর কারণ হ'ল, myMethodবস্তুগুলি setটাইপের মতো যুক্ত করতে পারে তবে Aএটি যে উপ- টাইপের নয়set কলারের সাইটে রয়েছে বলে ঘোষণা করা হয়েছে So তাই এটি সম্ভব হলে টাইপ সিস্টেমটি ভেঙে দিতে পারে))
এখন এখানে উদ্ধার করার জন্য জেনেরিকস আসুন, কারণ এটি যদি উদ্দেশ্য পরিবর্তে আমি এই পদ্ধতির স্বাক্ষরটি ব্যবহার করি তবে তা কাজ করে:
<T extends A> void myMethod(Set<T> set)
বা সংক্ষিপ্ততর, যদি আপনাকে পদ্ধতির শরীরে প্রকৃত ধরণের ব্যবহারের প্রয়োজন না হয়:
void myMethod(Set<? extends A> set)
এই পথে, set ধরণের, প্রকৃত উপ-টাইপের অবজেক্টগুলির সংকলনে পরিণত হয় A, সুতরাং প্রকারের ব্যবস্থাটি বিপদগ্রস্থ না করে সাবক্লাস সহ এটি ব্যবহার করা সম্ভব হয়।
যেমনটি আপনি উল্লেখ করেছেন, তালিকা নির্ধারণের নীচে দুটি সংস্করণ থাকতে পারে:
List<? extends Map<String, String>>List<?>2 খুব খোলা। এটি যে কোনও বস্তুর ধরণ ধরে রাখতে পারে। আপনি প্রদত্ত ধরণের মানচিত্র রাখতে চাইলে এটি কার্যকর নাও হতে পারে। যদি কেউ দুর্ঘটনাক্রমে কোনও ভিন্ন ধরণের মানচিত্র রাখে, উদাহরণস্বরূপ,Map<String, int> ,। আপনার ভোক্তা পদ্ধতি ভঙ্গ হতে পারে।
Listকোনও নির্দিষ্ট ধরণের অবজেক্টগুলি যাতে ধরে রাখতে পারে তা নিশ্চিত করার জন্য , জাভা জেনেরিকগুলি চালু করা হয়েছে ? extends। সুতরাং # 1-এ, টাইপ Listথেকে প্রাপ্ত কোনও বস্তু ধরে রাখতে পারে Map<String, String>। অন্য কোনও ধরণের ডেটা যুক্ত করা ব্যতিক্রম হতে পারে।