Ik heb een array a
die constant wordt bijgewerkt. Laten we zeggen a = [1,2,3,4,5]
. Ik moet een exacte kopie maken van a
en deze b
noemen. Als a
zou veranderen in [6,7,8,9,10]
, zou b
nog steeds [1,2,3,4,5]
. Wat is de beste manier om dit te doen? Ik heb een for
-lus geprobeerd, zoals:
for(int i=0; i<5; i++) {
b[i]=a[i];
}
maar dat lijkt niet goed te werken. Gebruik geen geavanceerde termen zoals deep copy, enz., want ik weet niet wat dat betekent.
Antwoord 1, autoriteit 100%
Je kunt proberen System.arraycopy()
int[] src = new int[]{1,2,3,4,5};
int[] dest = new int[5];
System.arraycopy( src, 0, dest, 0, src.length );
Maar in de meeste gevallen is het waarschijnlijk beter om clone() te gebruiken:
int[] src = ...
int[] dest = src.clone();
Antwoord 2, autoriteit 41%
u kunt gebruiken
int[] a = new int[]{1,2,3,4,5};
int[] b = a.clone();
ook.
Antwoord 3, autoriteit 32%
Als u een kopie wilt maken van:
int[] a = {1,2,3,4,5};
Dit is de manier om te gaan:
int[] b = Arrays.copyOf(a, a.length);
Arrays.copyOf
is mogelijk sneller dan a.clone()
op kleine arrays. Beide kopieerelementen zijn even snel, maar clone() retourneert Object
, dus de compiler moet een impliciete cast invoegen in int[]
. Je kunt het zien in de bytecode, ongeveer als volgt:
ALOAD 1
INVOKEVIRTUAL [I.clone ()Ljava/lang/Object;
CHECKCAST [I
ASTORE 2
Antwoord 4, autoriteit 11%
Leuke uitleg van http://www.journaldev.com /753/hoe-matrices-in-java te kopiëren
Java-array-kopieermethoden
Object.clone(): Object klasse biedt clone() methode en aangezien array
in java is ook een object, u kunt deze methode gebruiken om volledig te bereiken
array kopie. Deze methode is niet geschikt voor u als u een gedeeltelijke kopie wilt van
de array.System.arraycopy(): systeemklasse arraycopy() is de beste manier om
gedeeltelijke kopie van een array. Het biedt u een gemakkelijke manier om de
totaal aantal te kopiëren elementen en de bron- en doelarray
indexposities. Bijvoorbeeld System.arraycopy(bron, 3, bestemming,
2, 5)kopieert 5 elementen van bron naar bestemming, te beginnen vanaf
3e index van bron tot 2e index van bestemming.Arrays.copyOf():Als u de eerste paar elementen van een array of
volledige kopie van array, kunt u deze methode gebruiken. Het is duidelijk niet
veelzijdig zoals System.arraycopy() maar het is ook niet verwarrend en gemakkelijk
te gebruiken.Arrays.copyOfRange(): als u enkele elementen van een array wilt
gekopieerd, waarbij de startindex niet 0 is, kunt u deze methode gebruiken om te kopiëren
gedeeltelijke array.
Antwoord 5, Autoriteit 6%
Ik heb het gevoel dat al deze “betere manieren om een array te kopiëren” niet echt uw probleem op te lossen.
u zegt
Ik probeerde een voor lus zoals […] maar dat lijkt niet correct te werken?
Kijkend naar die lus, er is geen voor de hand liggende reden omdat het niet werkt … Tenzij:
- U hebt op de een of andere manier de
a
enb
arrays in de war (bijv.a
ENb
verwijzen naar hetzelfde array), of - Uw aanvraag is multi-threaded en verschillende threads lezen en bijwerken van de
a
array gelijktijdig.
In beide gevallen zullen alternatieve manieren van het kopiëren het onderliggende probleem niet oplossen.
De oplossing voor het eerste scenario is duidelijk. Voor het tweede scenario moet je een manier vinden om de draden te synchroniseren. Atomic Array-klassen helpen niet omdat ze geen atomaire kopie-constructeurs of kloonmethoden hebben, maar synchroniseren met behulp van een primitieve mutex zullen de truc doen.
(er zijn hints in uw vraag die me ertoe leiden dat dit inderdaad gerelateerd is, b.v. Uw verklaring dat a
constant verandert.)
Antwoord 6, Autoriteit 3%
U kunt proberen arrays.copyof () in Java
te gebruiken
int[] a = new int[5]{1,2,3,4,5};
int[] b = Arrays.copyOf(a, a.length);
Antwoord 7, Autoriteit 2%
Alle oplossing die lengte van array bellen, voeg uw code redundant NULL CheckersSconsider Voorbeeld:
int[] a = {1,2,3,4,5};
int[] b = Arrays.copyOf(a, a.length);
int[] c = a.clone();
//What if array a comes as local parameter? You need to use null check:
public void someMethod(int[] a) {
if (a!=null) {
int[] b = Arrays.copyOf(a, a.length);
int[] c = a.clone();
}
}
Ik raad u aan om het wiel niet te bedenken en gebruik van hulpprogramma’s waar alle benodigde controles al hebben uitgevoerd. Overweeg arrayutils van Apache Commons. Je codeert wordt korter:
public void someMethod(int[] a) {
int[] b = ArrayUtils.clone(a);
}
Apache Commons U kunt daar
Antwoord 8, Autoriteit 2%
U kunt Arrays.copyOfRange
.
voorbeeld :
public static void main(String[] args) {
int[] a = {1,2,3};
int[] b = Arrays.copyOfRange(a, 0, a.length);
a[0] = 5;
System.out.println(Arrays.toString(a)); // [5,2,3]
System.out.println(Arrays.toString(b)); // [1,2,3]
}
Deze methode is vergelijkbaar met Arrays.copyOf
, maar het is flexibeler. Beide gebruiken System.arraycopy
onder de kap.
Zie :
- https://docs.oracle.com/ Javase / 8 / DOCS / API / JAVA / UTIL / ARRAYS.HTML
- https://docs.oracle.com/javase/tutorial/ Java / Nutsandbolts / Arrays.html
- http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/util/arrays.java?av=f
Antwoord 9
Voor een null-safe-kopie van een array, kunt u ook een optioneel gebruiken met de Object.clone()
methode in deze Antwoord .
int[] arrayToCopy = {1, 2, 3};
int[] copiedArray = Optional.ofNullable(arrayToCopy).map(int[]::clone).orElse(null);
Antwoord 10
Als u moet werken met rauwe arrays en niet ArrayList
dan Arrays
heeft wat u nodig hebt. Als u naar de broncode kijkt, zijn dit de absoluut de beste manieren om een kopie van een array te krijgen. Ze hebben een goed bit van defensieve programmering omdat de System.arraycopy()
Method met veel niet-gecontroleerde uitzonderingen gooit als u IT ILLOGICAL PARAMETERS voedt.
u kunt Arrays.copyOf()
die van de eerste naar Nth
-element naar de nieuwe kortere array kopiëren.
public static <T> T[] copyOf(T[] original, int newLength)
Kopieert de opgegeven array, het afknippen of opvullen met nulls (als
noodzakelijk), zodat de kopie de opgegeven lengte heeft. Voor alle indices die
zijn geldig in zowel de originele array als de kopie, de twee arrays zullen
bevatten identieke waarden. Voor eventuele indices die geldig zijn in de kopie
Maar niet het origineel, de kopie bevat null. Dergelijke indices zullen
bestaan als en alleen als de opgegeven lengte groter is dan die van de
Originele array. De resulterende array is van precies dezelfde klas als
de originele array.
2770
2771 public static <T,U> T[] More ...copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
2772 T[] copy = ((Object)newType == (Object)Object[].class)
2773 ? (T[]) new Object[newLength]
2774 : (T[]) Array.newInstance(newType.getComponentType(), newLength);
2775 System.arraycopy(original, 0, copy, 0,
2776 Math.min(original.length, newLength));
2777 return copy;
2778 }
of Arrays.copyOfRange()
zal ook de kunst doen:
public static <T> T[] copyOfRange(T[] original, int from, int to)
Kopieert het opgegeven bereik van de opgegeven array in een nieuwe array.
De eerste index van het bereik (van) moet tussen nul liggen en
Original.Lengte, inclusief. De waarde bij origineel [van] is geplaatst
het initiële element van de kopie (tenzij van == origineel.lengte of
van == naar). Waarden van volgende elementen in de originele array zijn
in de volgende elementen in de kopie geplaatst. De laatste index van de
bereik (naar), dat groter moet zijn dan of gelijk aan van, kan zijn
groter dan origineel.length, in welk geval null in alles wordt geplaatst
Elementen van de kopie waarvan de index groter is dan of gelijk aan
Origineel.Lengte – van. De lengte van de geretourneerde array zal zijn –
van. De resulterende array is van precies dezelfde klas als het origineel
array.
3035 public static <T,U> T[] More ...copyOfRange(U[] original, int from, int to, Class<? extends T[]> newType) {
3036 int newLength = to - from;
3037 if (newLength < 0)
3038 throw new IllegalArgumentException(from + " > " + to);
3039 T[] copy = ((Object)newType == (Object)Object[].class)
3040 ? (T[]) new Object[newLength]
3041 : (T[]) Array.newInstance(newType.getComponentType(), newLength);
3042 System.arraycopy(original, from, copy, 0,
3043 Math.min(original.length - from, newLength));
3044 return copy;
3045 }
Zoals je kunt zien, zijn beide slechts wrapper-functies over System.arraycopy
met defensieve logica dat wat je probeert te doen geldig is.
System.arraycopy
is de absoluut snelste manier om arrays te kopiëren.
Antwoord 11
Ik had een soortgelijk probleem met 2D-arrays en eindigde hier.
Ik kopieerde de hoofdarray en veranderde de waarden van de binnenste arrays en was verrast toen de waarden in beide kopieën veranderden. In principe waren beide kopieën onafhankelijk, maar bevatten ze verwijzingen naar dezelfde binnenste arrays en ik moest een reeks kopieën van de binnenste arrays maken om te krijgen wat ik wilde.
Dit wordt soms een diepe kopie genoemd. Dezelfde term “diepe kopie” kan ook een heel andere en aantoonbaar complexere betekenis hebben, wat verwarrend kan zijn, vooral voor iemand die niet uitzoekt waarom hun gekopieerde arrays zich niet gedragen zoals zou moeten. Het is waarschijnlijk niet het probleem van de OP, maar ik hoop dat het toch nuttig kan zijn.