Mar*_*tin 6 java generics lambda junit hamcrest
我有以下功能:
private Person findMax(List<Person> persons,
Function<Person, ? extends Comparable> compare) {
return persons.stream().max(Comparator.comparing(compare)).get();
}
Run Code Online (Sandbox Code Playgroud)
我可以称之为:
Person result = findMax(people, person -> person.getAge());
Run Code Online (Sandbox Code Playgroud)
要么:
Person result = findMax(people, person -> person.getName());
Run Code Online (Sandbox Code Playgroud)
只要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();
}
Run Code Online (Sandbox Code Playgroud)
现在,当我尝试使用JUnit和Hamcrest测试该函数时:
这一行编译(使用旧的JUnit Assert模式):
assertEquals(silvester, findMax(input, person -> person.getName()));
Run Code Online (Sandbox Code Playgroud)
但是,这个不编译(类型不匹配:无法从Integer转换为Comparable>):
assertThat(findMax(input, person -> person.getAge()), equalTo(arnold));
Run Code Online (Sandbox Code Playgroud)
但是,如果我提取断言的第一个参数,它构建良好:
Person result = findMax(input, person -> person.getAge());
assertThat(result, equalTo(arnold));
Run Code Online (Sandbox Code Playgroud)
这种表示法也很好:
assertThat(findMax(input, Person::getAge), equalTo(arnold));
Run Code Online (Sandbox Code Playgroud)
这是Hamcrest,Java8还是Eclipse中的错误?或者我错过了什么?