Как объединить пользователей с общим email?

Может кто- то подсказать, делаю задачу , где нужно объединить пользователей с общим имейл, с помощью двух hashmap, сделал одну, где ключ- имейл пользователя, а значение имя юзера, но там же значения перезатираются с общим ключом, что я делаю не так?

Имеется n пользователей, каждому из них соответствует список email-ов (всего у всех пользователей m email-ов). Например:

user1 ->[email protected],[email protected],[email protected] ([email protected],[email protected],[email protected])
user2 ->[email protected],[email protected] ([email protected],[email protected])
user3 ->[email protected],[email protected] ([email protected],[email protected])
user4 ->[email protected],[email protected] ([email protected],[email protected])
user5 ->[email protected]

Считается, что если у двух пользователей есть общий email, значит это один и тот же пользователь. Требуется построить и реализовать алгоритм, выполняющий слияние пользователей. На выходе должен быть список пользователей с их email-ами (такой же как на входе).

В качестве имени объединенного пользователя можно брать любое из исходных имен. Список email-ов пользователя должен содержать только уникальные email-ы. Параметры n и m произвольные, длина конкретного списка email-ов никак не ограничена.

Требуется, чтобы асимптотическое время работы полученного решения было линейным, или близким к линейному.

Возможный ответ на задачу в указанном примере:

user1 ->[email protected],[email protected],[email protected],[email protected],[email protected] ([email protected],[email protected],[email protected],[email protected],[email protected])
user3 ->[email protected],[email protected] ([email protected],[email protected])
public class Email implements Sort {
public void convert(List<User> source) {
     Map<String, String> map1 = new HashMap<>();
        Map<String, String> map2 = new HashMap<>();
        for (int i = 0; i < source.size(); i++) {
            String[] list1 = source.get(i).getUser().split(":");
            String[] list2 = list1[1].split(",");
            for (int j = 0; j < list2.length; j++) {
                //ключ- имейл пользователя
                String key = list2[j];
                //значение - имя юзера
                String value = list1[0];
                map1.put(key, value);
            }
        }

        for (String key : map1.keySet()) {
            System.out.println(key + " " + map1.get(key));
        }
    }

 public static void main(String[] args) {
       Email email = new Email();
        List<User> source = Arrays.asList(
        new User("user1:[email protected],[email protected],[email protected]"),
        new User("user2:[email protected],[email protected]"),
        new User("user3:[email protected],[email protected]"),
        new User("user4:[email protected],[email protected]"),
        new User("user5:[email protected]")
        );
       email.convert(source);
    }
}

Ответы (2 шт):

Автор решения: Anton Shchyrov
  1. Объявляем класс

    class User {
      String name;
      Set<String> emails;
    }
    
  2. Объявляем Map<String, User> emails (ключ - e-mail, значение - объект)

  3. Объявляем Map<User, User> dups (ключ - пользователь, значение - основной пользователь)

  4. Объявляем Set<User> unique множество уникальных пользователей

  5. Пишем процедуру заполнения

    void addUsers(List<User> userList) {
      for (User user : userList) {
        boolean isMainUser = true;  // Пока считаем, что пользователь основной
        for (String email : user.emails) {
          String prevUser = emails.putIfAbsent(email, user);
          if (prevUser != null) {  // Уже есть пользователь с таким e-mail
            // достаем основного пользователя
            prevUser = dups.getOrDefault(prevUser, prevUser);
            prevUser.addAll(user.emails); // добавляем основному пользователю свои адреса
            dups.put(user, prevUser);
            isMainUser = false;
          }
        }
        if (isMainUser)  // если все адреса были уникальными
          unique.add(user);
      }
    }
    
  6. Теперь unique содержит уникальных пользователей с объединенными адресами

→ Ссылка
Автор решения: Denis

небольшая опечатка в строке:

prevUser.addAll(user.emails); // добавляем основному пользователю свои адреса

поменять на:

prevUser.emails.addAll(user.emails);

и все будет работать.

→ Ссылка