0

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?

mukul ishwar
  • 25
  • 1
  • 7
  • 2
    your `Box` class does not implement `Comparable`. How do you expect `sort` to know how to sort? – njzk2 Dec 18 '17 at 05:29

6 Answers6

3

It's because in first you sort "item", in second you sort "list thing"
So, you can fix it by using lambda:

Collections.sort(store, (o1, o2) -> {
your implementation of comparator
});
  • If you are using jdk 8 or above and want all classes implementing "Thing" should be sorted on the bases of same parameter you should change your interface to this: – DhaRmvEEr siNgh Dec 18 '17 at 05:44
3

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());
    }
}
Thomas Kläger
  • 17,754
  • 3
  • 23
  • 34
  • Thanks you so much I did it by making a separate Comparator public class Sort implements Comparator { @Override public int compare(Thing o1, Thing o2) { if(o1.getVolume() < o2.getVolume()){ return -1; } if(o1.getVolume() == o2.getVolume()){ return 0; } else{ return 1; } } } and using Collections.sort(store, new Sort()). but I didnt understood how to do this line of yours: "or you declare Thing implements Comparable" – mukul ishwar Dec 18 '17 at 07:26
0

I recommend you define Thing to extend Comparable, given your application doesn't work when you add classes not being Comparable.

By the way, your compareTo looks rather complicated. Do this instead:

int compareTo(Thing another) {
    return this.getVolume()  - another.getVolume();
    }
Johan Witters
  • 1,529
  • 11
  • 23
  • The `compareTo` method is implemented correctly. For a reason why your implementation is wrong look at https://stackoverflow.com/q/2728793/5646962 – Thomas Kläger Dec 18 '17 at 06:07
0

In the first program, you have

public class Item implements Thing, Comparable<Thing>

But in the second, you just have

public class Box implements Thing

If you want sort to work, you need to either implement Comparable or Comparator (separate class implementing just Comparator).

Nipun
  • 65
  • 9
0

If you are using jdk 8 or above and want all classes implementing "Thing" should be sorted on the bases of same parameter you should change your interface to this to provide default sorting capability:

//extend your interface with comparable

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) {
    if(this.getVolume()  < another.getVolume()){
        return -1;
    }

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

}

Now Item and Box only needs to implement Thing interface.

Please try to optimize compareTo() method also as suggested by @Jo Witters

DhaRmvEEr siNgh
  • 1,918
  • 2
  • 13
  • 17
-1

Make Thing an abstract class implementing Comparable , so that Thing is always ready for sorting . Item can be extended from Thing

Raaghu
  • 1,956
  • 1
  • 19
  • 17