Reputation: 1821
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?
Upvotes: 1
Views: 1299
Reputation: 411
What I would do is create a local variable which stores the cheapest item found and iterate through the list.
public T cheapestItem() {
T cheapest = items.get(0);
for (T item : items) {
if (item.getPrice() < cheapest.getPrice()) {
cheapest = item;
}
}
}
Upvotes: 0
Reputation: 6780
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)
.
Upvotes: 3
Reputation: 5333
Your exception shows that T
must implement Comparable
in order to use the method Collections.min
. You "prove" that to the compiler (and ensure it's true) in your not-shown definition of Item
. Declare that Item implements Comparable
and ensure that there is a compareTo
method there.
Upvotes: -1