مرتب سازی آیتم های ریسایکلر ویو
ممکنه بخواهیم آیتم های ریسایکلر ویو رو مرتب سازی کنیم. (مثلا توی اپ Voice Recorder فایل های ضبط شده برحسب تاریخ مرتب سازی شدن). برای این کار باید لیستی که به ریسایکلر ویو میدیم رو برحسب ویژگی مد نظرمون sort کنیم.
برای این کار کلاس model باید اینترفیس comparable یا comparator رو پیاده سازی کنه. این دو تا مثل هم هستن ولی تفاوت هایی دارن که در جدول زیر اومده:
برای sort کردن آرایه از Arrays.sort و برای sort کردن لیست از Collection.sort استفاده میکنیم.
نکته: به صورت پیش فرض Collections.sort لیست رو صعودی و Collections.reverse لیست رو نزولی مرتب میکنه.
مثال: sort کردن آرایه ای از فایل ها در اپ Voice recorder: (این مرتب سازی نزولی می باشد. چون میخواستم جدیدا بالای لیست قرار بگیرن) - اینکه اولی از دومی بزرگتر باشه نرتب سازی صعودی هست.
Arrays.sort(recordingList, new Comparator<File>() {
@Override
public int compare(File f1, File f2) {
if (f1.lastModified() < f2.lastModified()) {
return 1;
} else if (f1.lastModified() > f2.lastModified()) {
return -1;
} else {
return 0;
}
}
});
یک یعنی swap کن. منفی 1 یعنی swap نکن!
یکی از مزیت های comparator اینه که میشه توی آرگومان sort اونو پیاده سازی کرد. بنابراین اگر بخواهیم یک آرایه یا لیست رو برحسب ویژگی های مختلف مرتب کنیم، میتوان از این روش استفاده کرد. یعنی چند بار comparator به صورت های مختلف پیاده سازی میشه.
مثال خوب از این سایت:
class Movie implements Comparable<Movie>
{
private double rating;
private String name;
private int year;
// Used to sort movies by year
public int compareTo(Movie m)
{
return this.year - m.year;
}
// Constructor
public Movie(String nm, double rt, int yr)
{
this.name = nm;
this.rating = rt;
this.year = yr;
}
// Getter methods for accessing private data
public double getRating() { return rating; }
public String getName() { return name; }
public int getYear() { return year; }
}
//مقایسه بر حسب رتینگ
// Class to compare Movies by ratings
class RatingCompare implements Comparator<Movie>
{
public int compare(Movie m1, Movie m2)
{
if (m1.getRating() < m2.getRating()) return -1;
if (m1.getRating() > m2.getRating()) return 1;
else return 0;
}
}
// مقایسه برحسب اسم فیلم
// Class to compare Movies by name
class NameCompare implements Comparator<Movie>
{
public int compare(Movie m1, Movie m2)
{
return m1.getName().compareTo(m2.getName());
}
}
کلاس Main:
// Driver class
class Main
{
public static void main(String[] args)
{
ArrayList<Movie> list = new ArrayList<Movie>();
list.add(new Movie("Force Awakens", 8.3, 2015));
list.add(new Movie("Star Wars", 8.7, 1977));
list.add(new Movie("Empire Strikes Back", 8.8, 1980));
list.add(new Movie("Return of the Jedi", 8.4, 1983));
// Sort by rating : (1) Create an object of ratingCompare
// (2) Call Collections.sort
// (3) Print Sorted list
System.out.println("Sorted by rating");
RatingCompare ratingCompare = new RatingCompare();
Collections.sort(list, ratingCompare);
for (Movie movie: list)
System.out.println(movie.getRating() + " " +
movie.getName() + " " +
movie.getYear());
// Call overloaded sort method with RatingCompare
// (Same three steps as above)
System.out.println("\nSorted by name");
NameCompare nameCompare = new NameCompare();
Collections.sort(list, nameCompare);
for (Movie movie: list)
System.out.println(movie.getName() + " " +
movie.getRating() + " " +
movie.getYear());
// Uses Comparable to sort by year
System.out.println("\nSorted by year");
Collections.sort(list);
for (Movie movie: list)
System.out.println(movie.getYear() + " " +
movie.getRating() + " " +
movie.getName()+" ");
}
}
خروجی:
Sorted by rating
8.3 Force Awakens 2015
8.4 Return of the Jedi 1983
8.7 Star Wars 1977
8.8 Empire Strikes Back 1980
Sorted by name
Empire Strikes Back 8.8 1980
Force Awakens 8.3 2015
Return of the Jedi 8.4 1983
Star Wars 8.7 1977
Sorted by year
1977 8.7 Star Wars
1980 8.8 Empire Strikes Back
1983 8.4 Return of the Jedi
2015 8.3 Force Awakens
نتیجه گیری: در comparable فقط برحسب یک ویژگی میشه مقایسه کرد ولی در comparator با چند بار پیاده سازی میشه برحسب ویژگی های مختلف مقایسه رو انجام داد.