read the elements and add the unique elements in other object

Viewed 48

I have the below sample code.

 List<MyItemsData.GroupItemInfo> itemsList = new ArrayList<>();
    //some business logic to add the MyItemsData objects in the itemsList.
    itemsList.stream().forEach(groupItemInfo -> {
                if (groupItemInfo.getItems().isEmpty()) {
                    System.out.println("item is null");
                } else {
                    System.out.println("item not null " + groupItemInfo.getItems().size());
                }
                if (!groupItemInfo.getItems().isEmpty()) {
    
                }
            });

I want to store all the items from all objects whose type!=null and should be unique(duplicates should not be allowed)

3 Answers

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

Modify your MyItemsData as below,

  1. Implement equal and hash code, compare only type since uniqueness depends on the type.
  2. 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());

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