পার্থক্য কি ? এবং জাভা জেনেরিকস মধ্যে অবজেক্ট?


137

জাভা জেনেরিকস সঠিকভাবে ব্যবহার করতে কিছু কোড সাফ করতে আমাকে সাহায্য করতে আমি Elpipse ব্যবহার করছি। বেশিরভাগ সময় এটি অনুমানের ধরণের একটি দুর্দান্ত কাজ করে তবে এমন কিছু ঘটনা রয়েছে যেখানে অনুমিত টাইপটি যতটা সম্ভব জেনেরিক হতে হবে: অবজেক্ট। তবে মনে হয় Eclipse আমাকে এক ধরণের অবজেক্ট এবং '?' এর ধরণের মধ্যে বেছে নেওয়ার একটি বিকল্প দিচ্ছে।

সুতরাং এর মধ্যে পার্থক্য কি:

HashMap<String, ?> hash1;

এবং

HashMap<String, Object> hash2;

4
ওয়াইল্ডকার্ডসে সরকারী টিউটোরিয়াল দেখুন । এটি এটিকে ভালভাবে ব্যাখ্যা করে এবং কেবলমাত্র অবজেক্ট ব্যবহার করে কেন এটি প্রয়োজনীয় তা একটি উদাহরণ দেয়।
বেন এস

উত্তর:


148

HashMap<String, String>ম্যাচের উদাহরণ Map<String, ?>কিন্তু না Map<String, Object>। বলুন যে আপনি এমন একটি পদ্ধতি লিখতে চান যা মানচিত্র থেকে অন্য যে Stringকোনও ক্ষেত্রে গ্রহণ করে : আপনি যদি লিখতে চান would

public void foobar(Map<String, Object> ms) {
    ...
}

আপনি যদি একটি সাপ্লাই করতে পারছে না HashMap<String, String>। যদি লিখি

public void foobar(Map<String, ?> ms) {
    ...
}

এটা কাজ করে!

জাভা এর জেনেরিকের মাঝে মাঝে একটি জিনিস ভুল বোঝা যায় List<String>সেটি একটি সাব টাইপ নয় List<Object>। (কিন্তু String[]বস্তুত উপপ্রকার হয় Object[], যে কারণে জেনেরিক্স এবং অ্যারে ভাল মিশ্রিত না এক। (জাভা অ্যারে covariant হয়, জেনেরিক্স নয়, তারা পরিবর্তিত ))।

নমুনা: আপনি যদি এমন কোনও পদ্ধতি লিখতে চান যা Listএর InputStreamগুলি এবং উপ টাইপগুলি গ্রহণ করে InputStream, আপনি লিখতে চান

public void foobar(List<? extends InputStream> ms) {
    ...
}

উপায় দ্বারা: আপনি যখন জাভাতে এত সাধারণ জিনিসগুলি বুঝতে চাইবেন তখন জোশুয়া ব্লচের কার্যকর জাভা একটি দুর্দান্ত উত্স resource (উপরের আপনার প্রশ্নটিও বইটিতে খুব ভালভাবে কভার করা হয়েছে।)


1
আমার সমস্ত নিয়ামক কার্যকারিতার জন্য নিয়ামক স্তরে রেসপন্সেন্সটি <?> ব্যবহার করার এই সঠিক উপায়টি কি?
ইরাকলি

ত্রুটিহীন উত্তর জোহানেস!
গৌরব

36

এই সমস্যাটি সম্পর্কে ভাবার আর একটি উপায়

HashMap<String, ?> hash1;

সমতুল্য

HashMap<String, ? extends Object> hash1;

জাভা জেনারিকস এবং সংগ্রহগুলি বিভাগের (২.৪) বিভাগের "গেট অ্যান্ড পুট প্রিন্সিপাল" এর সাথে এই জ্ঞানটি দ্বিগুণ করুন :

গেট অ্যান্ড পুট প্রিন্সিপাল: যখন আপনি কেবল কোনও কাঠামোর বাইরে মান পাবেন তখন একটি প্রসারিত ওয়াইল্ডকার্ড ব্যবহার করুন, যখন আপনি কেবল কাঠামোর মধ্যে মান রাখবেন তখন সুপার ওয়াইল্ডকার্ড ব্যবহার করুন এবং যখন আপনি উভয়ই পাবেন এবং রাখবেন তখন ওয়াইল্ডকার্ড ব্যবহার করবেন না।

এবং ওয়াইল্ড কার্ড আরও বুদ্ধিমান হতে শুরু করবে, আশা করি fully


1
যদি "?" আপনাকে বিভ্রান্ত করে, "? অবজেক্ট অবজেক্ট" সম্ভবত আপনাকে আরও বিভ্রান্ত করবে। হতে পারে.
মাইকেল মায়ার্স

এই কঠিন বিষয় সম্পর্কে কারও পক্ষে যুক্তি দেখানোর জন্য "চিন্তাভাবনা সরঞ্জাম" সরবরাহ করার চেষ্টা করা হচ্ছে। ওয়াইল্ডকার্ডগুলি বাড়ানোর বিষয়ে অতিরিক্ত তথ্য সরবরাহ করা হয়েছে।
জুলিয়েন চস্তং

2
অতিরিক্ত তথ্যের জন্য ধন্যবাদ। আমি এখনও এটি হজম করছি। :)
skiphoppy

HashMap<String, ? extends Object> সুতরাং এটি কেবল nullহ্যাশম্যাপে যুক্ত হওয়া রোধ করে?
মল্লাউদ্দিন

12

এটি বুঝতে সহজ হয় যদি আপনি মনে করেন যে Collection<Object>এটি কেবল একটি জেনেরিক সংগ্রহ যা টাইপের অবজেক্টগুলিকে ধারণ করে Objectতবে Collection<?>এটি সমস্ত ধরণের সংগ্রহের একটি সুপার টাইপ।


1
একটি বক্তব্য রাখতে হবে যে এটি ঠিক সহজ নয় ;-), তবে এটি সঠিক।
শন রিলি

6

উপরোক্ত উত্তরগুলি বেশিরভাগ ক্ষেত্রে কভার করে তবে একটি জিনিস মিস করে:

"?" শ্রেণি শ্রেণিবিন্যাসের "অবজেক্ট" সহ অন্তর্ভুক্ত। আপনি বলতে পারেন স্ট্রিং একটি ধরণের অবজেক্ট এবং অবজেক্ট এক প্রকার? সবকিছু মিলছে না ऑজেক্টের সাথে, তবে সব মিলছে?

int test1(List<?> l) {
  return l.size();
}

int test2(List<Object> l) {
  return l.size();
}

List<?> l1 = Lists.newArrayList();
List<Object> l2 = Lists.newArrayList();
test1(l1);  // compiles because any list will work
test1(l2);  // compiles because any list will work
test2(l1);  // fails because a ? might not be an Object
test2(l2);  // compiled because Object matches Object

4

আপনি নিরাপদে কোনও কিছুই putোকাতে পারবেন না Map<String, ?>, কারণ মানগুলি কী ধরণের হতে হবে তা আপনি জানেন না।

আপনি যেকোন বস্তুকে একটিতে রাখতে পারেন Map<String, Object>, কারণ মানটি একটি হিসাবে পরিচিত Object


"আপনি মানচিত্র <স্ট্রিং,?> এ নিরাপদে কিছু রাখতে পারবেন না" মিথ্যা। আপনি পারেন, এটি এর উদ্দেশ্য।
বেন এস

3
বেন ভুল, আপনি <>> টাইপের সংকলনে একমাত্র মানটি বাতিল করতে পারেন তবে আপনি <ওজেক্ট> টাইপের সংকলনে যে কোনও কিছু রাখতে পারেন।
স্ক।

2
আমি আমার উত্তরে যে লিঙ্কটি দিয়েছি: "যেহেতু সি উপাদান উপাদানটি কী তা আমরা জানি না, তাই আমরা এতে বস্তুগুলি যুক্ত করতে পারি না।" ভুল তথ্যের জন্য আমি ক্ষমা চেয়ে নিচ্ছি।
বেন এস

1
সবচেয়ে বড় সমস্যা হ'ল আমি বুঝতে পারি না যে এটি কীভাবে সম্ভব যে আপনি হ্যাশম্যাপ <স্ট্রিং,?> তে কোনও কিছুই যুক্ত করতে পারবেন না, যদি আমরা বিবেচনা করি যে আদিমগুলি বাদে সমস্ত কিছুই বস্তু। না এটা আদিমদের জন্য?
অ্যাভালন

1
@ ও্যালোন অন্য কোথাও, সেই মানচিত্রের সীমাবদ্ধ রয়েছে to উদাহরণস্বরূপ, এটি একটি হতে পারে Map<String,Integer>Integerমান হিসাবে মান হিসাবে কেবলমাত্র বস্তু সঞ্চিত করা উচিত। কিন্তু যেহেতু আপনি মান (এটা ধরণ জানি না ?), আপনি যদি এটি নিরাপদ কল জানি না put(key, "x"), put(key, 0), বা অন্য কিছু।
ইরিকসন

2

ঘোষণা hash1হিসেবে HashMap<String, ?>dictates যে পরিবর্তনশীল hash1কোনো ধরে রাখতে পারেন HashMapকী আছে Stringএবং মান কোন প্রকার।

HashMap<String, ?> map;
map = new HashMap<String, Integer>();
map = new HashMap<String, Object>();
map = new HashMap<String, String>();

উপরের সমস্তটি বৈধ, কারণ ভেরিয়েবল map এই হ্যাশ মানচিত্রগুলির যে কোনও সংরক্ষণ করতে পারে। এই ভেরিয়েবলটি হ্যাশম্যাপটি ধারণ করে এর মান ধরণের কী তা বিবেচনা করে না।

একটি ওয়াইল্ড কার্ড রয়ে নেই না , কিন্তু, যদি আপনি আপনার মানচিত্রে মধ্যে বস্তুর কোনো ধরনের করা যাক। প্রকৃতপক্ষে, উপরের হ্যাশ ম্যাপের সাহায্যে, আপনি mapভেরিয়েবলটি ব্যবহার করে এর মধ্যে কিছুই রাখতে পারবেন না :

map.put("A", new Integer(0));
map.put("B", new Object());
map.put("C", "Some String");

উপরের সমস্ত পদ্ধতি কলগুলির একটি সংকলন-সময় ত্রুটির ফলাফল ঘটবে কারণ জাভা জানে না যে ভিতরে থাকা হ্যাশম্যাপের মান ধরণটি mapকী।

আপনি এখনও হ্যাশ মানচিত্র থেকে একটি মান পেতে পারেন। যদিও আপনি "মানটির ধরণ জানেন না", (কারণ আপনি জানেন না যে আপনার চলকের অভ্যন্তরে কী ধরণের হ্যাশ মানচিত্র রয়েছে), আপনি বলতে পারেন যে সমস্ত কিছুই একটি উপশ্রাহক Objectএবং তাই, আপনি যা যা মানচিত্র থেকে বেরিয়ে আসেন is টাইপটি অবজেক্টের হবে:

HashMap<String, Integer> myMap = new HashMap<>();// This variable is used to put things into the map.

myMap.put("ABC", 10);

HashMap<String, ?> map = myMap;
Object output = map.get("ABC");// Valid code; Object is the superclass of everything, (including whatever is stored our hash map).

System.out.println(output);

উপরের কোডের ব্লকটি কনসোলে 10 টি মুদ্রণ করবে।


সুতরাং, সমাপ্ত করার জন্য, HashMapওয়াইল্ডকার্ড সহ একটি ব্যবহার করুন যখন আপনি যত্ন নেন না (যেমন, এটি কোনও ব্যাপার নয়) কী কী প্রকারেরHashMap , উদাহরণস্বরূপ:

public static void printHashMapSize(Map<?, ?> anyMap) {
    // This code doesn't care what type of HashMap is inside anyMap.
    System.out.println(anyMap.size());
}

অন্যথায়, আপনার প্রয়োজনীয় প্রকারগুলি নির্দিষ্ট করুন:

public void printAThroughZ(Map<Character, ?> anyCharacterMap) {
    for (int i = 'A'; i <= 'Z'; i++)
        System.out.println(anyCharacterMap.get((char) i));
}

উপরের পদ্ধতিতে, আমাদের জানতে হবে যে মানচিত্রের কীটি হ'ল একটি Character, অন্যথায়, এর থেকে মানগুলি পেতে কী ধরণের ব্যবহার করতে হবে তা আমরা জানতাম না। সমস্ত বস্তুর একটি toString()পদ্ধতি রয়েছে তবে মানচিত্রটির মানগুলির জন্য যে কোনও ধরণের অবজেক্ট থাকতে পারে। আমরা এখনও মান মুদ্রণ করতে পারেন।

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