Mam tablicę, a
która jest stale aktualizowana. Powiedzmy Chodźmy a = [1,2,3,4,5]
. Muszę zrobić dokładną kopię a
i zadzwonić b
. Gdyby a
się zmienić [6,7,8,9,10]
, b
powinno być nadal [1,2,3,4,5]
. Jak najlepiej to zrobić? Próbowałem for
pętli:
for(int i=0; i<5; i++) {
b[i]=a[i]
}
ale to nie działa poprawnie. Nie używaj zaawansowanych terminów, takich jak głębokie kopiowanie itp., Ponieważ nie wiem, co to oznacza.
System.arraycopy
, zobaczysz, że metoda musi sprawdzić różne rzeczy przed jej uruchomieniem. Niektóre z tych kontroli są niepotrzebne w przypadku pętli kopiowania, w zależności od statycznych typów tablic.clone()
okazuje się najszybszy dla 250 000 elementów.src.clone()
jest bardziej czytelny i ma znacznie mniejszą szansę na błąd niż przydzielenie nowej tablicy i zrobienie tegoarraycopy
. (A także zdarza się, że jest szybki.)możesz użyć
także.
źródło
Jeśli chcesz zrobić kopię:
To jest odpowiednie rozwiązanie:
Arrays.copyOf
może być szybszy niża.clone()
na małych tablicach. Oba elementy kopiują równie szybko, aleObject
funkcja clone () zwraca, więc kompilator musi wstawić niejawne rzutowanieint[]
. Możesz to zobaczyć w kodzie bajtowym, coś takiego:źródło
Ładne wyjaśnienie z http://www.journaldev.com/753/how-to-copy-arrays-in-java
Metody kopiowania tablicy Java
źródło
Mam wrażenie, że te wszystkie „lepsze sposoby kopiowania tablicy” tak naprawdę nie rozwiążą twojego problemu.
Mówisz
Patrząc na tę pętlę, nie ma oczywistego powodu, aby nie działała ... chyba że:
a
ib
tablice pomieszane (npa
ib
odnoszą się do tej samej tablicy), luba
tablicę.W obu przypadkach alternatywne sposoby kopiowania nie rozwiążą podstawowego problemu.
Poprawka dla pierwszego scenariusza jest oczywista. W drugim scenariuszu musisz wymyślić jakiś sposób synchronizacji wątków. Klasy atomowe nie pomagają, ponieważ nie mają żadnych konstruktorów kopiowania atomowego ani metod klonowania, ale synchronizacja przy użyciu prymitywnego muteksu wystarczy.
(W twoim pytaniu są wskazówki, które prowadzą mnie do przekonania, że to rzeczywiście jest związane z wątkami; np. Twoje zdanie
a
ciągle się zmienia).źródło
Możesz spróbować użyć Arrays.copyOf () w Javie
źródło
Wszystkie rozwiązania, które wywołują długość z tablicy, dodaj kod nadmiarowy zerowy warcaby rozważ przykład:
Zalecam, aby nie wymyślać koła i używać klasy użytkowej, w której wszystkie niezbędne kontrole zostały już wykonane. Rozważ ArrayUtils z apache commons. Twój kod staje się krótszy:
Fotografia Apache można znaleźć tam
źródło
Możesz także użyć
Arrays.copyOfRange
.Przykład :
Ta metoda jest podobna
Arrays.copyOf
, ale jest bardziej elastyczna. Oba używająSystem.arraycopy
pod maską.Zobacz :
źródło
W przypadku bezpiecznej dla tablicy kopii tablicy można użyć opcjonalnej
Object.clone()
metody opisanej w tej odpowiedzi .źródło
Optional
obiekt jest tylko pustym obiektem z odniesieniem do istniejącej tablicy. Jeśli chodzi o wpływ na wydajność, powiedziałbym, że przedwczesne jest twierdzenie, że jest to wpływ, ponieważ ten typ konstrukcji jest dobrym kandydatem do wbudowania w JVM, a następnie nie większy wpływ niż inne metody. To kwestia stylu (programowanie funkcjonalne kontra programowanie proceduralne, ale nie tylko), aby uznać to za bardziej skomplikowane lub nie.Jeśli trzeba pracować z surowych tablic, a nie
ArrayList
wtedyArrays
ma to, czego potrzebujesz. Jeśli spojrzysz na kod źródłowy, są to absolutnie najlepsze sposoby na uzyskanie kopii tablicy. Mają sporo programowania obronnego, ponieważSystem.arraycopy()
metoda rzuca wiele niesprawdzonych wyjątków, jeśli podajesz jej nielogiczne parametry.Możesz użyć jednego,
Arrays.copyOf()
który skopiuje od pierwszego doNth
elementu do nowej krótszej tablicy.lub
Arrays.copyOfRange()
zrobi lewę:Jak widać, obie są po prostu funkcjami otoki
System.arraycopy
z logiką obronną, że to, co próbujesz zrobić, jest prawidłowe.System.arraycopy
jest absolutnie najszybszym sposobem kopiowania tablic.źródło
Miałem podobny problem z tablicami 2D i skończyłem tutaj. Kopiowałem główną tablicę i zmieniałem wartości wewnętrznych tablic i byłem zaskoczony, gdy wartości zmieniły się w obu kopiach. Zasadniczo obie kopie były niezależne, ale zawierały odniesienia do tych samych wewnętrznych tablic i musiałem wykonać szereg kopii wewnętrznych tablic, aby uzyskać to, czego chciałem.
Prawdopodobnie nie jest to problem PO, ale mam nadzieję, że nadal może być pomocny.
źródło