ArrayList.removeAll() zwraca false dla kolekcji tego samego typu oraz tych samych wartości.

0

Cześć. Czy ktoś wie dlaczego w drugim przypadku nie usuwa elementów? Byłbym wdzięczny za rozwiązanie.

ArrayList<Long> a = new ArrayList<Long>();
a.add(953l);
a.add(952l);
a.add(951l);
ArrayList<Long> b = (ArrayList<Long>) a.clone();
b.add(1121l);
	
System.out.println("1: "+a);
System.out.println("2: "+b);
System.out.println(b.removeAll(a));
System.out.println("Dodano: "+b);

Wynik:
1: [1, 2, 3]
2: [1, 2, 3, 4]
true
Dodano: [4]

1: [1, 2, 3]
2: [1, 2, 3, 4]

*Teraz pobieram dane dla "a" z bazy (Hibernate: SQLQuery query i rzutowanie query.list() na ArrayList<Long>, a "b" z JTable umieszonej w JDialog *

Wynik:
1: [1, 2, 3]
2: [1, 2, 3, 4]
false
Dodano: [1, 2, 3, 4]

0

A dlaczego oczekujesz, że metoda removeAll(b) cokolwiek usunie? Przecież ona nie analizuje zawartości obiektów, ale porównuje referencje.

0
bogdans napisał(a):

A dlaczego oczekujesz, że metoda removeAll(b) cokolwiek usunie? Przecież ona nie analizuje zawartości obiektów, ale porównuje referencje.

Wydaje mi się, że jest inaczej (SDK):

private boolean batchRemove(Collection<?> c, boolean complement) {
final Object[] elementData = this.elementData;
int r = 0, w = 0;
boolean modified = false;
try {
for (; r < size; r++)
if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];
} finally {
// Preserve behavioral compatibility with AbstractCollection,
// even if c.contains() throws.
if (r != size) {
System.arraycopy(elementData, r,
elementData, w,
size - r);
w += size - r;
}
if (w != size) {
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w;
modified = true;
}
}
return modified;
}

Dla Hibernate:Query działa prawidłowo, ale dlaczego nie dla SQLQuery

0

Podejrzewam, że prawdopodobne jest iż może tu być taka sytuacja, w której to, co otrzymujesz w liście z bazy ma inny typ niż twoja lista usuwana. Stawiam na to: "rzutowanie query.list() na ArrayList<Long>".
Chodzi o to, że aby obiekt został usunięty z listy, to musi on spełniać equals, a tam najpierw jest sprawdzane, czy porównywane są obiekty tej samej klasy. Przkładowo przy wypisywaniu List<Short> i List<Long> różnicy na konsoli możesz nie zobaczyć, ale jest na poziomie typów.
Jak zaznaczyłem to tylko podejrzenie, bo konkretnego przypadku jak coś takiego otrzymać raczej ci nie podam.

0
chodnik napisał(a):

Podejrzewam, że prawdopodobne jest iż może tu być taka sytuacja, w której to, co otrzymujesz w liście z bazy ma inny typ niż twoja lista usuwana. Stawiam na to: "rzutowanie query.list() na ArrayList<Long>".
Chodzi o to, że aby obiekt został usunięty z listy, to musi on spełniać equals, a tam najpierw jest sprawdzane, czy porównywane są obiekty tej samej klasy. Przkładowo przy wypisywaniu List<Short> i List<Long> różnicy na konsoli możesz nie zobaczyć, ale jest na poziomie typów.
Jak zaznaczyłem to tylko podejrzenie, bo konkretnego przypadku jak coś takiego otrzymać raczej ci nie podam.

Obie porównywane listy są typu Long. Też początkowo sądziłem, że są różne typy, ale dodałem sprawdzenie elementów list (if x instanceof Long). W bazie (Oracle) wartość dla pobieranej kolumny oznaczona jest jako number(10,0).

0

A co zwraca metoda equals() dla dwóch obiektów typu Long mających tę samą wartość, jeden z query, a drugi z JTable?

0

Pokaż te metody, którymi pobierasz z bazy, tą z Query i tą z SQLQuery. Nie korzystałem nigdy bezpośrednio z Hibertnate (tylko przez JPA), ale wydaje mi się, że jedna zwróci listę obiektów (entity), a druga listę tablic. I tu bym szukał jeszcze. Tylko pokaż ten kod.

0

Moja gafa, sprawdzałem typ tylko dla jednej tablicy 2x. Z bazy pobierane wartości są typu java.math.BigDecimal
Query:

 "select artykul_id from test where kategoria = :kategoria"

Dlaczego nie działa rzutowanie?

0

Jakie rzutowanie ma działać, skoro klasy BigDecimal nie można rzutować na Long?

1 użytkowników online, w tym zalogowanych: 0, gości: 1