I am quite new to Java streams and I am trying to implement a method using the streams but when I try to return the value it's throwing me the error Unexpected return value. I just wanted to know what am I doing wrong.
Following is the return within the Arrays.stream value which is throwing the error:
Object[] result = extensionBuilder((Map) extension.getValue());
Arrays.stream(result).forEach(innerExtension -> {
return new JAXBElement<JAXBElement>(new QName(getCleanLabel(extension.getKey())), JAXBElement.class, (JAXBElement) innerExtension);
});
However, if I try to return a single value outside the Arrays.stream then I am able to get the first value. (As you can see I am returning the first value only 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]);
I want to pass the values from the Object[] result one by one and return the result to my calling method.
Here is the complete method that I have:
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);
}
Here is the input given to the method:
{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}
I am a bit confused about this for a long time now. Can someone please assist me with how to accomplish the returning concept using the stream?
Basically, I would like to return the value for every element within the Object[] result as of now I am able to do it only for one element but I want for each object present within the Object[] result
***** EDITED ON 11 May ******
Based on the response to the question I am able to do it but the response I am getting looks something like this:
<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>
Whereas I am looking for something like this:
<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>
This is due the stream which is returning the JAXBElement for every element within the Object[] result I would like to return the result after completing the looping the child stream something like this:
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();
}
I tried this but this is throwing me the error java.lang.ClassCastException: class java.util.ArrayList cannot be cast to class javax.xml.bind.JAXBElement.
Can someone please assist me on how to modify the Java Stream so that I can have the expected output?