Home > Net >  using java8 stream i want to read the list element and store the value in another element of the sam
using java8 stream i want to read the list element and store the value in another element of the sam

Time:01-06

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.

enter image description here

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)

CodePudding user response:

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

CodePudding user response:

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<Details>::new));
});

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

Thanks

  •  Tags:  
  • Related