I have the below sample code.
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)
CodePudding user response:
To keep only the element whose items aren't empty, from your code with minimal modifications
List<MyItemsData> result = ...; // initial data
List<MyItemsData> itemWithNotEmptyItems = new ArrayList<>();
result.forEach(groupItemInfo -> {
if (!groupItemInfo.getItems().isEmpty()) {
itemWithNotEmptyItems.add(groupItemInfo);
}
});
Using Stream, you can filter from result then collect to a list
List<MyItemsData> result = new ArrayList<>();
List<MyItemsData> itemWithNotEmptyItems = result.stream()
.filter(groupItemInfo -> !groupItemInfo.getItems().isEmpty())
.collect(Collectors.toList());
CodePudding user response:
Modify your MyItemsData as below,
- Implement equal and hash code, compare only type since uniqueness depends on the type.
- Implement method to return boolean status of MyItemsData (return false if type is null or items is empty"
Sample MyItemsData class:
public static final class MyItemsData {
private String type;
private List items;
public String getType() {
return type;
}
public List getItems() {
return items;
}
public boolean isValid() {
return null != type && !type.isEmpty() && null != items && !items.isEmpty();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
MyItemsData that = (MyItemsData) o;
return type != null ? type.equals(that.type) : that.type == null;
}
@Override
public int hashCode() {
return type != null ? type.hashCode() : 0;
}
}
then you can use stream to filter and get distinct data as list.
Code :
List<MyItemsData> result = source.stream().filter(MyItemsData::isValid).distinct().collect(Collectors.toList());
CodePudding user response:
Let's define a class (to make it clear what we do):
public class MyItemsData {
public static class GroupItemInfo {
private String type;
private List<Item> items;
public String getType() {
return type;
}
public List<Item> getItems() {
return items;
}
public static class Item {}
}
}
And then you can define the custom comparator for MyItemsData.GroupItemInfo.Item. And then using Stream you can create a TreeSet to retrieve unique items using a given comparator. Then you can build a List.
public static void main(String... args) {
List<MyItemsData.GroupItemInfo> itemsList = new ArrayList<>();
List<MyItemsData.GroupItemInfo.Item> uniqueItems = getUniqueItems(itemsList);
}
public static List<MyItemsData.GroupItemInfo.Item> getUniqueItems(List<MyItemsData.GroupItemInfo> items) {
final Comparator<MyItemsData.GroupItemInfo.Item> comparator = (one, two) -> {
// TODO implement comparator (return =0 for equal items)
return 0;
};
return new ArrayList<>(items.stream()
.filter(item -> item.getType() != null)
.filter(item -> !item.getItems().isEmpty())
.map(MyItemsData.GroupItemInfo::getItems)
.flatMap(List::stream)
.collect(Collectors.toCollection(() -> new TreeSet<>(comparator))));
}

