简体   繁体   中英

using java8 stream i want to read the list element and store the value in another element of the same list based on conditional check

I have the below sample code. I want to read the values from the elements in the List and add in another element of the same List with conditional check.

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.*;

import java.util.ArrayList;
import java.util.List;

@Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties
class MyItems {
    private List<GroupItemInfo> groupItemInfos;

    @Getter
    @Setter
    @EqualsAndHashCode
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class Details {
        private String id;
        private String status;
    }

    @Getter
    @Setter
    @EqualsAndHashCode
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class GroupItemInfo {
        private String type;
        List<Details> items;
    }
}

public class ScreenTest {

    public static void main(String args[]) {
        List<MyItems.GroupItemInfo> itemInfoList = new ArrayList<>();
        MyItems.GroupItemInfo groupItemInfo1 = new MyItems.GroupItemInfo();
        groupItemInfo1.setType(null);
        groupItemInfo1.setItems(null);

        MyItems.GroupItemInfo groupItemInfo2 = new MyItems.GroupItemInfo();
        List<MyItems.Details> detailsList = new ArrayList<>();
        MyItems.Details details1 = new MyItems.Details();
        details1.setId("A");
        details1.setStatus("Active");
        MyItems.Details details2 = new MyItems.Details();
        details2.setId("B");
        details2.setStatus("Active");
        MyItems.Details details3 = new MyItems.Details();
        details3.setId("C");
        details3.setStatus("InActive");
        detailsList.add(details1);
        detailsList.add(details2);
        detailsList.add(details3);

        groupItemInfo2.setType("WIRE");
        groupItemInfo2.setItems(detailsList);


        MyItems.GroupItemInfo groupItemInfo3 = new MyItems.GroupItemInfo();
        MyItems.Details details4= new MyItems.Details();
        details4.setId("A");
        details4.setStatus("Active");
        MyItems.Details details5 = new MyItems.Details();
        details5.setId("H");
        details5.setStatus("Active");
        List<MyItems.Details> detailsList2 = new ArrayList<>();
        detailsList2.add(details4);
        detailsList2.add(details5);
        groupItemInfo3.setType("MODEM");
        groupItemInfo3.setItems(detailsList2);

        itemInfoList.add(groupItemInfo1);
        itemInfoList.add(groupItemInfo2);
        itemInfoList.add(groupItemInfo3);
        System.out.println("---------itemInfoList------------ " + itemInfoList);

      /*  itemInfoList.stream().forEach(groupItemInfo -> {
            groupItemInfo.setType();
        });*/
    }
}

I want to store all the items from all objects whose type!=null (WIRE,MODEM) in the object with type=null and should be unique(duplicates should not be allowed). Below is the sample image of how the data is stored.

在此处输入图像描述

In the above image, the result list has 3 elements and element 2 and element 3 has items that I wanted to read and store in the first element whose type==null (without duplicates). Having difficulty in how to read the groupItemInfo.getItems() when already in the loop(itemsList.stream().forEach..).

Expectation is for element zero with type=null and items=null, read all the items from other elements in the list and store with out duplicates (A,B,C,H should be stored)

Since lombok is already generating equals/hashCode for you this should be very simple.

List<MyItems.Details> combined = Stream.concat(detailsList.stream(), detailsList2.stream()) // Create a Stream based on the two lists
    .distinct() // Remove duplicates
    .toList(); // Creates the list. Depending on your Java version you may need to write collect(Collectors.toList()) instead.
groupItemInfo1.setItems(combined);

Couple things,

If you want to have only unique elements i would suggest you change the type of the items member of GroupItemInfo from List<Details> to Set<Details> (or SortedSet<Details> if an ordering is needed).

Similarly you might want to think if you really need the itemInfoList member to be a List<MyItems.GroupItemInfo> or can it be a Set<MyItems.GroupItemInfo> instead (or again a SortedSet<MyItems.GroupItemInfo> depending on the ordering need).

Now having said that, with the above code (assuming you can't change) we can do this as below,

// First get the one whose type==null..
MyItems.GroupItemInfo nullTypedGroupItemInfo = itemInfoList.stream().filter(groupItemInfo -> groupItemInfo.getType() == null).findFirst().orElseThrow();

// Get unique, ordered set of details from the others whose whose type!=null..
Collection<Details> detailsCollection = itemInfoList.stream().filter(groupItemInfo -> groupItemInfo.getType() != null).flatMap(item -> item.getItems()).collect(Collectors.toCollection(TreeSet::new));
});

// Finally set the above unique details collection in the one whose type==null that we obtained earlier..
nullTypedGroupItemInfo.setItems(new ArrayList<>(detailsCollection));

Thanks

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