Сравнение двух коллекций в Java

У меня есть две коллекции в Java-класс.Первая коллекция содержит предыдущие данные, вторая содержит обновленные данные из предыдущей коллекции.

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

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

любая помощь оценили

5 ответов


трудно помочь, потому что вы не сказали нам как вам нравится сравнивать коллекции (равного размера). Некоторые идеи, надеясь, что один подойдет:

сравнить обе коллекции, если они содержат одни и те же объекты в том же порядке

Iterator targetIt = target.iterator();
for (Object obj:source)
  if (!obj.equals(targetIt.next()))
    // compare result -> false

сравнить обе коллекции, если они содержат одни и те же объекты в любом порядке

for (Object obj:source)
  if (target.contains(obj))
    // compare result -> false

найти элементы в другой коллекции, которая имеет изменено

Iterator targetIt = target.iterator();
for (Object obj:source)
  if (!obj.equals(targetIt.next())
    // Element has changed

основываясь на вашем комментарии, этот алгоритм сделает это. Он собирает все автомобили, которые были обновлены. Если результатом метода является пустой список, обе коллекции содержат одинаковые записи в одном порядке. Алгоритм использует о правильной реализации equals() на Car тип!

public List<Car> findUpdatedCars(Collection<Car> oldCars, Collection<Car> newCars)
  List<Car> updatedCars = new ArrayList<Car>();
  Iterator oldIt = oldCars.iterator();
  for (Car newCar:newCars) {
    if (!newCar.equals(oldIt.next()) {
      updatedCars.add(newCar);
    }
  }
  return updatedCars;
}

из арифметики множеств A и B равны iff a subsetequal B и B subsetequal A. Таким образом, в Java, учитывая две коллекции A и B, вы можете проверить их равенство без учета порядка элементов с

boolean collectionsAreEqual = A.containsAll(B) && B.containsAll(A);

  • повторите первую коллекцию и добавьте ее в Map<Entity, Integer> whereby Entity класс хранится в вашей коллекции и Integer представляет количество раз, когда это происходит.
  • повторите вторую коллекцию и для каждого элемента попытайтесь найти ее в Map - если он существует, то уменьшите Integer value by one и выполните любое действие, необходимое при обнаружении совпадения. Если Integer значение достигло нуля, затем удалите (Entity, Integer) запись с карты.

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


слегка обновлено с учетом нулевых значений:

static <T> boolean equals(Collection<T> lhs, Collection<T> rhs) {
    boolean equals = false;
    if(lhs!=null && rhs!=null) {
       equals = lhs.size( ) == rhs.size( ) && lhs.containsAll(rhs)  && rhs.containsAll(lhs);
    } else if (lhs==null && rhs==null) {
       equals = true;
    }
 return equals;
}

если не беспокоится о таких случаях, как (2,2,3), (2,3,3):

static <T> boolean equals(Collection<T> lhs, Collection<T> rhs) {
    return lhs.size( ) == rhs.size( ) && lhs.containsAll(rhs)  && rhs.containsAll(lhs);
}