处理对 java.lang.Number 的子类的操作的通用通用方法

Gau*_*m M 2 java generics java-stream

我有一个类MyGen,它接受两个通用参数并有一个方法getValue()

public interface MyGen<E,T> {

    T getValue();
}
Run Code Online (Sandbox Code Playgroud)

通常第二个泛型类型是Longor Integer

然后,当第二个泛型类型Long如下时,我写了一个方法来组合对象:

public static <E extends MyGen<?, Long>> long combineValue(Set<E> set) {
    return set.stream()
              .map(MyGen::getValue)
              .reduce(0L, (a,b) -> a | b);
}
Run Code Online (Sandbox Code Playgroud)

现在我想在第二种类型是Integer. 所以我尝试将上述相同的方法更新为:

public static <E extends MyGen<?, ? extends Number>> long combineValue(Set<E> set) {
    return (long) set.stream()
                     .map(MyGen::getValue)
                     .reduce((a,b) -> a | b) // error1
                     .orElse(0); // error2

}
Run Code Online (Sandbox Code Playgroud)

但显示以下错误:

  1. 错误1

运营商 | 未定义参数类型 capture#4-of ?扩展 java.lang.Number, capture#4-of ? 扩展 java.lang.Number

  1. 错误2

Optional<capture#4-of 类型中的方法 orElse(capture#4-of ? extends Number) extends Number> 不适用于参数 (int)

有没有办法用相同的方法来处理这两种情况LongInteger或者只能使用两种不同的方法来完成?

Swe*_*per 6

您似乎对这个常用方法的返回值是long. 在这种情况下,这是可能的,因为您可以longNumberusing获取 a longValue

public static long combineValue(Set<? extends MyGen<?, ? extends Number>> set) {
    return set.stream()
              .map(MyGen::getValue)
              .mapToLong(Number::longValue)
              .reduce(0L, (a,b) -> a | b);
}
Run Code Online (Sandbox Code Playgroud)

你基本上long是先把每个数字都变成s,然后再做归约。

  • 也可以使用单个 `.mapToLong(g -&gt; g.getValue().longValue())` 进行映射。或者一次执行所有操作: `set.stream().reduce(0L, (l, g) -&gt; l | g.getValue().longValue(), (a,b) -&gt; a | b)` (2认同)