如何在Java中传递函数时定义方法签名 - 使用Hamcrest的JUNIT失败

时间:2015-03-06 11:54:22

标签: java generics junit lambda hamcrest

我有以下功能:

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 Assert模式):

assertEquals(silvester, findMax(input, person -> person.getName()));

但是,这个不编译(类型不匹配:无法从Integer转换为Comparable&gt;):

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中的错误?或者我错过了什么?

1 个答案:

答案 0 :(得分:0)

确保您的项目结构(对于intellij的IDE)设置为允许lambda表达式。文件&gt;项目结构&gt;下拉菜单,了解语法的高级程度。