Reputation: 23
I want to use lambda and streams on a complex nested object and want to compare the dates. can someone help how can I do it using lambda expression
From below object I want to filter out all asset item ids with ownership start date < employee joining date and want to put all those ids to an Array List
The code I have so far gives me all the asset item ids , I dont know how to use filter to compare item.ownership.startDate with emp.joiningDate
{
"transactionDate": "",
"employees": [
{
"joiningDate": "2018-06-12T07:13:48.504Z",
"assets": [
{
"assetItem": [
{
"id": "1",
"ownership": {
"startDate": "2017-06-12T07:13:48.506Z",
"endDate": "2017-06-12T07:13:48.506Z"
}
}
]
},
{
"assetItem": [
{
"id": "2",
"ownership": {
"startDate": "2018-06-12T07:13:48.506Z",
"endDate": "2018-06-12T07:13:48.506Z"
}
}
]
},
{
"assetItem": [
{
"id": "3",
"ownership": {
"startDate": "2017-06-12T07:13:48.506Z",
"endDate": "2017-06-12T07:13:48.506Z"
}
}
]
}
]
}
]
}
Below is the code I have which I want to modify
List<String> assetList = object.getEmployees().stream().
flatMap(emp -> emp.getAssets().stream()).
flatMap(asset -> asset.getAssetItem().stream()).
map(item -> item.getId()).collect(Collectors.toList());
The expectation is to have only asset item id 2 in the list.
Upvotes: 2
Views: 1557
Reputation: 31868
A mixed approach with a for
loop iteration of the collection of Employee
s and streaming over the assets per employee and then filter
ing and map
ping based on the condition and to item ids respectively.
List<String> assetItemIds = new ArrayList<>();
for (Employee employee : employees) {
assetItemIds.addAll(employee.getAssets().stream()
.flatMap(asset -> asset.getAssetItem().stream())
.filter(assetItem -> assetItem.getOwnerShip().getStartDate() >= employee.getJoiningDate())
.map(AssetItem::getId)
.collect(Collectors.toList()));
}
Though a little complex structure of converting this into a single stream operation would be to create an entry of Employee
and the AssetItem
stream with the filter operation being the trick and then mapping the values accordingly. This could be achieved as follows:
List<String> assetItemIds = employees.stream()
.map(emp -> new AbstractMap.SimpleEntry<>(emp,
emp.getAssets().stream()
.flatMap(asset -> asset.getAssetItem().stream())
.filter(assetItem -> assetItem.getOwnerShip().getStartDate() >= emp.getJoiningDate())))
.flatMap(e -> e.getValue().map(AssetItem::getId))
.collect(Collectors.toList());
Upvotes: 1