How to convert the following nested forEach loop into functional code?
ABC abc = new ABC();
for (A a : aList) {
for (String b : bList) {
if (Objects.equals(a.getName(), b)) {
abc.setId(a.getId());
abc.setValue(a.getValue());
}
}
}
I've tried to convert it this way, but it didn't work:
aList.forEach(a -> {
bList.stream()
.filter(b -> Objects.equals(b, a.getName()));
abc.setId(a.getId());
abc.setValue(a.getValue());
});
CodePudding user response:
You can try
aList.forEach(a -> {
if( bList.stream()
.anyMatch(b -> Objects.equals(b, a.getName()))){
abc.setId(a.getId());
abc.setValue(a.getValue());
}
});
or better
aList.stream().filter(a -> bList.stream()
.anyMatch(b -> Objects.equals(b,a.getName())))
.findAny()
.ifPresent(a -> {
abc.setId(a.getId());
abc.setValue(a.getValue());
});
CodePudding user response:
Not sure what is considered a "functional code" and why that is needed here.
My approach, assuming bList
is a List<String>
:
var abc = aList
.stream()
.filter(this::isKnownName)
.map(this::abcFromA)
.findFirst() // see ¹ bellow
.orElseGet(ABC::new);
using the following helper functions - not really needed, we could use lambda expressions, but I think using this is a little bit more readable ² :
private boolean isKnownName(A a) {
return bList.contains(a.getName());
}
private ABC abcFromA(A a) {
var result = new ABC();
result.setId(a.getId());
result.setValue(a.getValue());
return result;
}
¹ this code is using the first match found in bList
, code in question is using the last match
² I would struggle between using this solution at all and using a single loop (with bList.contains()
instead of inner loop as posted in question).