Reputation: 3254
I'm using an 3rd party library where there are two very similar classes that don't implement an interface. The code currently loops through a list of items to find the first occurrence of an object using one of these classes and then converts it to a stream where it is processed. It would be nice if I could convert this code to use a stream and have it chained to the rest of my code.
for (Component3Choice component: components) {
if (component instanceof OptionalComponent3Bean) {
OptionalComponent3Bean section = (OptionalComponent3Bean) component;
entryStream = section.getSection().getEntry().stream()
break;
}
else if (component instanceof RequiredComponent3Bean) {
RequiredComponent3Bean section = (RequiredComponent3Bean) component;
entryStream = section.getSection().getEntry().stream();
break;
}
}
... do something with the stream ...
components.stream()
.filter(entry -> entry instanceof OptionalComponent3Bean
|| entry instanceof RequiredComponent3Bean)
.findFirst()
.map( {{ cast entry }} )
.map( castedEntry.getSection().getEntry())
... continue on with my processing
Is it possible cast the entry based on the previous filter in the stream?
Upvotes: 0
Views: 2406
Reputation: 3230
No, nothing can save you from bad design, which is what it seems you're fighting against.
You can force a common interface by means of a wrapper, if you need to replicate boilerplate similar to this one in many places. Otherwise, I guess the best you can do is
static private IDontKnow getStream(Component3Choice c3c) {
if (c3c instanceof OptionalComponent3Bean) {
return ((OptionalComponent3Bean)c3c).getStream();
} else if (c3c instanceof RequiredComponent3Bean) {
return ((RequiredComponent3Bean)c3c).getStream();
} else {
return null;
}
}
components.stream()
.map(x -> getStream(x))
.filter(x -> x!=null)
.findFirst()
.map(x -> x.getEntry().stream());
... continue on with yout processing
Upvotes: 3
Reputation: 393831
Not the prettiest code, but you could do :
components.stream()
.filter(entry -> entry instanceof OptionalComponent3Bean
|| entry instanceof RequiredComponent3Bean)
.map(entry -> {
if ((entry instanceof OptionalComponent3Bean)
return ((OptionalComponent3Bean) entry).getSection().getEntry().stream();
else
return ((RequiredComponent3Bean) entry).getSection().getEntry().stream();
})
.findFirst();
This would return an Optional<Stream<Something>>
.
Note that findFirst
must be the last operation, since it's terminal.
Upvotes: 1