使用通配符类型减少流

2023-12-14

我正在尝试Stream.reduce(),并且遇到了类型系统的障碍。这是一个玩具示例:

public static Number reduceNum1(List<Number> nums) {
  return nums.stream().reduce(0, (a, b) -> a);
}

这适用于任何List<Number>,但是如果我希望能够减少一个列表,该怎么办? extends Number?这不能编译:

public static Number reduceNum2(List<? extends Number> nums) {
    return nums.stream().reduce((Number)0, (a, b) -> a);
}

出现错误:

ReduceTest.java:72: error: no suitable method found for reduce(Number,(a,b)->a)
        return nums.stream().reduce((Number)0, (a, b) -> a);
                            ^
    method Stream.reduce(CAP#1,BinaryOperator<CAP#1>) is not applicable
      (argument mismatch; Number cannot be converted to CAP#1)
    method Stream.<U>reduce(U,BiFunction<U,? super CAP#1,U>,BinaryOperator<U>) is not applicable
      (cannot infer type-variable(s) U
        (actual and formal argument lists differ in length))
  where U,T are type-variables:
    U extends Object declared in method <U>reduce(U,BiFunction<U,? super T,U>,BinaryOperator<U>)
    T extends Object declared in interface Stream
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Number from capture of ? extends Number
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output

从概念上讲,我明白为什么会发生这种情况。Stream.reduce()必须返回与源元素类型相同的内容,并且? extends Number不等于Number。但我不确定如何处理这个案子。我如何允许子类的集合(例如List<Integer>)减少(或收集)?


如果有帮助的话,这里有一个更实际的例子,同样无法编译:

public static <E> Set<E> reduceSet1(List<? extends Set<E>> sets) {
  return sets.stream().reduce(ImmutableSet.<E>of(), (a, b) -> Sets.union(a, b));
}

问题实际上并不在于? extends,但随着identity参数为reduce()。正如 Sotirios Delimanolis 建议的那样,您可以指定有界类型N extends Number,但前提是身份值为null.

public static <N extends Number> N reduceNum3(List<N> nums) {
  return nums.stream().reduce(null, (a, b) -> a);
}

这是因为通配符和有界方法都无法确定标识参数是否与列表元素的类型相同(除非它是null,所有类型共享)。

解决方法是使用三参数reduce()方法,它允许您将结果视为不同的类型(即使它不是really).

这是Number例子:

public static Number reduceNum4(List<? extends Number> nums) {
  return nums.stream().reduce((Number)0,
    (a, b) -> a,
    (a, b) -> a);
}

这是Set例子:

public static <E> Set<E> reduceSet2(List<? extends Set<E>> sets) {
  return sets.stream().<Set<E>>reduce(
      ImmutableSet.<E>of(), Sets::union, Sets::union);
}

有点烦人的是,你必须重复减少功能,因为accumulatorcombiner是不同的类型。您大概可以在变量中定义一次,然后通过不安全的强制转换将其传递给两者,但我不太确定这是一种改进。无论如何,使用方法引用可能是正确的方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用通配符类型减少流 的相关文章

  • jvm中本机代码如何转换为机器代码[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我读过一些文章说 jvm将字节码转换为机器码 jvm将字节码转换为本机代码 jvm 将字节码转换为系统调用 系统调用又由操作系统与硬件
  • Java中的文字赋值[重复]

    这个问题在这里已经有答案了 定义上有什么区别 double example 23 1d or double example 23 1 为什么long float double可以以l f d结尾 之间没有区别double example 2
  • Spring boot 2.0.5.RELEASE和mongo 4.0连接问题

    我正在关注使用 MongoDB 访问数据教程春季网站 https spring io guides gs accessing data mongodb 我将 Mongo DB 服务器版本 4 安装为服务当我使用客户端连接到它时 它的身份验证
  • jpa2 CriteriaBuilder order by “ORDER BY 表达式必须出现在选择列表中”

    我正在写一个查询标准生成器 但无法添加order by子句 因为它随消息一起抛出错误ORDER BY 表达式必须出现在选择列表中这是我的实体 public class A Integer aId ManyToOne JoinColumn n
  • Active MQ - HelloWorld 示例异常

    我正在尝试运行 hello world 示例在这里找到 http activemq apache org hello world html I added activemq all 5 5 1 jar已经到图书馆了 它构建成功 但出现以下警
  • EL 通过 Scriptlet

    在 JSP 中使用 EL 相对于 scriptlet 的优势是什么 EL 被认为是无脚本语言 EL 使 JSP 免受容易出错原始 Java 代码并强制您根据 MVC 思想编写 JSP EL 或像 JSTL 这样的标签库 不可能实现的任何事情
  • MediaPlayer.create() 始终返回 null

    我以前用过媒体播放器 从来没有遇到过这个问题 每当我尝试使用 MediaPlayer create 时 该方法都会给我 null 并且我无法播放声音 我有什么遗漏的吗 public class Game extends Activity p
  • 在java中将DataURL图像转换为图像文件

    我在我的 java servlet 中接收图像 DataURL 它看起来像 data image jpeg base64 9j 4AAQSkZJRgABAQAAAQABAA 我需要将其另存为图像文件 我该怎么做 The simplest w
  • net.sf.jasperreports.engine.JRRuntimeException:java.io.IOException:无法读取字体数据

    我正在尝试通过 JasperReport 创建 PDF 报告 但读取字体数据时出现问题 我有 jasperreports extension properties 和 ClassPath 中的相关 TTF 文件 这是错误 java io I
  • spring mvc 跟踪引用页面

    在基于注释的弹簧控制器中 如果用户正在url com first page并点击一个链接或提交一份表格指出url com second page 如何制作second page知道url of first page所以这样second pa
  • vm 参数中的 -D 是什么,它表示为什么我们必须在 vm 参数中始终指定 -D

    vm 参数中的 D 是什么 它表示为什么我们必须在 vm 参数中始终指定 D 有什么标准吗 如果是 那是什么以及指定的位置 D 设置当前运行的 java 程序可以访问的属性值 它允许程序员设置程序运行所需的值 但程序不知道这些值是什么 因此
  • 无法自动装配 org.springframework.mail.javamail.JavaMailSender

    尝试运行我的应用程序时遇到以下问题 所有的东西都调试过了 还是一无所获 IDE 毫无问题地找到了 bean 所以我对这里发生的情况感到非常困惑 SEVERE Exception sending context initialized eve
  • 使用 Box2d(适用于 Android)进行碰撞检测?

    有人可以解释一下使用 box2d for android 进行碰撞检测的工作原理吗 我无法理解 BBContactListener 以什么方式工作 BBContactListener listener new BBContactListen
  • 获取包中声明的所有 Java 类的名称

    我正在编写一个功能 它将有助于将类放入我的程序的某个包中 另外 我只想要子类某个类的类 我需要这些类才能调用它们的静态方法 有没有一种自动的方法来做到这一点 如果是的话 速度慢吗 如果我不清楚 我想要的是这样的 ArrayList
  • 如何在Java中模拟引用传递?

    我是一个十足的 Java 菜鸟 我知道 Java 将所有参数视为按值传递 并且还有其他几个线程人们对此进行了解释 例如 在 C 中我可以这样做 void makeAThree int n n 3 int main int myInt 4 m
  • Java 验证日期为 yyyyMMddHHmmss

    我想在java中验证给定的日期格式为yyyyMMddHHmmss 状况 应符合格式 yyyyMMddHHmmss 它应该验证当前日期 它应该验证与当前小时有 3 小时或 3 小时差异的小时数 如果满足所有三个条件 Java 方法应返回 tr
  • Jetty 9 + Java > 8u74 总是在 Linux 上分配最大(-Xmx)内存?

    如果我使用 Xmx512m 在 Linux 上使用 jre 8u74 启动 Java 应用程序 则不会立即分配内存 如果 Java 需要内存 则会分配内存 因此 如果没有必要 它可以保持在 512 MB 限制以下 这是我所期望的 在 Jav
  • 使用正则表达式匹配阿拉伯文文本

    我试图使用正则表达式仅匹配阿拉伯语文本 但出现异常 这是我的代码 txt matches P Arabic 这是例外情况 线程 main 中的异常 java util regex PatternSyntaxException 索引 9 附近
  • 在没有EOF的情况下停止读取java中的输入

    In 问题 如何停止读取输入 我的程序继续运行 要求更多输入 public static void main String args throws Exception BufferedReader br new BufferedReader
  • Java 可变 BigInteger 类

    我正在使用 BigIntegers 进行计算 该计算使用一个调用 multiply 大约 1000 亿次的循环 并且从 BigInteger 创建新对象使其非常慢 我希望有人编写或找到了 MutableBigInteger 类 我在 jav

随机推荐