[java]Po wykonaniu komendy add, poprzednie dane zostają nadp


#1

Witam,

mam dosyć dziwny problem:

otóż mam array listę:

List infoobloku = new ArrayList();

Oraz ten kawałek kodu:

tabBlocks = _map.getMap();

		tabMoving = _map.getMap3();

		for(int c=0; c
		{

			for(int d=0; d
			{

				if(tabBlocks.get(c).get(d) != 0 && tabMoving.get(c).get(d) != 0){


					infoobloku.add(c+(100*d)); //ID

					infoobloku.add(0); //+X

					infoobloku.add(0); //+Y

					infoobloku.add(d); //tabX

					infoobloku.add(c); //tabY

					_af.moving_blocks.add(infoobloku);

					infoobloku.clear();

				}	

			}

		}

Problem polega na tym, że w ArrayLiście _af.moving_blocks dzieje się coś dziwnego:

Otóż gdy dodaję dane (metodą add), faktycznie program dokłada jeszcze jedną kolumnę/wiersz, ale także podmienia wszystkie poprzednie.


(Sawyer47) #2

Dodajesz wciąż tę samę referencję, do tej samej listy. Twórz za każdym razem nową ArrayList.


(Grzelix) #3

Lista jest obiektem typu referencyjnego - to już w sumie powinno dać ci odpowiedź.

Rozwiązanie w każdej pętli musisz utworzyć instancję nowego obiektu typu lista.

także brakuje Ci poniższej linijki

infoobloku = new ArrayList();

([alex]) #4

grzelix , ma to gdzieś zadeklarowane globalnie, tak przynajmniej napisał.

Można też użyć Clone();

_af.moving_blocks.add(infoobloku.Clone());

ale z mojego doświadczenia czasami to działa niezbyt poprawnie.


(Grzelix) #5

@alex owszem ma gdzieś to zadeklarowane inaczej rzucało by błędami (w trakcie kompilacji albo w momencie użycie nie jestem pewien)

w moim wpisie chodzi mi o to, że przy każdej iteracji kiedy dodaje nowy obiekt listy infoobloku musi faktycznie stworzyć nowy obiekt, czyli wywołać konstruktor. Ponieważ w obecnym kodzie operuje tylko na jednej instancji obiektu, i z racji iż jest to obiekt referencyjny zmienia wszystkie odwołania do niego. Co autor pokazał.

Faktycznie metoda clone może tu pomóc ale ja polecałbym moje rozwiązanie.


([alex]) #6

grzelix , takie właśnie rozwiązanie zaproponował nr47 (przed tobą). Ja zaproponowałem alternatywę wprowadzenie której potrzebuje mniej zmian w kodzie. Ale owszem to rozwiązanie od nr47 jest lepsze ponieważ Clone() musi kopiować całość po czym Clear() całość usuwa, tworzenie nowego obiektu eliminuje kopiowanie oraz czyszczenie, co sprowadza się do wydajniejszego kodu.