Подтвердить что ты не робот

Как я могу проверить, отличаются ли два ArrayList, мне все равно, что изменилось

Как проверить, отличаются ли два ArrayLists друг от друга? Меня не волнует, в чем разница, я просто хочу знать, если они не совпадают.

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

Теперь значение ArrayList является фактически классом, который я создал (который содержит имя, lvl, rank, score).

Мне нужно реализовать equals() на нем?

4b9b3361

Ответ 1

Здесь простой метод, который проверяет, содержит ли 2 списка массивов одинаковые значения независимо от их порядка.

 //the name of the method explains it well...
    public boolean isTwoArrayListsWithSameValues(ArrayList<Object> list1, ArrayList<Object> list2)
    {
        //null checking
        if(list1==null && list2==null)
            return true;
        if((list1 == null && list2 != null) || (list1 != null && list2 == null))
            return false;

        if(list1.size()!=list2.size())
            return false;
        for(Object itemList1: list1)
        {
            if(!list2.contains(itemList1))
                return false;
        }

        return true;
    }

Ответ 2

По определению "идентичность"

Как отметил Йоахим, для большинства приложений List.equals(Object o) работает:

Сравнивает указанный объект с этим списком для равенства. Возвращает true тогда и только тогда, когда указанный объект также является списком, оба списка имеют одинаковый размер, и все соответствующие пары элементов в двух списках равны. (Два элемента e1 и e2 равны, если (e1==null ? e2==null : e1.equals(e2)).) Другими словами, два списка определены равными, если они содержат одни и те же элементы в одном порядке. Это определение гарантирует, что метод equals корректно работает в разных реализациях интерфейса List.

В зависимости от того, как вы его используете, это может работать не так, как ожидалось. Например, если у вас есть List<int[]>, он не работает, потому что массивы наследуют equals из Object, который определяет равенство как ссылочный идентификатор.

    List<int[]> list1 = Arrays.asList(new int[] { 1, 2, 3 });
    List<int[]> list2 = Arrays.asList(new int[] { 1, 2, 3 });
    System.out.println(list1.equals(list2)); // prints "false"

Кроме того, два списка с разными параметрами типа могут быть equals:

    List<Number> list1 = new ArrayList<Number>();
    List<String> list2 = new ArrayList<String>();
    System.out.println(list1.equals(list2)); // prints "true"

Вы также упомянули, что список должен содержать элементы одного типа. Здесь еще один пример, когда элементы не имеют одного и того же типа, но все же они equals:

    List<Object> list1 = new ArrayList<Object>();
    List<Object> list2 = new ArrayList<Object>();
    list1.add(new ArrayList<Integer>());
    list2.add(new LinkedList<String>());
    System.out.println(list1.equals(list2)); // prints "true"

Итак, если вы не четко определите, что означает для вас равенство, вопрос может иметь очень разные ответы. Для большинства практических целей достаточно List.equals.


При реализации equals

Информация после обновления подсказывает, что List.equals будет выполнять задание просто отлично, при условии, что элементы будут правильно реализовывать equals (потому что List<E>.equals вызывает E.equals в не-t221 > -элементах, по документации API выше).

Итак, в этом случае, если у нас есть, скажем, List<Player>, то Player должен @Override equals(Object o) возвращать true, если o instanceof Player и в соответствующих полях, все они equals ( для ссылочных типов) или == (для примитивов).

Конечно, когда вы @Override equals, вы также должны @Override int hashCode(). Едкий приемлемый минимум - return 42;; немного лучше - return name.hashCode();; лучше всего использовать формулу, которая включает все поля, на которых вы определяете equals. Хорошая среда IDE может автоматически генерировать методы equals/hashCode для вас.

См. также

  • Эффективное Java 2nd Edition
    • Пункт 8: соблюдать общий контракт при переопределении равных
    • Пункт 9: Всегда переопределять хэш-код при переопределении равных

Ссылки API

Связанные вопросы

Вкл equals/hashCode комбо:

Вкл equals vs ==:

Ответ 3

Используйте equals(). Пока элементы внутри списков реализуют equals() правильно, он вернет правильные значения.

Если вы не хотите игнорировать порядок значений, вы должны сбросить значения в двух объектах Set и сравнить их с помощью equals().

Ответ 4

Как сказал в своем ответе @Joachim Sauer, равные должны работать, если списки равны, а их содержимое реализовано правильно. Но он не должен работать, если элементы не находятся в одном "порядке", так как он не используется для проверки. В этом смысле он проверяет "строгое" равенство, как указано @jarnbjo

        //From android Arraylist implementation
        Iterator<?> it = that.iterator();
        for (int i = 0; i < s; i++) {
            Object eThis = a[i];
            Object eThat = it.next();
            if (eThis == null ? eThat != null : !eThis.equals(eThat)) {
                return false;
            }
        }

Однако мне хотелось немного по-другому, мне не нравился порядок или что-то в этом роде. Все, что я хотел, было убедиться, что у двух не было одинаковых предметов. Мое решение,

    //first check that both are not null and are of same length. (not shown here)
    //if both match, pull out the big guns as below
    ...
    List<Object> comparedList = new ArrayList<>(listOne);
    comparedList.removeAll(listTwo);
    if(comparedList.size() != 0) //there are differences between the two

Это менее результативно, так как он дважды повторяется, сначала в removeAll, а затем в contains, который вызывается removeAll.

Мой список был гарантированно коротким, поэтому я не против удара.

Ответ 5

Вы также можете проверить Arraylist, как показано ниже:

public  boolean equalLists(List<String> one, List<String> two){     
if (one == null && two == null){
    return true;
}

if((one == null && two != null) 
  || one != null && two == null
  || one.size() != two.size()){
    return false;
}

//to avoid messing the order of the lists we will use a copy
//as noted in comments by A. R. S.
one = new ArrayList<String>(one); 
two = new ArrayList<String>(two);   

Collections.sort(one);
Collections.sort(two);      
return one.equals(two);
}

Благодаря @Jacob