java - জাভার ব্যবহার




কেন জাভা সংগ্রহ জেনারিক পদ্ধতি অপসারণ করা হয় না? (6)

কেন Collection.remove (অবজেক্ট ও) সাধারণ নয়?

Collection<E> মত মনে হচ্ছে Collection<E> boolean remove(E o); হতে পারে boolean remove(E o);

তারপরে, যখন আপনি দুর্ঘটনাক্রমে একটি Collection<String> থেকে প্রতিটি স্ট্রিংয়ের পরিবর্তে Set<String> করতে চেষ্টা করেন, তখন এটি ডিবাগিং সমস্যাটির পরিবর্তে একটি কম্পাইল সময় ত্রুটি হবে।


অনুমান করুন একের মধ্যে Cat সংগ্রহ রয়েছে, এবং কিছু বস্তুর Animal , Cat , SiameseCat এবং DogCat বা SiameseCat রেফারেন্স দ্বারা উল্লিখিত বস্তু রয়েছে কিনা সংগ্রহ জিজ্ঞাসা যুক্তিসঙ্গত মনে হয়। Animal রেফারেন্স দ্বারা উল্লেখিত বস্তুটির মধ্যে রয়েছে কিনা তা জিজ্ঞাসা করা হয়তো দূর্বল মনে হতে পারে তবে এটি এখনও পুরোপুরি যুক্তিযুক্ত। প্রশ্ন বস্তু, সব পরে, একটি Cat হতে পারে, এবং সংগ্রহে প্রদর্শিত হতে পারে।

উপরন্তু, বস্তুটি যদি Cat ছাড়া অন্য কিছু হয় তবে এমনকি সংগ্রহটিতে প্রদর্শিত হয় কিনা তা কোন সমস্যা নেই - কেবল "না, এটি না" উত্তর দেয়। কোনও ধরণের "সন্ধান-শৈলী" সংগ্রহটি কোনও সুপারটিপের উল্লেখযোগ্য অর্থ গ্রহণ করতে এবং এটি বস্তুর মধ্যে থাকা বস্তুটি বিদ্যমান কিনা তা নির্ধারণ করতে সক্ষম হওয়া উচিত। যদি পাস-ইন অবজেক্ট রেফারেন্সটি কোন সম্পর্কহীন প্রকারের হয় তবে সংগ্রহটি সম্ভবত এটি ধারণ করতে পারে এমন কোন উপায় নেই, তাই কোয়েরিটি কিছুটা অর্থপূর্ণ নয় (এটি সর্বদা "না" উত্তর দেবে)। তা সত্ত্বেও, উপপরিচালক বা সুপারটিপাইপ হওয়ার জন্য প্যারামিটারগুলি সীমাবদ্ধ করার কোন উপায় নেই, যেহেতু সংগ্রহের সাথে সম্পর্কিত নয় এমন কোনও বস্তুর জন্য কেবলমাত্র কোনও প্রকারের উত্তর এবং "না" উত্তর দেওয়ার পক্ষে সর্বাধিক ব্যবহারিক।


অন্যান্য উত্তরগুলির পাশাপাশি পদ্ধতিটি একটি Object গ্রহণ করা উচিত বলে অন্য একটি কারণ রয়েছে যা ভবিষ্যদ্বাণী করা হয়। নিম্নলিখিত নমুনা বিবেচনা করুন:

class Person {
    public String name;
    // override equals()
}
class Employee extends Person {
    public String company;
    // override equals()
}
class Developer extends Employee {
    public int yearsOfExperience;
    // override equals()
}

class Test {
    public static void main(String[] args) {
        Collection<? extends Person> people = new ArrayList<Employee>();
        // ...

        // to remove the first employee with a specific name:
        people.remove(new Person(someName1));

        // to remove the first developer that matches some criteria:
        people.remove(new Developer(someName2, someCompany, 10));

        // to remove the first employee who is either
        // a developer or an employee of someCompany:
        people.remove(new Object() {
            public boolean equals(Object employee) {
                return employee instanceof Developer
                    || ((Employee) employee).company.equals(someCompany);
        }});
    }
}

বিন্দুটি হ'ল remove পদ্ধতিতে প্রেরিত বস্তুটি equals পদ্ধতি নির্ধারণের জন্য দায়ী। ভবিষ্যদ্বাণী ভবন এই ভাবে খুব সহজ হয়ে যায়।


আরেকটি কারণ ইন্টারফেস কারণ। এখানে দেখানোর জন্য এটি একটি উদাহরণ:

public interface A {}

public interface B {}

public class MyClass implements A, B {}

public static void main(String[] args) {
   Collection<A> collection = new ArrayList<>();
   MyClass item = new MyClass();
   collection.add(item);  // works fine
   B b = item; // valid
   collection.remove(b); /* It works because the remove method accepts an Object. If it was generic, this would not work */
}

কারণ আপনার টাইপ প্যারামিটার একটি ওয়াইল্ডকার্ড থাকলে, আপনি একটি জেনেরিক অপসারণ পদ্ধতি ব্যবহার করতে পারবেন না।

আমি ম্যাপ এর পেতে (অবজেক্ট) পদ্ধতির সাথে এই প্রশ্নের মধ্যে চলমান মনে মনে। এই ক্ষেত্রে পেতে পদ্ধতিটি জেনেরিক নয়, তবে এটি যুক্তিযুক্তভাবে প্রথম টাইপ পরামিতি হিসাবে একই ধরণের একটি বস্তু পাস করা উচিত। আমি বুঝতে পারলাম যে যদি আপনি প্রথম টাইপ পরামিতির মতো কোনও ওয়াইল্ডকার্ড দিয়ে মানচিত্রের কাছাকাছি চলে যাচ্ছেন তবে সেই পদ্ধতির সাথে মানচিত্র থেকে উপাদানটি বের করার কোন উপায় নেই, যদি সেই যুক্তিটি জেনেরিক হয়। ওয়াইল্ডকার্ড আর্গুমেন্ট সত্যিই সন্তুষ্ট হতে পারে না, কারণ কম্পাইলার সঠিক যে টাইপ সঠিক নয়। আমি যুক্তিসঙ্গত কারণ যোগ জেনারিক হয় যে আপনি সংগ্রহের যোগ করার আগে টাইপ সঠিক যে গ্যারান্টি আশা করা হয়। যাইহোক, যখন কোনও বস্তু অপসারণ করা হয়, যদি টাইপটি ভুল হয় তবে এটি যেকোনো উপায়ে মিলবে না। যদি যুক্তিটি একটি ওয়াইল্ডকার্ড হয় তবে পদ্ধতিটি সহজেই অব্যবহারযোগ্য হবে, যদিও আপনার কাছে এমন একটি বস্তু থাকতে পারে যা আপনি গ্যারান্টিটি সেই সংগ্রহের অন্তর্গত হতে পারেন, কারণ আপনি পূর্বের লাইনে এটির একটি রেফারেন্স পেয়েছেন ....

আমি সম্ভবত এটি খুব ভাল ব্যাখ্যা না, কিন্তু এটা আমার কাছে যথেষ্ট যৌক্তিক মনে হয়।


জোশ ব্লোক এবং বিল পুগ জাভা পাজলার্স IV এ এই বিষয়টি উল্লেখ করেছেন: দ্য ফ্যান্টম রেফারেন্স মেনেস, ক্লোন আক্রমণ, এবং শিফ্ট অফ রিফ্ট

জোশ ব্লোক বলেছেন (6:41) যে তারা মানচিত্রের পদ্ধতিটি জেনারেট করার পদ্ধতি, পদ্ধতি এবং অন্য কিছু সরানোর চেষ্টা করেছিল, কিন্তু "এটি কেবল কাজ করে নি।"

অনেকগুলি যুক্তিসঙ্গত প্রোগ্রাম রয়েছে যা জেনারেট করা যাবে না যদি আপনি কেবল জেনারিক প্রকারের সংগ্রহটিকে প্যারামিটার টাইপ হিসাবে অনুমতি দেন। তার দ্বারা প্রদত্ত উদাহরণটি সংখ্যাগুলির List এবং Long তালিকাগুলির একটি অন্তর্চ্ছেদ।


সরান একটি জেনেরিক পদ্ধতি নয় যাতে অ-জেনেরিক সংগ্রহ ব্যবহার করে বিদ্যমান কোড এখনও কম্পাইল এবং এখনও একই আচরণ থাকবে।

বিস্তারিত জানার জন্য http://www.ibm.com/developerworks/java/library/j-jtp01255.html দেখুন।

সম্পাদনা: একটি মন্তব্যকারী জেনারিক যোগ পদ্ধতি কেন জিজ্ঞেস করে। [... আমার ব্যাখ্যা সরানো ...] দ্বিতীয় মন্তব্যকারী আমার চেয়ে অনেক ভাল firebird84 এর প্রশ্নের উত্তর দিয়েছে।






collections