我正在尝试编写一个方法来使用 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
而不是 reduce
和 Map.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/