我对 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>
这是由于 stream
为 Object[] 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/