Issue
Below is my working code set of nested forEach
. Looking for the best alternate to make code clean. Looks to be a very complex set of code
This Model1
is a List
containing various SubList
and other few elements
List<Model1> listModel1 = getDataForModel1(......);
listModel1.getSubList1().forEach(dataSubList1 -> {
dataSubList1.getChildSublList2().forEach(dataChildSubList2 -> {
dataChildSubList2.getChildSubList3().forEach(dataChildSubList3 -> {
if (dataChildSubList3.getIsValid()) {
// Setting my required data in this dataChildSubList3 all properties
}
})
})
})
The above code is working as expected but Looking for an alternate to forEach
. Thus making the above code less complex. Thanks in advance
Solution
This answer should be seen as a sketch. Since the code does not explicitly define the return types, the code might not work 1:1.
In the following, I assume that:
listModel1.getSubList1()
returns aList<Data1>
,dataSubList1.getChildSublList2()
returns aList<Data2>
, anddataSubList2.getChildSublList3()
returns aList<Data3>
.
If we use Java 8+, we can utilize the stream
API:
List<Model1> listModel1 = getDataForModel1(......);
listModel1.getSubList1().stream()
// 1st block replaces 1st foreach:
.filter(Objects::nonNull) // remove nulls, just to be safe
.map(Data1::getChildSublList2) // transform each Data1-object to its list of
// Data2-objects
.flatMap(List::stream) // flatten: transform each list in a stream of its
// elements
// 2nd block replaces 2nd foreach:
.filter(Objects::nonNull) // remove nulls, just to be safe
.map(Data2::getChildSublList3) // transform each Data2-object to its list of
// Data3-objects
.flatMap(List::stream) // flatten: transform each list in a stream of its
// elements
// 3rd block replaces 3rd foreach:
.filter(Objects::nonNull) // remove nulls, just to be safe
.filter(Data3::getIsValid) // move if-condition to here
.forEach(dataChildSubList3 -> {
// Setting my required data in this dataChildSubList3 all properties
});
It would be even better if we move the lambda-body of the forEach
-lambda in a separate method (e.g. named foo
) that takes a Data3
as parameter and does the processing, this would simplify the forEach(...)
to:
listModel1.getSubList1().stream()
...
.forEach(this::foo);
Answered By - Turing85
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.