У меня есть класс процессора, который принимает произвольные предикаты для запуска в потоках, а также поле для сортировки. Мой класс процессора:
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
?