Search code examples
javasortingcomparable

Java Collections.sort() not working even though comparable is declared


Here is my interface class

public interface Thing {
    int getVolume();
}

And here is the class which implements Thing

Item.java

public class Item implements Thing, Comparable<Thing> {
    private String name;
    private int volume;

    public Item(String name,int volume){
        this.name = name;
        this.volume = volume;
    }

    @Override
    public int getVolume() {
        return this.volume;
    }

    public String getName(){
        return this.name;
    }

    @Override
    public String toString(){
        return name+" ("+volume+" dm^3)";
    }

 //   @Override
    @Override
    public int compareTo(Thing another) {
        if(this.getVolume()  < another.getVolume()){
            return -1;
        }

        if(this.getVolume() == another.getVolume()){
            return 0;
        }
        else{
            return 1;
        }
    }

}

When I try to run the main program with the following commands it runs fine // main program.java

public class Main {

    public static void main(String[] args) {
        // test your program here
     List<Item> items = new ArrayList<Item>();
    items.add(new Item("passport", 2));
    items.add(new Item("toothbrash", 1));
    items.add(new Item("circular saw", 100));

    Collections.sort(items);
    System.out.println(items);



    }
}

But when I try to run Collections.sort() on another class which implements the Thing interface, I get an error

here is the box class which implements the Thing interface and when I try to run the Collections.sort(store) in the void sort() function it gives an error even the store is a List and the Box class implements Thing interface and I have defined comparable for Thing in the Item.java class

Box.java

public class Box implements Thing {

    private int maximumCapacity;
    private List<Thing> store;

    public Box(int maximumCapacity) {
        this.maximumCapacity = maximumCapacity;
        this.store = new ArrayList<Thing>();
    }

    public boolean addThing(Thing thing) {
        // I.E. if the item added does not make the total volume go to max capacity only
        // then add
        if (this.getVolume() + thing.getVolume() < this.maximumCapacity) {
            store.add(thing);
            return true;
        }
        return false;
    }

    @Override
    public int getVolume() {
        // we calculate things of all items in the boxes (current value)
        int currentWeight = 0;
        for (Thing t : store) {
            currentWeight += t.getVolume();
        }
        return currentWeight;
    }

    public List<Thing> getStore() {
        return store;
    }

    public int numOfItems(){
        return this.store.size();
    }


     public void sort(){ 

        Collections.sort(store); // *****does not work ****//

     }

}

It gives an error above for sort as "No suitable method found for sort(List <Thing>)."

My question is if it can work in the main.java program where the items are given as List then why can it not work here ? How to fix it?


Solution

  • It the main class you sort a List<Item> where Item implements Thing, Comparable<Thing>.

    In the Box class you try to sort List<Thing>, but Thing itself does not implement Comparable<Thing>. Therefore Java doesn't know how to sort Things.

    To fix it you either have to provide a comparator for two Things (as proposed by Александр Нестеров) or you declare Thing implements Comparable<Thing>:

    public interface Thing extends Comparable<Thing>{
    
        int getVolume();
    
        //provide default method to sort any class which implements Thing
        @Override
        public default int compareTo(Thing another) {
            return Integer.compare(this.getVolume(), another.getVolume());
        }
    }