简体   繁体   中英

use of lambda and streams on nested object

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.

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());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM