( একাধিক ক্ষেত্রের ভিত্তিতে জাভাতে অবজেক্টের তালিকাগুলি বাছাই করার উপায়গুলি থেকে )
এই টুকরোটিতে কার্যকারী কোড
জাভা 8 ল্যাম্বদা ব্যবহার করে (10 এপ্রিল, 2019 যোগ করা হয়েছে)
জাভা 8 ল্যাম্বডা দ্বারা এটি সুন্দরভাবে সমাধান করে (যদিও পেয়ারা এবং অ্যাপাচি কমন্স এখনও আরও নমনীয়তার প্রস্তাব দিতে পারে):
Collections.sort(reportList, Comparator.comparing(Report::getReportKey)
.thenComparing(Report::getStudentNumber)
.thenComparing(Report::getSchool));
নীচে @ gaoagong এর উত্তর ধন্যবাদ ।
অগোছালো এবং সংশ্লেষিত: হাতে বাছাই করা
Collections.sort(pizzas, new Comparator<Pizza>() {
@Override
public int compare(Pizza p1, Pizza p2) {
int sizeCmp = p1.size.compareTo(p2.size);
if (sizeCmp != 0) {
return sizeCmp;
}
int nrOfToppingsCmp = p1.nrOfToppings.compareTo(p2.nrOfToppings);
if (nrOfToppingsCmp != 0) {
return nrOfToppingsCmp;
}
return p1.name.compareTo(p2.name);
}
});
এর জন্য প্রচুর টাইপিং, রক্ষণাবেক্ষণ প্রয়োজন এবং এটি ত্রুটিযুক্ত।
প্রতিবিম্বিত উপায়: বিন কমপারেটর দিয়ে বাছাই করা
ComparatorChain chain = new ComparatorChain(Arrays.asList(
new BeanComparator("size"),
new BeanComparator("nrOfToppings"),
new BeanComparator("name")));
Collections.sort(pizzas, chain);
স্পষ্টতই এটি আরও সংক্ষিপ্ত, তবে এর পরিবর্তে স্ট্রিংস ব্যবহার করে আপনি ক্ষেত্রগুলিতে সরাসরি রেফারেন্স হারিয়ে ফেলার কারণে আরও ত্রুটিযুক্ত হওয়ার সম্ভাবনা রয়েছে (কোনও টাইপস্যাফটি, অটো-রিফ্যাক্টরিং নেই)। এখন যদি কোনও ক্ষেত্রটির নাম পরিবর্তন করা হয়, তবে সংকলক এমনকি কোনও সমস্যার প্রতিবেদন করবে না। তদতিরিক্ত, কারণ এই সমাধানটি প্রতিবিম্ব ব্যবহার করে, বাছাই করা অনেক ধীর।
সেখানে পৌঁছনো: গুগল পেয়ারার তুলনাচিহ্নের সাথে বাছাই করা
Collections.sort(pizzas, new Comparator<Pizza>() {
@Override
public int compare(Pizza p1, Pizza p2) {
return ComparisonChain.start().compare(p1.size, p2.size).compare(p1.nrOfToppings, p2.nrOfToppings).compare(p1.name, p2.name).result();
// or in case the fields can be null:
/*
return ComparisonChain.start()
.compare(p1.size, p2.size, Ordering.natural().nullsLast())
.compare(p1.nrOfToppings, p2.nrOfToppings, Ordering.natural().nullsLast())
.compare(p1.name, p2.name, Ordering.natural().nullsLast())
.result();
*/
}
});
এটি অনেক ভাল, তবে সাধারণ ব্যবহারের ক্ষেত্রে কিছু বয়লার প্লেট কোডের প্রয়োজন: নাল-মানগুলি ডিফল্টরূপে কম মূল্যবান হওয়া উচিত। নাল ক্ষেত্রের জন্য, আপনাকে পেয়ারা কে এই ক্ষেত্রে কী করতে হবে তার জন্য অতিরিক্ত নির্দেশিকা সরবরাহ করতে হবে। আপনি সুনির্দিষ্ট কিছু করতে চাইলে এটি একটি নমনীয় প্রক্রিয়া, তবে প্রায়শই আপনি ডিফল্ট কেসটি (যেমন 1, এ, বি, জেড, নাল) চান।
অ্যাপাচি কমন্স তুলনাটোবিল্ডারের সাথে বাছাই করা হচ্ছে
Collections.sort(pizzas, new Comparator<Pizza>() {
@Override
public int compare(Pizza p1, Pizza p2) {
return new CompareToBuilder().append(p1.size, p2.size).append(p1.nrOfToppings, p2.nrOfToppings).append(p1.name, p2.name).toComparison();
}
});
পেয়ারার তুলনাচাঁইনের মতো এই লাইব্রেরি ক্লাসটি একাধিক ক্ষেত্রগুলিতে সহজেই সাজান, তবে নাল মানগুলির জন্য ডিফল্ট আচরণকে (যেমন 1, a, b, z, নাল) সংজ্ঞায়িত করে। তবে আপনি নিজের তুলনামূলক সরবরাহ না করে আপনি অন্য কোনও কিছু নির্দিষ্ট করতে পারবেন না।
এইভাবে
শেষ পর্যন্ত এটি স্বাদে নেমে আসে এবং নমনীয়তার জন্য প্রয়োজনীয়তা (পেয়ারা'র তুলনাচয়ন) বনাম সংক্ষিপ্ত কোড (অ্যাপাচি'র কমপিটারটোবিল্ডার)।
বোনাস পদ্ধতি
আমি একটা চমৎকার সমাধান পাওয়া যে সম্মিলন একাধিক comparators অগ্রাধিকার ক্রমানুসারে CodeReview উপর একটি MultiComparator
:
class MultiComparator<T> implements Comparator<T> {
private final List<Comparator<T>> comparators;
public MultiComparator(List<Comparator<? super T>> comparators) {
this.comparators = comparators;
}
public MultiComparator(Comparator<? super T>... comparators) {
this(Arrays.asList(comparators));
}
public int compare(T o1, T o2) {
for (Comparator<T> c : comparators) {
int result = c.compare(o1, o2);
if (result != 0) {
return result;
}
}
return 0;
}
public static <T> void sort(List<T> list, Comparator<? super T>... comparators) {
Collections.sort(list, new MultiComparator<T>(comparators));
}
}
অবশ্যই অবশ্যই অ্যাপাচি কমন্স সংগ্রহগুলির এর জন্য ইতিমধ্যে একটি ব্যবহার রয়েছে:
ComparatorUtils.chainedComparator (comparatorCollection)
Collections.sort(list, ComparatorUtils.chainedComparator(comparators));