我有以下功能:

private Person findMax(List<Person> persons,
        Function<Person, ? extends Comparable> compare) {
    return persons.stream().max(Comparator.comparing(compare)).get();
}

我可以称其为:
Person result = findMax(people, person -> person.getAge());

或者:
Person result = findMax(people, person -> person.getName());

只要Person的属性为Comparable即可使用,在这种情况下,该属性适用于Integer和String。但是,此架构会生成警告,这是错误代码的味道:

可比是原始类型。泛型类型Comparable的引用应参数化

但是,我无法将比较器固定为任何东西,因为它取决于我作为参数传递的函数...

我试过像这样修改方法:
private <T extends Comparable<T>> Person findMax(List<Person> persons,
        Function<Person, T> compare) {
    return persons.stream().max(Comparator.comparing(compare)).get();
}

现在,当我尝试使用JUnit和Hamcrest测试该功能时:

这行代码进行编译(使用旧的JUnit声明模式):
assertEquals(silvester, findMax(input, person -> person.getName()));

但是,此代码无法编译(类型不匹配:无法从Integer转换为Comparable>):
assertThat(findMax(input, person -> person.getAge()), equalTo(arnold));

但是,如果我提取断言的第一个参数,它将很好地构建:
Person result = findMax(input, person -> person.getAge());
assertThat(result, equalTo(arnold));

这种表示法还可以很好地构建:
assertThat(findMax(input, Person::getAge), equalTo(arnold));

这是Hamcrest,Java8或Eclipse中的错误吗?还是我错过了什么?

最佳答案

确保您的项目结构(对于intellij的IDE)设置为允许使用lambda表达式。 "file">“项目结构”>“下拉菜单”,以了解语法的高级程度。

关于java - 在Java中传递函数时如何定义方法签名-具有Hamcrest的JUNIT失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28898232/

10-09 00:32