Как сравнить два ArrayList`a по их содержимому?
Я хочу сравнит два листа, по их содержимому в объекте. Если объект из первого листа найден во втором, то ввести его. Но мой код не работает, выдает exception: java heap memory
Вопрос: Что тут не так и как правильно реализовать? код:
private List<PaymentRBS> rbsList;
private List<PaymentPartner> partnerList;
public void compare() {
ArrayList<PaymentPartner> found = new ArrayList<>();
ArrayList<PaymentPartner> notFound = new ArrayList<>();
for (PaymentRBS rbs : rbsList) {
for (PaymentPartner partner : partnerList){
if (partner.getAccount().equals(rbs.getAccount()) && partner.getSum() == rbs.getSum()){
found.add(partner);
}
else{
notFound.add(partner);
}
}
}
}
Ответы (3 шт):
Длинновато для комментария:
про exception - отлаживайте, проверяйте, какие объекты не созданы, например, в данном куске кода не видно создания списков из верхних строчек (может, где-то оно и есть).
Кроме того, имеется логическая ошибка - в список notfound добавляется каждый partner, не совпадающий с текущим rbs, но ведь он может совпасть с другим элементом rbsList. В данном случае notfound будут содержать много одинаковых копий
Можно воспользоваться JUnit:
import static org.junit.Assert.assertArrayEquals;
assertArrayEquals(found.toArray(), notFound.toArray());
Метод compare должен возвращать какой-либо из списков found/notFound (или некий объект, позволяющий вернуть оба таких списка, например Map<Boolean, List<PaymentPartner>>). Также для метода следует выбрать более подходящее название типа findMatches, findNonMatches.
Также списки rbsList, partnerList должны передаваться в метод compare как аргументы.
Добавление в список notFound следует выполнять только если из списка partnerList не был обнаружен в списке rbs (после цикла)
Примерная реализация, возвращающая оба списка в Map:
public Map<Boolean, List<PaymentPartner>> findMatches(
List<PaymentRBS> rbsList, List<PaymentPartner> partnerList)
{
Map<Boolean, List<PaymentPartner>> result = new LinkedHashMap<>();
for (PaymentPartner partner : partnerList) {
boolean found = false;
for (PaymentRBS rbs : rbsList) {
if (partner.getAccount().equals(rbs.getAccount())
&& partner.getSum() == rbs.getSum()) {
found = true;
break; // нашли первое совпадение
}
}
result.computeIfAbsent(found, (k) -> new ArrayList<>())
.add(partner);
}
return result;
}
Что касается ошибки OutOfMemory, она может быть вызвана, когда один из списков слишком большой (например, вычитывается из таблицы в БД, содержащей миллионы объемных записей, состоящие из десятка-другого полей, хотя фактически для сравнения используются только два поля). Нужно увеличивать объем памяти, доступный для кучи Heap и оптимизировать объём данных.