Devo essere in grado di ordinare un oggetto in base a più condizioni e questi tipi devono essere configurabili dal file application.properties (come in esso dovrebbe essere possibile specificare nel file gli ordinamenti da applicare e l'ordine).
Quindi nel mio design ho creato un comparatore per ciascuno di questi tipi, quindi un enumerato con un fornitore come:
public enum CarSort {
ENGINE(CarEngineComparator::new), BRAND(CarBrandComparator::new);
private final Supplier<Comparator<Car>> constructor;
CarSort(Supplier<Comparator<Car>> constructor){
this.constructor = constructor;
}
Comparator<Car> newComparator() {
return constructor.get();
}
}
Con questo design, sarei quindi in grado di caricare i tipi da un file delle proprietà:
myapp.cars.sorts=BRAND,ENGINE
E concatenati con qualcosa del tipo:
Stream<Comparator<Car>> comparators = sorts.stream().map(CarSort::newComparator);
return comparators
.reduce(Comparator::thenComparing)
.map(comparator -> filteredCars.sorted((comparator.reversed())))
.orElse(filteredCars)
.collect(Collectors.toList());
Il problema che ho al momento è che uno dei comparatori richiede due parametri, quindi non credo che questa soluzione regga più, ma al momento non riesco a pensare ad alternative pulite.
Sai se sarebbe possibile adattare il mio attuale design per soddisfare questo requisito o disporre di una soluzione alternativa valida?
EDIT: ho intenzione di aggiungere ulteriori dettagli. Diciamo che il comparatore specifico che ho bisogno di aggiungere tipi di auto in base ad esempio su quanto sono lontani dal client. Quindi potrebbe essere qualcosa del genere (i dettagli non sono importanti in realtà, solo il fatto che ha bisogno di un parametro aggiuntivo):
public class CarDistanceComparator implements Comparator<Car> {
private Location origin;
CarDistanceComparator(Location origin) {
this.origin = origin;
}
@Override
public int compare(Car o1, Car o2) {
double distanceToFirstCar = DistanceService.calculateDistance(origin, o1.getLocation());
double distanceToSecondCar = DistanceService.calculateDistance(origin, o2.getLocation());
return Double.compare(distanceToFirstCar, distanceToSecondCar);
}
}
Quindi quello che vorrei è essere in grado di ordinare per BRAND, ENGINE, DISTANCE (come specificato nel file di configurazione) per più clienti. Significa che dovrei passare ogni volta un argomento diverso a DistanceComparator.