Ivan C
Ivan C

Reputation: 1821

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?

Upvotes: 1

Views: 1299

Answers (3)

MacStation
MacStation

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

nhouser9
nhouser9

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

Joshua Goldberg
Joshua Goldberg

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

Related Questions