Wpis z mikrobloga

#programowanie #java
Czemu w tym przypadku java zachoduje się jakby była pass-by-referrence?

ArrayList customer = seller.createseller();
ArrayList createdcar = car.createcar();
ArrayList customercar = offer.offeredcar(createdcar, customer);

Mam taki kod.
createdcar wygląda np. tak:
[[0.0, 0.0, 20.0, 36726.86487578927, 0.7, 15.0, 185310.0, 0.0], [1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 90, 84, 63, 66, 33, 0, 0, 0, 0], [false, false, true, true, false, false, false]]
Metoda offeredcar, której parametrem jest właśnie createdcar ma zwrócić customercar, które ma zmienione dane liczbowe, ale taki sam format. Wszystko działa, ale metoda zmienia mi również parametr, więc dochodzi do absurdalnej sytuacji, gdzie createdcar=customercar

Gdzie siedzi mój błąd?
  • 10
@NaPewnoNieZyd: na 99.9% zmieniasz oryginalną kolekcję w którejś z tych metod (pewnie po prostu przepisujesz referencję do tabeli z jednej zmiennej do drugiej, i tam gdzie wydaje się Tobie, że zmieniasz tylko nową tablicę tak naprawdę jednocześnie zmieniasz obie)
@informatyk: @vytah: @ppawel: Dobra, to powiedzcie mi jeszcze jak zduplikować ArrayList.
Próbowałem w metodzie

public ArrayList offeredcar(ArrayList car, ArrayList seller){

tych sposobów:
ArrayList offeredcar = new ArrayList(car);
i
ArrayList offeredcar = new ArrayList();
offeredcar.addAll(car);

Ale żaden nie zadziałał jak trzeba.
@NaPewnoNieZyd: Konstruktor i addAll kopują tylko zawartość listy, a więc wszystkie wskaźniki, które rzecz jasna będą nadal wskazywać tam gdzie wskazywały. To samo robi Collections.copy().
Jak chcesz mieć naprawdę kopię głęboką (a przynajmniej o jeden poziom głębszą), to musisz ręcznie to ogarnąć, np. tak:

List offeredcar = new ArrayList<>();
for(Object o: car) offeredcar.add(new ArrayList<>((Collection )o));
A tak w ogóle to nieco lipa z takimi słabymi typami jak Object, zrób coś sensowniejszego.
@NaPewnoNieZyd: oba powinny działać - duplikować listę, ale pamiętaj że na obu listach będą wisieć te same obiekty

btw, w typie zmiennej listy możesz użyć interfejsu zamiast konkretnej implementacji listy: List = new ArrayList<>();