TDDE22 Datastrukturer och algoritmer
Komparatorer i Java
Göra egna comparators
Nedan följer ett exempel som illustrerar och förklarar hur ni kan göra egna comparators i java för att förenkla sortering. Jag har liberalt kryddat det med kommentarer, så förhoppningsvis är det tydligt. Det går utmärkt att kopiera, kompilera och testa om ni vill.
Course.java// A small class to represent a course, so we have something // interesting to sort. public class Course { private boolean programmingCourse; private double rating; private String name; public Course(String name, boolean programmingCourse, double rating) { this.programmingCourse = programmingCourse; this.rating = rating; this.name = name; } public boolean isProgrammingCourse() { return programmingCourse; } public double getRating() { return rating; } public String getName() { return name; } }Main.java
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; public class Main { public static void main(String[] args) { // We have an arraylist and add some data to it. ArrayList<Course> courseList = new ArrayList<>(); courseList.add(new Course("SIGH99", false, 3.9)); courseList.add(new Course("TDDE22", true, 4.5)); courseList.add(new Course("TDDE10", true, 4.5)); courseList.add(new Course("ZZZZ01", false, 2.5)); // We print all the data prior to sorting for (Course c : courseList) { System.out.println(c.getName()); } System.out.println("\n########################################\n"); // We call Collections.sort on our arraylist, and pass an // instance of our Comparator to show sort how we want the // objects within the list compared. Collections.sort(courseList, new CourseComparator()); // We once more print the list, this time after sorting. for (Course c : courseList) { System.out.println(c.getName()); } } /** * Comparator class for the Course class. We judge which course is * the better course by first determining whether they are * programming courses, and if needed we compare their ratings. If * we wish to sort in descending order rather than ascending, we * can switch places on return -1 and return 1, and return * -aRating.compareTo(b.getRating()); (minus aRating...) to switch * the polarity. Basically we reverse the sort by changing what is * considered "greater" and "lesser". * If you don't have unique elements in the data you are sorting, * you will get into trouble unless you handle elements of * equal value. If you get the error that you are breaching or * violating the contract, it means your comparator is not transitive. * Transitivity means that if a < b, we cannot have b < a. If you * don't handle the case where a == b, this problem can arise. * If the two elements are equal, return 0. The .compareTo-method * handles this, so if you use that as I do below, there won't be a * problem. */ private static class CourseComparator implements Comparator<Course> { public int compare(Course a, Course b){ // If both courses are programming courses we have to // check their rating. if (a.isProgrammingCourse() && b.isProgrammingCourse()) { // We extract a's rating and store it as Double (the // wrapper class) instead of the primitive double, // since all such classes have a defined // compareTo-method. Even Strings do! Double aRating = a.getRating(); // We use the built in compareTo-method instead of // writing our own comparison (which we, of course, // can if we want to using if-statements and the <, // >, == operators). return aRating.compareTo(b.getRating()); } else if (a.isProgrammingCourse()) { // Course a is a programming course, so it's greater // than b (right?), so we return 1. return 1; } else if (b.isProgrammingCourse()) { // Course b is a programming course, so it's greater // than a (right?), so we return -1. return -1; } else { // Neither course is a programming course, so we look // at the rating. See above for explanation. Double aRating = a.getRating(); return aRating.compareTo(b.getRating()); } // If we would like two courses to be considered "equal" // we would return 0. } } }Om vi kör programmet ovan får vi följande utskrift:
SIGH99 TDDE22 TDDE10 ZZZZ01 ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ZZZZ01 SIGH99 TDDE22 TDDE10
Sidansvarig: Magnus Nielsen
Senast uppdaterad: 2023-08-08