Ivan C Ivan C - 1 month ago 15
Java Question

Find out the cheapest item

I'm still new to Java and Eclipse. I'm supposed to find out the cheapest item in a list through a generic class and print out it's parameters. I have this:

public class Store<T extends Item>{

public List<T> items = new ArrayList<T>();

public void addItem(T it){
items.add(it);
}

public T cheapestItem(){
T cheapest;

Collections.sort(items, (i1, i2) -> i1.getPrice().compareTo(i2.getPrice()));

cheapest = Collections.min(items,null);

return cheapest;

}


}


Inside my main activity:

Store<Item> store = new Store<>();

for (int i = 0; i < items.size(); i++) {
store.addItem(items.get(i).getA());
store.addItem(items.get(i).getB());
}

System.out.println("Cheapest item price is " + store.cheapestItem().getPrice());


I get an error message:

Exception in thread "main" java.lang.ClassCastException: com.java.school.B cannot be cast to java.lang.Comparable
at java.util.Collections.min(Unknown Source)
at java.util.Collections.min(Unknown Source)
at com.java.school.Store.cheapestItem(Store.java:20)
at com.java.school.Main.main(Main.java:313)


Unfortunately, I'm not sure what I am doing wrong, since Eclipse is not pointing it out before runtime. Can somebody point me in the right direction? Is there another way to go about doing this?

Answer

The best solution is to use your comparator in the min method, instead of null. This should allow it to get the result you need - a comparator cannot get the minimum if it doesn't know how to compare the items! You can remove the call to sort and add the comparator to the call to min. It would look like this:

public T cheapestItem(){
    return Collections.min(items, (i1, i2) -> i1.getPrice().compareTo(i2.getPrice()));
}

If this returns the most expensive instead of the cheapest, just change the order of your comparison from t1.compareTo(t2) to t2.compareTo(t1).