Java Streams 返回抛出错误 意外的返回值

标签 java arrays java-8 return java-stream

我对 Java 流很陌生,我正在尝试使用流来实现一个方法,但是当我尝试返回值时,它向我抛出错误 Unexpected return value。我只是想知道我做错了什么。

以下是引发错误的 Arrays.stream 值中的返回:

Object[] result = extensionBuilder((Map) extension.getValue());
Arrays.stream(result).forEach(innerExtension -> {
    return new JAXBElement<JAXBElement>(new QName(getCleanLabel(extension.getKey())), JAXBElement.class, (JAXBElement) innerExtension);
});

但是,如果我尝试返回 Arrays.stream 之外的单个值,那么我可以获得第一个值。 (如您所见,我只返回第一个值 result[0])

Object[] result = extensionBuilder((Map) extension.getValue());
Arrays.stream(result).forEach(innerExtension -> {
    System.out.println((JAXBElement) innerExtension);
});
return new JAXBElement<JAXBElement>(new QName(getCleanLabel(extension.getKey())), JAXBElement.class, (JAXBElement) result[0]);

我想将 Object[] 结果 中的值一个一个地传递,并将结果返回给我的调用方法。

这是我拥有的完整方法:

  private Object[] extensionBuilder(Map<String, Object> extensions) {
    if (extensions == null) {
      return null;
    }
    return extensions.entrySet().stream().map(extension -> {
      if (extension.getValue() instanceof Map) {

        // return new JAXBElement<JAXBElement>(new QName(getCleanLabel(extension.getKey())), JAXBElement.class,
        //    (JAXBElement) extensionBuilder((Map) extension.getValue())[0]);

        Object[] result = extensionBuilder((Map) extension.getValue());
        Arrays.stream(result).forEach(innerExtension -> {
          System.out.println((JAXBElement) innerExtension);
        });
        return new JAXBElement<JAXBElement>(new QName(getCleanLabel(extension.getKey())), JAXBElement.class, (JAXBElement) result[0]);

      } else {
        return new JAXBElement<String>(new QName(getCleanLabel(extension.getKey())), String.class, extension.getValue().toString());
      }
    }).filter(Objects::nonNull).collect(Collectors.toList()).toArray(Object[]::new);
  }

这里是给方法的输入:

{nameSpace:MyField-2={fb:My-Sub-Field-1={nameSpace:MyField-1=myValue, nameSpace:MyField-2=myValue, nameSpace:MyField-3=myValue}, nameSpace2:My-Sub-Field-2={nameSpace:MyField-4=myValue4, nameSpace:MyField-5=myValue5, nameSpace:MyField-6=myValue6}, nameSpace:MyField-7MyField-3=myValue1}, nameSpace:MyField-8=Name}

我很长一段时间都对这个问题感到困惑。有人可以帮助我如何使用流来完成返回概念吗?

基本上,我想返回 Object[] 结果 中每个元素的值,到目前为止,我只能对一个元素执行此操作,但我希望对存在于对象[]结果

***** 编辑于 5 月 11 日 ******

根据对问题的回答,我能够做到,但我得到的回答看起来像这样:

<namespace:MainField>
    <namespace:SubField1>
        <namespace:Field1>Value1</namespace:Field1>
    </namespace:SubField1>
</namespace:MainField>
<namespace:MainField>
    <insta:SubField2>
        <insta:Field2>Value2</insta:Field2>
    </insta:SubField2>
</namespace:MainField>
<namespace:MainField>
    <namespace:SubField3>SubValue3</namespace:SubField3>
</namespace:MainField>
<namespace:MainField2>MainValue2</namespace:MainField2>
<namespace:MainField3>MainValue3</namespace:MainField3>

而我正在寻找这样的东西:

<namespace:MainField>
    <namespace:SubField1>
        <namespace:Field1>Value1</namespace:Field1>
    </namespace:SubField1>
    <insta:SubField2>
        <insta:Field2>Value2</insta:Field2>
    </insta:SubField2>
    <namespace:SubField3>SubValue3</namespace:SubField3>
</namespace:MainField>
<namespace:MainField2>MainValue2</namespace:MainField2>
<namespace:MainField3>MainValue3</namespace:MainField3>

这是由于 streamObject[] result 中的每个元素返回 JAXBElement 我想返回结果完成子流的循环后是这样的:

  private Object[] extensionBuilder(Map<String, Object> extensions) {
    if (extensions == null) {
      return null;
    }
    return extensions.entrySet().stream().flatMap(extension -> {
      if (extension.getValue() instanceof Map) {
        // return Stream of result transformed to JAXBElements
        return Arrays.stream(extensionBuilder((Map) extension.getValue())).map(innerExtension -> {
          System.out.println(innerExtension);
          return new JAXBElement<JAXBElement>(new QName(getCleanLabel(extension.getKey())), JAXBElement.class, (JAXBElement) innerExtension);
        });
      } else {
        return Stream.of(new JAXBElement<String>(new QName(getCleanLabel(extension.getKey())), String.class, extension.getValue().toString()));
      }
    }).filter(Objects::nonNull).collect(Collectors.toList()).toArray();
  }

我试过了,但这会抛出错误 java.lang.ClassCastException: class java.util.ArrayList cannot be cast to class javax.xml.bind.JAXBElement

有人可以帮助我修改 Java Stream 以便我可以获得预期的输出吗?

最佳答案

您正在尝试从传递给 forEach 的 lambda 返回一些值.该 lambda 类型是 Consumer<T>及其方法accept返回类型是 void所以你不能从它返回任何值。

如果你想从你的方法中返回对象集合,我建议重写它以返回 Stream :

  private Object[] extensionBuilder(Map<String, Object> extensions) {
    if (extensions == null) {
      return null;
    }
    //                        use flatMap vvvvvvv instead of map
    return extensions.entrySet().stream().flatMap(extension -> {
      if (extension.getValue() instanceof Map) {
        Object[] result = extensionBuilder((Map) extension.getValue());
        // return Stream of result transformed to JAXBElements
        return Arrays.stream(result).map(innerExtension -> {
          return new JAXBElement<JAXBElement>(new QName(getCleanLabel(extension.getKey())), JAXBElement.class, (JAXBElement) result[0]);
        });
      } else {
        // return Stream of single item
        return Stream.of(
          new JAXBElement<String>(new QName(getCleanLabel(extension.getKey())), String.class, extension.getValue().toString())
        );
      }
    }).filter(Objects::nonNull).collect(Collectors.toList()).toArray();
  }

参见 Stream::flatMap文档。


不用result也可以交易变量,如果你只是内联它:

  private Object[] extensionBuilder(Map<String, Object> extensions) {
    if (extensions == null) {
      return null;
    }

    return extensions.entrySet().stream().flatMap(extension -> {
      if (extension.getValue() instanceof Map) {
        // return Stream of result transformed to JAXBElements
        return Arrays.stream(extensionBuilder((Map) extension.getValue()))
          .map(innerExtension -> new JAXBElement<JAXBElement>(
             new QName(getCleanLabel(extension.getKey())),
             JAXBElement.class,
             (JAXBElement) result[0]
          ));
      } else {
        return Stream.of(
          new JAXBElement<String>(new QName(getCleanLabel(extension.getKey())), String.class, extension.getValue().toString())
        );
      }
    }).filter(Objects::nonNull).collect(Collectors.toList()).toArray();
  }

但是要小心,最好想出一个更好的名字 对于这个变量,不仅仅是内联它, 因为它缺乏可读性(恕我直言)。

关于Java Streams 返回抛出错误 意外的返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67428793/

相关文章:

java - 为什么使用 DataOutputStream 将消息写入客户端套接字到服务器套接字仅在关闭客户端套接字后发送?

java - 关于 isConnectingOrConnecting 的替代编码?

objective-c - 声明二维数组大小的常量

java - 使用流计算无穷和

java - 如何以编程方式从线程外部启动 EJB 计时器

java - 在 Mac 上使用 JBDC 对 SQL Server 进行 Windows 身份验证

PHP 扫描目录和数组

java - 在 Java 中无需硬编码即可定义数组大小

java - 将逗号分隔的数字列表压缩到范围内

java - Android 库不适用于 Java 8