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

Posted

技术标签:

【中文标题】在 Java 中传递函数时如何定义方法签名 - 带有 Hamcrest 的 JUNIT 失败【英文标题】:How to define Method signature when passing a Function in Java - JUNIT with Hamcrest Fails 【发布时间】:2015-05-08 00:36:31 【问题描述】:

我有以下功能:

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 是原始类型。对泛型 Comparable 的引用应该被参数化

但是,我无法将 Comparator 修复为任何东西,因为它取决于我作为参数传递的函数...

我尝试像这样修改方法:

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()));

但是,这个不编译(类型不匹配:无法从整数转换为可比较>):

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 中的错误吗?还是我错过了什么?

【问题讨论】:

警告是什么? Comparable 是原始类型。对泛型类型 Comparable 的引用应该被参数化。我将问题编辑得更具体,但是代码可以直接粘贴到 java8 IDE 中。 两个版本都没有收到任何警告 @JavierMollá,您使用的是什么 IDE?我收到 Eclipse Luna 的警告... 我也在使用 Eclipse Luna、Java 8、Mac OS 10.10.2 【参考方案1】:

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

【讨论】:

以上是关于在 Java 中传递函数时如何定义方法签名 - 带有 Hamcrest 的 JUNIT 失败的主要内容,如果未能解决你的问题,请参考以下文章

参数传递:shell脚本调用一个带参数的python函数

深入理解Java中方法的参数传递机制

java中怎么用jsp调用已有的接口,加密拼接参数

我们如何在 Cassandra“用户定义函数”中传递一个常量值?

Promise:如何传递带参数的函数? [复制]

shell 自定义带参数函数