Как искать конкретного пользователя в списке из миллионов пользовательских объектов?

#java

#java

Вопрос:

Допустим, у меня есть класс User, подобный приведенному ниже,

 class User {
  int id;
  String emailAddress; 
} 
  

и допустим, у меня есть список из миллионов таких пользователей. Это может быть что угодно — массив или список массивов или что угодно.

Теперь, учитывая пользователя с идентификатором или адресом электронной почты, как мне эффективно искать конкретного пользователя, например, поиск по идентификатору или поиск по адресу электронной почты независимо.

Комментарии:

1. Используйте базу данных.

2. @ScaryWombat. К сожалению, эти данные поступают из какого-то другого источника, и мне приходится делать это только в памяти.

3. Если вам действительно нужно сохранить это в памяти, взгляните на хэш-таблицы.

4. @Henry, да, но тогда он будет искать либо по идентификатору, либо по адресу электронной почты, если я использую один из них в качестве ключа.

5. Ничто не мешает вам использовать две таблицы.

Ответ №1:

Я думаю, что есть 2 возможных способа решить вашу проблему, и оба решения зависят от вашей текущей архитектуры.

  1. Если вы получаете пользовательские данные из базы данных, тогда просто создайте два метода поиска. первый метод поиска содержит предложение where идентификатора пользователя, а другой метод поиска содержит предложение where электронной почты пользователя.
  2. Если вы не получаете пользовательские данные из базы данных, то вы можете сделать пользователя различными алгоритмами поиска, которые уже реализованы. На рисунке ниже показана временная сложность некоторых алгоритмов поиска и сортировки. Но для меня лучше сначала отсортировать данные с помощью сортировки слиянием, а затем использовать двоичный поиск.

Ответ №2:

Используйте две карты, один идентификатор карты для пользователя, другой адрес электронной почты карты для пользователя, простой код, подобный этому:

 public class UserCache {
    Map<Integer, List<User>> id2User = new ConcurrentHashMap<>();
    Map<String, List<User>> email2User = new ConcurrentHashMap<>();

    public void initMaps(List<User> users) {
        id2User.putAll(users.stream()
            .collect(Collectors.groupingBy(User::getId)));
        email2User.putAll(users.stream()
            .collect(Collectors.groupingBy(User::getEmailAddress)));
    }

    public List<User> getUsersById(String id) {
        return id2User.get(id);
    }

    public List<User> getUserByEmail(String email) {
        return email2User.get(email);
    }

    public void deleteUserById(String id) {
        List<User> users = id2User.remove(id);
        users.stream()
            .forEach(user -> email2User.remove(user.getEmailAddress()));
    }

    public void deleteUserByEmail(String email) {
        List<User> users = email2User.remove(email);
        users.stream()
            .forEach(user -> id2User.remove(user.getId()));
    }
}