Göm menyn

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