Создать компаратор, используя карту ссылок на методы получения - PullRequest
1 голос
/ 18 июня 2020

Я попытался создать компаратор на основе полей объекта, которые имеют ненулевые значения, используя Comparator.compare, а затем связать его с Comparator.thenCompare. У меня есть HashMap, который хранит поле в качестве ключа и ссылку на метод получения в качестве значения.

Вот мой список полей:

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

Каждое из этих полей связано с некоторым полем в Bike объект.

Следующая остановка - моя 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);

И, наконец, мой метод:

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

Моя идея - перейти к уже отфильтрованному методу Set<BikePropery>, выполните итерацию этого и цепного методов компаратора.

Например, для данного набора Set.of(BikeProperty.PRICE,BikeProperty.IS_LIGHT_AVAILABLE), сгенерируйте следующий компаратор: Comparator.compare(Bike::getBrand).thenCompare(Bike::getPrice).thenCompare(Bike::isLightAvailable)

Проблема: Созданный компаратор имеет только одно сравнение по умолчанию Bike::getBrand(). Поэтому у меня возник вопрос, а можно ли вообще это сделать, и если есть возможность, дайте совет. Спасибо!

Обновление

Когда я создаю компаратор (например) из своего основного метода, он выглядит так: enter image description here

enter image description here

Но когда я создаю его в своем методе с помощью forEach l oop, это выглядит так:

Таким образом, он не добавляет никакой thenComparing () keyExtractor к компаратору

1 Ответ

1 голос
/ 18 июня 2020

Вы не сохраняете изменения. thenCompare не изменяет исходный компаратор, а возвращает новый.

for (var s : fields) {
    comparator = comparator.thenComparing(fieldToFieldExtractor.get(s)));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...