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?
答案 0 :(得分: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 Thing
s.
To fix it you either have to provide a comparator for two Thing
s (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());
}
}
答案 1 :(得分:2)
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
});
答案 2 :(得分: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();
}
答案 3 :(得分: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).
答案 4 :(得分: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
答案 5 :(得分:-1)
Make Thing an abstract class implementing Comparable , so that Thing is always ready for sorting . Item can be extended from Thing