use of lambda and streams on nested object

R_Jain :

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.

Naman :

A mixed approach with a for loop iteration of the collection of Employees and streaming over the assets per employee and then filtering and mapping 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());

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=135140&siteId=1