একটি কাস্টম তুলনাকারীর সাথে একটি ট্রিসেট থেকে সরানো কেন আইটেমের একটি বৃহত্তর সেট সরিয়ে দেয় না?


22

জাভা 8 এবং জাভা 11 উভয়ই ব্যবহার করে নীচের তুলকের TreeSetসাথে বিবেচনা করুন String::compareToIgnoreCase:

final Set<String> languages = new TreeSet<>(String::compareToIgnoreCase);
languages.add("java");
languages.add("c++");
languages.add("python");

System.out.println(languages);                 // [c++, java, python]

আমি যখন উপস্থিত সঠিক উপাদানগুলি মুছে ফেলার চেষ্টা করি তখন TreeSetএটি কাজ করে: নির্দিষ্ট করে দেওয়া সমস্তগুলিই সরানো হয়:

languages.removeAll(Arrays.asList("PYTHON", "C++"));

System.out.println(languages);                 // [java]

যাইহোক, আমি যদি উপস্থিতটিতে উপস্থিত থাকার চেয়ে আরও কিছু সরিয়ে ফেলার চেষ্টা করি তবে TreeSetকলটি কিছুতেই সরিয়ে দেয় না (এটি পরবর্তী কল নয় তবে উপরের স্নিপেটের পরিবর্তে কল করা হয়েছে):

languages.removeAll(Arrays.asList("PYTHON", "C++", "LISP"));

System.out.println(languages);                 // [c++, java, python]

আমি কি ভুল করছি? কেন এটি এভাবে আচরণ করে?

সম্পাদনা: String::compareToIgnoreCaseএকটি বৈধ তুলক:

(l, r) -> l.compareToIgnoreCase(r)

5
সংশ্লিষ্ট বাগ এন্ট্রি: bugs.openjdk.java.net/browse/JDK-8180409 (String.CASE_INSENSITIVE_ORDER সঙ্গে TreeSet removeAll অসঙ্গত আচরণ)
Progman

একটি ঘনিষ্ঠভাবে সম্পর্কিত Q & A-
নামান

উত্তর:


22

সরানোর সমস্ত জাভাদোক এখানে () :

এই প্রয়োগটি প্রতিটিটিতে আকারের পদ্ধতিতে অনুরোধ করে এই সেট এবং নির্দিষ্ট সংগ্রহের চেয়ে ছোটটি নির্ধারণ করে। যদি এই সেটে কম উপাদান থাকে তবে বাস্তবায়নটি এই সেটটিতে পুনরাবৃত্তি করে এবং পুনরুক্তি করে প্রতিটি উপাদানকে নির্দিষ্ট সংকলনে অন্তর্ভুক্ত রয়েছে কিনা তা পরীক্ষা করে পুনরুদ্ধার করে checking যদি এটি এতটা থাকে তবে এটি সেটরটি পুনরাবৃত্তির অপসারণ পদ্ধতির সাহায্যে সরানো হবে। যদি নির্দিষ্ট সংগ্রহটিতে কম উপাদান থাকে, তবে প্রয়োগটি নির্দিষ্ট সংগ্রহের উপরে পুনরাবৃত্তি করে, এই সেট থেকে অপসারণকারী প্রতিটি উপাদান এই সেটটির অপসারণ পদ্ধতিটি ব্যবহার করে পুনরায় সেট করে removing

আপনার দ্বিতীয় পরীক্ষায়, আপনি জাভাডোকের প্রথম ক্ষেত্রে। সুতরাং এটি "জাভা", "সি ++" ইত্যাদির উপর পুনরাবৃত্তি করে এবং সেগুলি সেটার সাথে ফিরে আসে কিনা তা পরীক্ষা করে Set.of("PYTHON", "C++")। তারা নেই, তাই তাদের সরানো হয়নি। যুক্তি হিসাবে একই তুলনামূলক ব্যবহার করে অন্য একটি ট্রিসেট ব্যবহার করুন এবং এটি ঠিকঠাক কাজ করা উচিত। দুটি পৃথক সেট বাস্তবায়ন ব্যবহার করা, একটি ব্যবহার করা equals()এবং অন্যটি তুলনামূলক ব্যবহার করা সত্যই একটি বিপজ্জনক জিনিস।

নোট সেখানে একটি বাগ এই সম্পর্কে খোলে যে: [JDK-8180409] String.CASE_INSENSITIVE_ORDER সঙ্গে TreeSet removeAll অসঙ্গত আচরণ


আপনার অর্থ কি যখন উভয় সেট একই বৈশিষ্ট্য থাকবে, এটি কাজ করে? final Set<String> subLanguages = new TreeSet<>(String::compareToIgnoreCase); subLanguages.addAll(Arrays.asList("PYTHON", "C++", "LISP")); languages.removeAll(subLanguages);
নিকোলাস

1
জাভাডোক দ্বারা বর্ণিত আপনি "যদি এই সেটে কম উপাদান থাকে" in অন্য কেসটি হচ্ছে "যদি নির্দিষ্ট সংগ্রহটিতে কম উপাদান থাকে"।
জেবি নিজত

8
এই উত্তরটি সঠিক, তবে এটি অত্যন্ত অনিচ্ছুক আচরণ। এটি ডিজাইনের একটি ত্রুটির মতো অনুভব করে TreeSet
বোয়ান

আমি সম্মত, কিন্তু আমি এ বিষয়ে কিছুই করতে পারি না।
জেবি নিজত

4
এটি উভয়ই: এটি একটি অত্যন্ত অনিচ্ছাকৃত আচরণ যা সঠিকভাবে নথিবদ্ধ, তবে, অনিচ্ছুক এবং প্রতারক হওয়ার কারণে এটি একটি ডিজাইন বাগও রয়েছে যা কোনও এক দিন স্থির হতে পারে।
জেবি নিজেট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.