2

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.

1 Answer 1

1

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());
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much @Naman , let me try this. I will get back with the results !
@R_Jain I have question. what is this called"AssetItem::getId"inside map. and also if I have another object inside getId say getRealId so how will I write it? AssetItem::getId::getRealId??

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.