简体   繁体   English

使用 getter 方法参考的 map 创建比较器

[英]Create Comparator using map of getter method references

I have tried to create a Comparator based on object fields that have non-null values using Comparator.compare and then chain it with Comparator.thenCompare .我试图创建一个基于 object 字段的比较器,这些字段使用Comparator.compare具有非空值,然后将其与Comparator.thenCompare链接。 I have a HashMap that stores a field as a key and getter method reference as a value.我有一个 HashMap 将字段存储为键和 getter 方法引用作为值。

Here is my enum of fields:这是我的字段枚举:

 public enum BikeProperty {
     BRAND,
     MAX_SPEED,
     WEIGHT,
     SIZE_OF_WHEEL,
     NUMBER_OF_GEARS,
     IS_LIGHT_AVAILABLE,
     BATTERY_CAPACITY,
     COLOR,
     PRICE
}

Each of this fields related to some field in Bike object.每个字段都与Bike object 中的某个字段相关。

Next stop is my HashMap that looks like this:下一站是我的 HashMap,它看起来像这样:

    Map<BikeProperty, Function<Bike, Comparable<?>>> fieldToFieldExtractor = new HashMap<>();
    fieldToFieldExtractor.put(BikeProperty.MAX_SPEED, Bike::getMaxSpeed);
    fieldToFieldExtractor.put(BikeProperty.WEIGHT, Bike::getWeight);
    fieldToFieldExtractor.put(BikeProperty.SIZE_OF_WHEEL, Bike::getSizeOfWheels);
    fieldToFieldExtractor.put(BikeProperty.NUMBER_OF_GEARS, Bike::getNumberOfGears);
    fieldToFieldExtractor.put(BikeProperty.IS_LIGHT_AVAILABLE, Bike::isLightsAvailable);
    fieldToFieldExtractor.put(BikeProperty.BATTERY_CAPACITY, Bike::getBatteryCapacity);
    fieldToFieldExtractor.put(BikeProperty.COLOR, Bike::getColor);
    fieldToFieldExtractor.put(BikeProperty.PRICE, Bike::getPrice);

And finally my method:最后是我的方法:

public Comparator<Bike> provideComparatorByFields(Set<BikeProperty> fields) {
    Comparator<Bike> comparator = Comparator.comparing(Bike::getBrand);
    fields
            .forEach(s -> comparator.thenComparing(fieldToFieldExtractor.get(s)));
    return comparator;
}

My idea is to pass to method already filtered Set<BikePropery> , iterate through this and chain comparator methods.我的想法是传递给已过滤的方法Set<BikePropery> ,遍历此方法并链接比较器方法。

For example, for given set Set.of(BikeProperty.PRICE,BikeProperty.IS_LIGHT_AVAILABLE) , generate following comparator: Comparator.compare(Bike::getBrand).thenCompare(Bike::getPrice).thenCompare(Bike::isLightAvailable)例如,对于给定的集合Set.of(BikeProperty.PRICE,BikeProperty.IS_LIGHT_AVAILABLE) ,生成以下比较器: Comparator.compare(Bike::getBrand).thenCompare(Bike::getPrice).thenCompare(Bike::isLightAvailable)

Problem: Created comparator have only one default comparing of Bike::getBrand() .问题:创建的比较器只有一个Bike::getBrand()的默认比较。 Therefore, I had a question, is it possible to do so at all, and if possible, bring some advice.因此,我有一个问题,是否有可能这样做,如果可能,请提出一些建议。 Thank you!谢谢!

Update更新

When I`m creating comparator (for example) from my main method, it looks like this:当我从我的主要方法创建比较器(例如)时,它看起来像这样: 在此处输入图像描述

在此处输入图像描述

But when I`m creating it in my method by forEach loop it looks like this:但是当我通过 forEach 循环在我的方法中创建它时,它看起来像这样:

So it does not append any thenComparing() keyExtractor to comparator所以它不是 append 任何 thenComparing() keyExtractor 到比较器

You are not storing the changes.您没有存储更改。 thenCompare doesn't modify the original comparator, but returns a new one. thenCompare不会修改原始的比较器,而是返回一个新的比较器。

for (var s : fields) {
    comparator = comparator.thenComparing(fieldToFieldExtractor.get(s)));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM