У меня есть класс процессора, который принимает произвольные предикаты для запуска в потоках, а также поле для сортировки. Мой класс процессора:
import com.example.vm.domain.Transaction;
import lombok.Builder;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@Builder
public class Processor {
private Collection<Predicate<Transaction>> predicates;
public List<Transaction> process(List<Transaction> transactions) {
return process(transactions, TransactionFields.CATEGORY.getExtractor());
}
public List<Transaction> process(List<Transaction> transactions, Function<Transaction, Object> order) {
if (predicates == null) {
return transactions;
}
if (order == null) {
return transactions.stream()
.parallel()
.filter(predicates.stream().reduce(p -> true, Predicate::and))
.collect(Collectors.toList());
} else {
return transactions.stream()
.parallel()
.filter(predicates.stream().reduce(p -> true, Predicate::and))
.sorted(Comparator.comparing(Transaction::getCategory))
.collect(Collectors.toList());
}
}
}
Это отлично работает, но я хочу, чтобы Comparator.comparing(Transaction::getCategory) был параметром, чтобы
.sorted(Comparator.comparing(Transaction::getCategory))
становится этим
.sorted(Comparator.comparing(order))
Перегруженный вызов:
process(transactions, TransactionFields.CATEGORY.getExtractor());
происходит из перечисления, чтобы вернуть поле экстрактора:
import com.example.vm.domain.Transaction;
import java.util.function.Function;
public enum TransactionFields {
CATEGORY("category", t -> t.getCategory());
private String name;
private Function<Transaction, Object> extractor;
private TransactionFields(String name, Function<Transaction, Object> extractor) {
this.name = name;
this.extractor = extractor;
}
public Function<Transaction, Object> getExtractor() {
return extractor;
}
}
Я не могу заставить это работать, и приведение к компаратору также не удается. Решение не обязательно должно быть компаратором, лишь бы оно сортировалось. Кто-нибудь знает, как это решить?




Общие ограничения параметра Function для Comparator#comparing равны <T,U extends Comparable<? super U>>, что означает, что функция должна возвращать что-то, что расширяет Comparable<…>. Измените свою функцию с Function<Transaction, Object> на Function<Transaction, Comparable<…>>, и вы сможете сделать .sorted(Comparator.comparing(order)).
Единственное требование состоит в том, чтобы ваш метод Transaction#getCategory возвращал что-то, что является Comparable (строка, число, пользовательский тип, который реализует Comparable<YourType>).
Угу... Не могу поверить, что пропустил это. Большое спасибо. Я пытался проголосовать, но моя репутация слишком низкая.
Какой тип имеет
Category? ЭтоComparable?