为流顺序传递方法引用

问题描述

我有一个处理器类,它接受在流上运行的任意谓词,以及一个用于排序的字段。我的处理器类:

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,Object> extractor) {
        this.name = name;
        this.extractor = extractor;
    }

    public Function<Transaction,Object> getExtractor() {
        return extractor;
    }
}

我无法让它工作并且转换到比较器也失败。解决方案不一定是比较器,只要它排序即可。有大佬知道怎么解决吗?

解决方法

FunctionComparator#comparing 参数的通用约束是 <T,U extends Comparable<? super U>>,这意味着该函数必须返回扩展 Comparable<…> 的内容。将您的函数从 Function<Transaction,Object> 更改为 Function<Transaction,Comparable<…>>,您应该可以执行 .sorted(Comparator.comparing(order))

唯一的要求是您的 Transaction#getCategory 方法返回的是 Comparable(字符串、数字、实现 Comparable<YourType> 的自定义类型)。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...