Java-来自不同对象类型的相同属性的比较器类

时间:2020-04-01 14:04:42

标签: java list comparator

我有一个奇怪的问题:

我有两个班,BookNewspaper。它们共享属性price。我必须实现一个PriceComparator,它显然会比较priceBook中的Newspaper。我不太有经验-尤其是在Java中,但是我最头疼的解决方案是创建一个接口,该接口将为我提供通用值,并且我可以基于这些值进行比较,但是由于两个原因,这是不可能的:

1)我只能有类BookNewspaperMainPriceComparator,并且不允许在同一类中创建另一个类/接口。 Java文件。

2)我必须使用一个包含BookNewspaper

的列表

为此,我的解决方案是创建一个List<Object>,然后使用强制转换比较通用对象以通过其getter获得其值,但是对我来说这似乎很笨拙,我认为必须有一个更好的解决方案,尽管我想不到一个。我希望我的问题有道理。谢谢!

2 个答案:

答案 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的类的对象,则将抛出NoSuchFieldExceptionClassCastException并返回-1进行比较后,这些对象在排序后位于列表的开头。

相关问题