2

I've tried to solve the problem and am stuck. I have class User:

public class User {

   public String name;
   public String email;
   public Integer age;
   public String group;

   public User() {
   }

   public User(String name, String email, Integer age, String group) {
      this.name = name;
      this.email = email;
      this.age = age;
      this.group = group;
   }
}

And list of users looks like:

List<User> users = new ArrayList<>();
users.add(new User("Max" , "test@test", 20 , "n1"));
users.add(new User("John" , "list@test", 21 , "n2"));
users.add(new User("Nancy" , "must@test", 22 , "n3"));
users.add(new User("Nancy" , "must@test", 22 , "n4"));
users.add(new User("Max" , "test@test", 20 , "n5"));

But this list contains duplicate objects with a difference only in the group. So I need to combine duplicate objects to new object looks like :

User: name: "Max", email: "test@test" , age: 20, groups: "n1, n5"

User: name: "John", email: "list@test" , age: 21, groups: "n2"

User: name: "Nancy", email: "must@test" , age: 22, groups: "n3, n4"

I understand that I need to use steams from Java 8, but don't understand exactly how.

Please, help

7
  • I don't really think Streams will help you here. What's your level of Java: are you ok with pseudo-code and implement it yourself of do you want a full solution? Commented May 16, 2019 at 11:22
  • The expected out doesn't match the given description. Please, edit the post and correct it in order to help you better. Also see coment from @Zabuza. Images are less helpful than actual code. Commented May 16, 2019 at 11:23
  • I would suggest adding an id Field for your user object, as identify unique users easily. Commented May 16, 2019 at 11:34
  • 1
    Possible duplicate of Java stream merge or reduce duplicate objects Commented May 16, 2019 at 11:37
  • @Mihai Im ok with it , even pseodo-code can be helpful for me Commented May 16, 2019 at 11:50

3 Answers 3

2

you can take advantage of toMap collector as it has a merge function which will join your duplicate objects, for example I will create a new object every time a duplicate is found, but you can just modify the existing object

static User join(User a, User b) {
    return new User(a.getName(), a.getEmail(), a.getAge(), a.getGroup() + "," + b.getGroup());
}

and the stream op.

List<User> collect = users.stream()
            .collect(Collectors.collectingAndThen(Collectors.toMap(User::getEmail,
                            Function.identity(), 
                            (a, b) -> join(a, b)),
                    map -> new ArrayList<>(map.values())));
Sign up to request clarification or add additional context in comments.

Comments

1

You may simply do:

List<User> sortedUsers = new ArrayList<>();
// group by email-id
Map<String, List<User>> collectMap = 
                 users.stream().collect(Collectors.groupingBy(User::getEmail));

collectMap.entrySet().forEach(e -> {
    String group = e.getValue().stream()                     // collect group names
                               .map(i -> i.getGroup())
                               .collect(Collectors.joining(","));
    User user = e.getValue().get(0);
    sortedUsers.add(new User(user.getName(), user.getEmail(), user.getAge(), group));
});

which outputs:

[
   User [name=John, email=list@test, age=21, group=n2], 
   User [name=Max, email=test@test, age=20, group=n1,n5], 
   User [name=Nancy, email=must@test, age=22, group=n3,n4]
]

Make sure to add getters and setters, also override the toString() of User.

Comments

1

This is a working example of what you need (I hope :)).

It considers the combination of the first 3 fields as a unique key. It then goes through the list and adds Users to a Map based on the key and having the group as a value. I use a Map because it makes retrieval faster. Before inserting a new User I check if it is already in the map. If it is then I append the new group. If it is not I insert it with the current group.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class User {

    public String name;
    public String email;
    public Integer age;
    public String group;

    public static final void main(String[] args) {
        List<User> users = new ArrayList<>();
        users.add(new User("Max", "test@test", 20, "n1"));
        users.add(new User("John", "list@test", 21, "n2"));
        users.add(new User("Nancy", "must@test", 22, "n3"));
        users.add(new User("Nancy", "must@test", 22, "n4"));
        users.add(new User("Max", "test@test", 20, "n5"));

        List<User> filtered = filter(users);
        filtered.stream().forEach(System.out::println);
    }

    public User() {
    }

    public User(String key, String group) {
        String[] keys = key.split("-");
        this.name = keys[0];
        this.email = keys[1];
        this.age = Integer.parseInt(keys[2]);
        this.group = group;
    }

    public User(String name, String email, Integer age, String group) {
        this.name = name;
        this.email = email;
        this.age = age;
        this.group = group;
    }

    public String toString() {
        return name + " : " + email + " : " + " : " + age + " : " + group;
    }

    public String getUniqueKey() {
        return name + "-" + email + "-" + age;
    }

    public static List<User> filter(List<User> users) {
        Map<String, String> uniqueGroup = new HashMap<>();
        for (User user : users) {
            String found = uniqueGroup.get(user.getUniqueKey());
            if (null == found) {
                uniqueGroup.put(user.getUniqueKey(), user.group);
            } else {
                uniqueGroup.put(user.getUniqueKey(), found + ", " + user.group);
            }
        }

        List<User> newUsers = new ArrayList<>();
        for (String key : uniqueGroup.keySet()) {
            newUsers.add(new User(key, uniqueGroup.get(key)));
        }

        return newUsers;
    }

}

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.