Search code examples
javasortingarraylistinterfacecomparable

Why Can't I Sort this ArrayList?


I am copying off of an example from my textbook and yet it refuses to compile. Did I make a typo somewhere? For some reason, on the client code, Collections.sort(words) does not allow the program to compile. Any help is appreciated. Code is copied from "Building Java Programs" 2nd edition by Stuart Reges and Marty Stepp. I'm trying to understand it by copying it.

The program is supposed to crate a CalendarDate object to put into an ArrayList. By implementing the Comparable interface for CalendarDate, I can use the Collections.sort to sort the birthdays in order in that arraylist. However, that's not working b/c Collections.sort(dates) will not run.

The Client code(Contains the issue):

import java.util.*;

// Short program that creates a list of birthdays of the
// first 5 U.S. Presidents and that puts them into sorted order.
// We can now use Collections.sort for ArrayList<CalendarDate> b/c CalendarDate implements the Comparable interface. 

public class CalendarDateTest {
    public static void main(String[] args) {
        ArrayList<CalendarDate> dates = new ArrayList<CalendarDate>(); // Creates a new ArrayList of 'CalendarDate' object type.

        // adds a new CalendarDate object with month = 2 and day = 22 into an element of ArrayList dates, and etc.
        dates.add(new CalendarDate(2, 22)); // Washington
        dates.add(new CalendarDate(10, 30)); //Adams
        dates.add(new CalendarDate(4, 13)); // Jefferson
        dates.add(new CalendarDate(3, 16)); // Madison
        dates.add(new CalendarDate(4, 28)); // Monroe

        System.out.println("birthdays = " + dates); // Before sorting
        Collections.sort(dates); // WHY WON'T THIS WORK?
        System.out.println("birthdays = " + dates); // After Sorting
    }

}

The CalendarDate object class:

 public class CalendarDate implements Comparable<CalendarDate> { 
    private int month;
    private int day;

    // Constructor
    public CalendarDate(int month, int day) {
        this.month = month;
        this.day = day;
    }

    // Compares this calendar date to another date
    // Dates are compared by month and then by day
    public int compareTo(CalendarDate other) {
        if (month != other.month) { // If different months
            return month - other.month; //negative, positive, or zero
        } else { // If same months; compare days instead
            return day - other.day; // negative, positive, or zero
        }
    }

    // Accessor for month (b/c month is private)
    public int getMonth() {
        return this.month;
    }

    // Accessor for day (b/c day is private)
    public int getDay() {
        return this.day;
    }

    // A toString method
    public String toString() {
        return month + "/" + day;
    }
    }

The Comparable interface:

 public interface Comparable<T> { // T is the generic type (a placeholder for when other classes implement this)
        public int compareTo(T other); // placeholder to be implemented; need more specific version into class implementing this.
    }

Compiler error:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
    Bound mismatch: The generic method sort(List<T>) of type Collections is not applicable for the arguments (ArrayList<CalendarDate>). The inferred type CalendarDate is not a valid substitute for the bounded parameter <T extends Comparable<? super T>>

    at CalendarDateExample.CalendarDateTest.main(CalendarDateTest.java:21)

Solution

  • Don't define your own Comparable interface. You need to implement java.lang.Comparable.