我有一个奇怪的问题:
我有两个班,Book
和Newspaper
。它们共享属性price
。我必须实现一个PriceComparator
,它显然会比较price
和Book
中的Newspaper
。我不太有经验-尤其是在Java中,但是我最头疼的解决方案是创建一个接口,该接口将为我提供通用值,并且我可以基于这些值进行比较,但是由于两个原因,这是不可能的:>
1)我只能有类Book
,Newspaper
,Main
和PriceComparator
,并且不允许在同一类中创建另一个类/接口。 Java文件。
2)我必须使用一个包含Book
和Newspaper
为此,我的解决方案是创建一个List<Object>
,然后使用强制转换比较通用对象以通过其getter获得其值,但是对我来说这似乎很笨拙,我认为必须有一个更好的解决方案,尽管我想不到一个。我希望我的问题有道理。谢谢!
答案 0 :(得分:2)
如果不允许您在同一.java文件中创建另一个类/接口,请分别创建您的接口。例如,
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;
}
}
现在,您可以定义一个Comparator<Pricable>
来比较价格。例如,
Comparator<Priceable> products = (o1, o2) -> (int) (o2.getPrice() o1.getPrice());
答案 1 :(得分:0)
@Themelis的答案是更合适的(可能是更有效的)IMO解决方案。但是,如果有人对此感兴趣的话,可以使用反射:
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);
注意:如果传入没有声明类型fieldName
的声明字段double
的类的对象,则将抛出NoSuchFieldException
或ClassCastException
并返回-1进行比较后,这些对象在排序后位于列表的开头。