0

I have a Group object that looks like this

public class Group { 
    private String mName;
    private List<Item> mItems;
}

and an Item object that looks like this

public class Item {
    private String mNumber;
}

Now let's say I have a first list like List<Group> { ["Group1", {Item1, Item2, Item3}] } and a second one like List<Group> { ["Group1", {Item2}] }. I would like to remove Item2 from the first list with lambda.

What I have so far is the following but I'm stuck in the middle.

firstList.stream()
.flatMap(group -> group.getItemList().stream())
.filter(item -> (
        // here I'm stuck. I think i need a stream of the second list or something?
        ))
.collect(Collectors.toList());

The result should look like List<Group> {["Group1", {Item1, Item3}]}

1
  • Do you wish to mutate the existing List (firstList) or create a new output List? Commented Jun 30, 2021 at 9:01

4 Answers 4

1

I am not sure, If you can do it through flatMap approach. Here is the slightly different approach.

Assuming you have overridden equals and hashcode methods for Item class and Group List will contain unique items. Also, I am assuming that Group mName attribute can be used to identify relation between group in two group list

    List<Group> groupList1 = new ArrayList<>();
    List<Group> groupList2 = new ArrayList<>();

    Group group1 = new Group();
    group1.setMName("group1");
    group1.setMItems(Lists.newArrayList(new Item("item1"),new Item("item2"), new Item("item3")));
    groupList1.add(group1);

    Group group2 = new Group();
    group2.setMName("group1");
    group2.setMItems(Lists.newArrayList(new Item("item2")));
    groupList2.add(group2);

    Map<String, Group> group2Map = groupList2.stream().collect(Collectors.toMap(group -> group.getMName(), Function.identity()));

    List<Group> finalGroupList = groupList1.stream().filter(group -> group2Map.get(group.getMName()) != null)
            .map(group -> {
                Group grp = group2Map.get(group.getMName());
                List<Item> items = group.getMItems().stream().filter(item -> !grp.getMItems().contains(item)).collect(Collectors.toList());
                group.setMItems(items);
                return group;
            }).collect(Collectors.toList());
//finalGroupList  will be similar to <Group> {["Group1", {Item1, Item3}]}
Sign up to request clarification or add additional context in comments.

1 Comment

thank you! although your exact code didn't work for me you pointed me in the right direction to solve my problem. upvoted
0

The lastlist not contains

firstList.stream()
.flatMap(group -> group.getItemList().stream())
.filter(item -> (!lastList.countains(item)))
.collect(Collectors.toList());

3 Comments

thanks for your reply but !lastList.contains(item) doesnt work because lastList is of type List<Group> and item is of type Item
so, !lastList.Items.countains(item)??
If you just remove the duplication, you can try to sort out the item list first
0

This would give you the updated mItems, assuming you dont want to mutate the existing..

var mItems = first.stream()
        .flatMap(group -> group.getMItems().stream())
        .filter(item -> !(second.stream().anyMatch(g -> g.getMItems().contains(item))))
        .collect(Collectors.toList());

result: [Item(mNumber=Item1), Item(mNumber=Item3)

Comments

0

Pramod pointed me to the right direction to solve my problem :) The solution is:

firstList.stream()
.filter(secondList::contains) // added this later because I only need groups wich are in both lists
.map(group -> {
    List<Item> items = group.getItemList().stream()
            .filter(item -> !(secondList.stream().flatMap(group2 -> group2.getItemList().stream())
                    .collect(Collectors.toList()))
                    .contains(item))
            .collect(Collectors.toList());
    group.setItemList(items);
    return group;
}).collect(Collectors.toList());

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.