তালিকা <মানচিত্র <স্ট্রিং, স্ট্রিং >> বনাম তালিকা <? মানচিত্র <স্ট্রিং, স্ট্রিং >> প্রসারিত


129

এর মধ্যে কোনও পার্থক্য আছে কি?

List<Map<String, String>>

এবং

List<? extends Map<String, String>>

?

কোনও পার্থক্য না থাকলে ব্যবহার করে ? extendsকী লাভ ?


2
আমি জাভা পছন্দ করি তবে এটি এমন একটি বিষয় যা খুব ভাল নয় ...
মাইট মিত্রেস্কি

4
আমি অনুভব করি যে আমরা যদি এটি "প্রসারিত কিছু ..." এর মতো পড়ি তবে এটি স্পষ্ট হয়ে যায়।
আবর্জনা

অবিশ্বাস্য, প্রায় 3 দিনের মধ্যে 12 কে ভিউ? !!
ইঞ্জি ফুয়েড

5
এটি হ্যাকার নিউজের প্রথম পৃষ্ঠায় পৌঁছেছে। অভিনন্দন.
r3st0r3

1
@ ইঞ্জিঃ ফাউন্ড এটি এখানে। প্রথম পৃষ্ঠায় আর নেই, তবে গতকাল সেখানে ছিল। নিউজ.আইকোবিনেটর.नेट / সাইটম?id=3751901 (গতকাল মধ্য রোববার ভারতে এখানে।)
r3st0r3

উত্তর:


180

পার্থক্যটি হ'ল, উদাহরণস্বরূপ, এ

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গুলি।


6
এখনও, HashMapএকটি হল Mapপলিমরফিজম কারণে।
ইঞ্জিঃ ফুয়াদ

46
ঠিক আছে, কিন্তু একটি 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বৈধ, যদি আমি সেগুলি সঠিকভাবে পড়ছি।
ট্রুথিলিটি

24

আপনি List<NavigableMap<String,String>>প্রথমটির মতো প্রকারের সাথে এক্সপ্রেশন নির্ধারণ করতে পারবেন না ।

(আপনি যদি জানতে চান তবে কেন আপনি এসও-তে আরও একটি জিলিয়ন প্রশ্ন দেখার List<String>জন্য নির্ধারণ করতে পারবেন না ))List<Object>


1
এটা আরও ব্যাখ্যা করতে পারেন? আমি বুঝতে পারি না বা ভাল অনুশীলনের জন্য কোনও লিঙ্ক?
সমীর মঙ্গরোলিয়া

3
@ সমীর কি ব্যাখ্যা করবেন? List<String>একটি উপপ্রকার নয় List<Object>? - দেখুন, উদাহরণস্বরূপ, stackoverflow.com/questions/3246137/...
tackline - টম Hawtin

2
এর সাথে বা বাইরে পার্থক্য কী তা ব্যাখ্যা করে না ? extends। তেমনি এটি সুপার / সাব টাইপস বা কো / বিপরীতে (যদি থাকে তবে) এর সাথে সম্পর্কও ব্যাখ্যা করে না।
আবেল

16

অন্যান্য উত্তরে আমি যা অনুপস্থিত তা হ'ল এটি কীভাবে সাধারণভাবে সাধারণভাবে এবং জাভার সাথে সহ-বিপরীততা এবং সাব-এবং সুপারটাইপস (অর্থাৎ পলিমারফিজম) এর সাথে সম্পর্কিত 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

Contravariance

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

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>());

"তাই এর সাথে ... তবে কিছুই নেই" সংকলন করবে না।
NobleUplift

@ নোবেলপ্লিট: আপনি যদি ত্রুটি বার্তাটি পান না তবে আপনাকে সাহায্য করা শক্ত। আপনার উত্তর পেতে সাফল্যের আরও বড় সম্ভাবনা পাওয়ার জন্য এসও-তে একটি নতুন প্রশ্ন জিজ্ঞাসা করার জন্য বিকল্প হিসাবেও বিবেচনা করুন। উপরের কোডটি কেবল স্নিপেটস, এটি নির্ভর করে আপনি এটি আপনার দৃশ্যে প্রয়োগ করেছেন।
আবেল

আমার কাছে নতুন প্রশ্ন নেই, আমার উন্নতি হয়েছে। 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 boundsList<Map<String, String>> mapList = new ArrayList<Map<String, String>>(); mapList.add(new TreeMap<String, String>());পুরোপুরি কাজ করে। শেষ উদাহরণটি অবশ্যই স্পষ্টভাবে সঠিক।
NobleUplift

@ নোবেলপ্লিট: দুঃখিত, দীর্ঘ সময় ভ্রমণ, ফিরে আসার পরে ঠিক হয়ে যাবে, এবং সুস্পষ্ট ত্রুটি চিহ্নিত করার জন্য ধন্যবাদ! :)
আবেল

কোনও সমস্যা নেই, আমি ঠিক করেছি এটি ঠিক হয়ে যাবে। আপনি যদি এগুলি অনুমোদিত করতে চান তবে আমি সম্পাদনাগুলি করেছি made
NobleUplift

4

আজ, আমি এই বৈশিষ্ট্যটি ব্যবহার করেছি, তাই এখানে আমার খুব তাজা বাস্তব জীবনের উদাহরণ। (আমি শ্রেণি এবং পদ্ধতির নামগুলি জেনেরিকগুলিতে পরিবর্তন করেছি যাতে তারা আসল বিন্দু থেকে বিভ্রান্ত হয় না))

আমি একটি পদ্ধতি যে একটি গ্রহণ করতে সেসব আছে 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, সুতরাং প্রকারের ব্যবস্থাটি বিপদগ্রস্থ না করে সাবক্লাস সহ এটি ব্যবহার করা সম্ভব হয়।


0

যেমনটি আপনি উল্লেখ করেছেন, তালিকা নির্ধারণের নীচে দুটি সংস্করণ থাকতে পারে:

  1. List<? extends Map<String, String>>
  2. List<?>

2 খুব খোলা। এটি যে কোনও বস্তুর ধরণ ধরে রাখতে পারে। আপনি প্রদত্ত ধরণের মানচিত্র রাখতে চাইলে এটি কার্যকর নাও হতে পারে। যদি কেউ দুর্ঘটনাক্রমে কোনও ভিন্ন ধরণের মানচিত্র রাখে, উদাহরণস্বরূপ,Map<String, int> ,। আপনার ভোক্তা পদ্ধতি ভঙ্গ হতে পারে।

Listকোনও নির্দিষ্ট ধরণের অবজেক্টগুলি যাতে ধরে রাখতে পারে তা নিশ্চিত করার জন্য , জাভা জেনেরিকগুলি চালু করা হয়েছে ? extends। সুতরাং # 1-এ, টাইপ Listথেকে প্রাপ্ত কোনও বস্তু ধরে রাখতে পারে Map<String, String>। অন্য কোনও ধরণের ডেটা যুক্ত করা ব্যতিক্রম হতে পারে।

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