Reputation: 123
I have an odd question:
I have two classes, Book
and Newspaper
. They share the attribute price
. I have to implement a PriceComparator
which obviously compares price
from Book
and Newspaper
. I'm not too experienced -especially in Java but my top off the head solution would be to make an interface which would get me the common values and I could do my comparison based on those but that is not possible for two reasons:
1) I can only have the classes Book
, Newspaper
, Main
and PriceComparator
and I'm not allowed to create another class/interface within the same .java file.
2) I have to use one list which contains both Book
and Newspaper
My solution for this would be to maybe create a List<Object>
and then compare the generic objects using casting to get their value via their getter, but this seems so clunky to me and I think there must be a better solution, though I can't think of one. I hope my question makes sense. Thanks!
Upvotes: 0
Views: 1047
Reputation: 439
@Themelis answer is the more appropriate (and probably more efficient) solution IMO. But in case anyone is interested here is an alternative using reflection:
Function<Object, Double> keyExtractor = o -> {
try {
Field field = o.getClass().getDeclaredField("fieldName");
field.setAccessible(true);
Double value = (Double) field.get(o);
field.setAccessible(false);
return value;
} catch (Exception e) {
return -1D;
}
};
Comparator<Object> comparing = Comparator.comparing(keyExtractor, Double::compareTo);
List<Object> objects = new ArrayList<>(List.of(new A(1), new B(3), new A(2), new B(0)));
objects.sort(comparing);
Note: If you pass in an object of a class with no declared field fieldName
of type double
then NoSuchFieldException
or ClassCastException
will be thrown and -1 return for the comparison resulting in these objects to be at the beginning of the list after a sort.
Upvotes: 0
Reputation: 4255
If you're not allowed to create another class/interface within the same .java file then create your interface seperately. For example,
Priceable.java
public interface Priceable {
double getPrice();
}
Book.java
public class Book implements Priceable{
// ...
int price;
@Override
public double getPrice() {
return price;
}
}
Newspaper.java
public class Newspaper implements Priceable{
// ... other
private double price;
@Override
public double getPrice() {
return price;
}
}
Now you can define a Comparator<Pricable>
which compares the prices. For example,
Comparator<Priceable> products = (o1, o2) -> (int) (o2.getPrice() o1.getPrice());
Upvotes: 2