java - 如何使用流编写模式方法

标签 java generics java-8 java-stream

我正在尝试编写一个方法来使用 Comparator 获取 Collection 的模式。

有人可以告诉我我必须做哪些更改才能编译吗?我不想更改签名。

static <T> T mode(Collection<? extends T> collection, Comparator<? super T> comparator) {
    return collection.stream()
                     .collect(Collectors.groupingBy(t -> t, () -> new TreeMap<>(comparator), Collectors.counting()))
                     .entrySet()
                     .stream()
                     .reduce(BinaryOperator.maxBy(Comparator.comparingLong(Map.Entry::getValue)))
                     .map(Map.Entry::getKey)
                     .orElseThrow(IllegalArgumentException::new);
}

编辑

事实证明我只是使用了错误的版本。这不会使用 javac 1.8.0_25 进行编译。确切的三个错误消息是:

Error:(40, 47) java: incompatible types: inferred type does not conform to upper bound(s)
inferred: java.lang.Object
upper bound(s): T,java.lang.Object

Error:(43, 45) java: incompatible types: cannot infer type-variable(s) T
(argument mismatch; invalid method reference
  method getValue in interface java.util.Map.Entry<K,V> cannot be applied to given types
    required: no arguments
    found: java.lang.Object
    reason: actual and formal argument lists differ in length)

Error:(44, 25) java: invalid method reference
non-static method getKey() cannot be referenced from a static context

但是,我已经升级到 javac 1.8.0_65 并且它可以完美编译。

最佳答案

此代码无法使用 Java 8u40 之前的 javac 进行编译。如果你仍然想让它与旧的 javac 版本兼容,你可以像这样引入另一个通用变量:

static <T> T mode(Collection<? extends T> collection, Comparator<? super T> comparator) {
    return mode0(collection, comparator);
}

private static <T, TT extends T> T mode0(Collection<TT> collection,
                                         Comparator<? super T> comparator) {
    return collection.stream()
                     .collect(Collectors.groupingBy(t -> t, 
                                  () -> new TreeMap<>(comparator), 
                                  Collectors.counting()))
                     .entrySet()
                     .stream()
                     .reduce(BinaryOperator.maxBy(
                                  Comparator.comparingLong(Map.Entry::getValue)))
                     .map(Map.Entry::getKey)
                     .orElseThrow(IllegalArgumentException::new);
}

顺便说一下,您可以使用 Stream.max 而不是 reduceMap.Entry.comparingByValue() 比较器:

private static <T, TT extends T> T mode0(Collection<TT> collection,
                                         Comparator<? super T> comparator) {
    return collection.stream()
                     .collect(Collectors.groupingBy(t -> t, 
                                  () -> new TreeMap<>(comparator), 
                                  Collectors.counting()))
                     .entrySet()
                     .stream()
                     .max(Map.Entry.comparingByValue())
                     .map(Map.Entry::getKey)
                     .orElseThrow(IllegalArgumentException::new);
}

关于java - 如何使用流编写模式方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33979137/

相关文章:

java - 数组列表中的泛型错误

go - 是否有可能在 Golang 中制作类型泛型(模板)函数

java - 使用 lambda 进行代码重构 - Java 8

java - Spring Data REST (2.4.4.RELEASE) 和 CORS

java - 使用 java 8 在文件名和扩展名之间添加中缀

java - 是否可以在不使用 Selenium Webdriver Java 中的 driver.switchTo().frame ("frameName"的情况下切换到框架中的元素?

java - 如何在 JSP <c :if> condition 中使用 java 代码

java - 优化欧拉项目 #22

java - Eclipse不会在Liferay maven项目中生成父主题文件

依赖于某些参数的 Java 类