Создание ArrayList уникальных элементов в ArrayList в Java

У меня есть ArrayList пользователей, которые могут заходить на веб-сайт несколько раз в день. Как я могу создать ArrayList уникальных пользователей из первого массива. Другими словами, мне нужно игнорировать несколько входов в систему. Если, например, было 20 входов на веб-сайт, и все эти входы были сделаны двумя пользователями, то второй список должен содержать только два пользовательских объекта. Я новичок в языке программирования Java, и мне нужна помощь.

Вот класс пользователя:

public class User {

    private String id
    private String date;

    public String getId() {
        return id
    }

    public void setId(String id) {
        this.id = id
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }
}

И вот как я собирался решить проблему, но почему-то это не работает.

ArrayList<User> userList = new ArrayList<>();
ArrayList<User> uniqueUserlist = new ArrayList<>();

    String id = null;

    for(User user : userList) {

        if (user.getId() != id) {
            uniqueUserlist.add(user);
        }

        id = user.getId();
    }

Спасибо.


person Daniel Foo    schedule 03.08.2017    source источник
comment
У вас нет данных инициализации для вашего userList перед использованием в цикле   -  person TuyenNTA    schedule 04.08.2017
comment
== и != в Java сравнивают равенство ссылок, а не равенство данных. Если вы хотите проверить, равны ли идентификаторы, используйте user.getId().equals(id).   -  person azurefrog    schedule 04.08.2017
comment
Если вы измените свой класс User, чтобы сделать его разумным equals и hashCodetoString для полноты), вы можете использовать решение в Получить уникальные значения из arraylist в java .   -  person Kevin J. Chase    schedule 04.08.2017


Ответы (3)


Если вам не нужны дубликаты, но вы хотите использовать ArrayList, быстрым решением будет переместить все элементы в HashSet (который не допускает дублирования), очистить ArrayList, а затем добавить элементы из HashSet обратно в ArrayList.

person Blizzardman    schedule 03.08.2017
comment
Хэш-код не int, это строка? - person Daniel Foo; 04.08.2017
comment
Список‹Пользователь› результат = новый ArrayList‹Пользователь›(); Set‹String› ids= new HashSet‹String›(); for(Пользователь-пользователь: originalList) { if(ids.add(user.getId()) { result.add(user); } } - person Daniel Foo; 08.10.2017

Хотя ваша ошибка просто неправильно сравнивает Strings, есть гораздо лучший способ сделать это:

  • Добавьте hashCode и equals в свой User класс
  • Поместите эти предметы в LinkedHashSet

Что вы делаете:

  • Определение hashCode позволяет вам использовать структуры данных, для которых требуется хеш-значение, например Set.
  • LinkedHashSet сохраняет порядок вставки и устраняет дубликаты за счет небольшой дополнительной памяти.
person Makoto    schedule 03.08.2017
comment
Что такое hashCode не int? Что такое hashCode, это строка? - person Daniel Foo; 04.08.2017
comment
@DanielFoo: hashCode всегда int. Вы вычисляете значение. Если вы не слишком уверены, то вы можете использовать 31 * id.hashCode() + 31 * date.hashCode(), хотя имейте в виду, что я сделал это навскидку и не буду ручаться за его надежность вообще. Это я оставляю в качестве упражнения для читателя. - person Makoto; 04.08.2017
comment
В моем случае идентификатор пользователя может иметь буквы. Как мне переопределить хэш-код и равенство, если я собираюсь сравнивать пользователей по идентификатору строки. - person Daniel Foo; 04.08.2017

Вы можете использовать Stream API... поместите свой список в TreeSet, из которого вы предоставляете настраиваемый компаратор, который сравнивает идентификатор уникально.

Что-то вроде приведенного ниже удовлетворит ваши потребности.

ArrayList<User> uniqueUserlist = userList.stream()
                            .collect(collectingAndThen(toCollection(() -> new TreeSet<>(comparingInt(User::getId))), ArrayList::new));
person Jeeppp    schedule 03.08.2017
comment
Это потребует, чтобы элементы были Comparable. - person Makoto; 04.08.2017