Nur einen Teil eines Arrays in Java abrufen?

274

Ich habe ein Array von Ganzzahlen in Java, ich möchte nur einen Teil davon verwenden. Ich weiß, dass Sie in Python so etwas wie dieses Array [index:] ausführen können, und es gibt das Array aus dem Index zurück. Ist so etwas in Java möglich.

Borut Flis
quelle

Antworten:

443

Die Länge eines Arrays in Java ist unveränderlich. Sie müssen also das gewünschte Teil als neues Array kopieren.
Verwenden Sie die copyOfRangeMethode aus der Klasse java.util.Arrays :

int[] newArray = Arrays.copyOfRange(oldArray, startIndex, endIndex);

startIndex ist der Anfangsindex des zu kopierenden Bereichs einschließlich.
endIndex ist der endgültige Index des zu kopierenden Bereichs, exklusiv. (Dieser Index kann außerhalb des Arrays liegen.)

Z.B:

   //index   0   1   2   3   4
int[] arr = {10, 20, 30, 40, 50};
Arrays.copyOfRange(arr, 0, 2);          // returns {10, 20}
Arrays.copyOfRange(arr, 1, 4);          // returns {20, 30, 40}
Arrays.copyOfRange(arr, 2, arr.length); // returns {30, 40, 50} (length = 5)
elias
quelle
scheint es eine Größenbeschränkung zu geben? nur das funktioniert: Arrays.copyOfRange(Thread.currentThread().getStackTrace(),1,255)da ich anstelle von 255 nicht Integer.MAX_VALUE verwenden kann, falls ich nicht die tatsächliche Länge erhalten möchte
Aquarius Power
@AquariusPower Die Größenbeschränkung ist die Arraygröße und kann größer als 255 sein. Sie können nur keine Größe angeben, die endIndexgrößer als die Größe des Arrays ist, das als erstes Argument übergeben wurde. Wenn Sie also eine vollständige Kopie wünschen, erstellen Sie eine Variable, die auf dieses Array verweist, und verwenden Sie Arrays.copyOfRange(var, 0, var.length)oderArrays.copyOf(var, var.length)
elias
Ich müsste eine lokale Variable für das Stacktrace-Subarray erstellen, aber ich habe festgestellt, dass dies funktioniert !!! Arrays.copyOfRange(Thread.currentThread().getStackTrace(),1,Short.MAX_VALUE)
Aquarius Power
Sei vorsichtig mit ArrayIndexOutOfBoundsException.
Elias
1
Es gibt noch ein anderes Problem. Was ist, wenn ich das String-Array mit einer Länge von beispielsweise 500 KB in die Subarrays mit 250 KB aufteilen muss? Diese Methode akzeptiert Interegr, das bei 65000 maximal ist.
Vishnu Dahatonde
31

Sie können Ihr Array als Liste umschließen und eine Unterliste davon anfordern.

MyClass[] array = ...;
List<MyClass> subArray = Arrays.asList(array).subList(index, array.length);
K-Ballo
quelle
22

Ja, du kannst verwenden Arrays.copyOfRange verwenden

Es funktioniert ungefähr genauso (beachten Sie, dass es eine Kopie gibt: Sie ändern das ursprüngliche Array nicht).

Denys Séguret
quelle
2
Wenn Sie jedoch keine explizite Kopie erstellen möchten, müssen Sie ein Listund ein verwenden, subListwie in der Antwort von @ K-ballo beschrieben.
Louis Wasserman
Das stimmt. Java verfügt nicht über die Array-Slicing-Funktionen, die modernere Sprachen bieten.
Denys Séguret
Ich bin mir nicht sicher, ob ich es so ausdrücken würde, aber ... ja, Java bietet kein Array-Slicing an. (Das heißt, dieser Ansatz bietet einige Vorteile: Reduzierte Möglichkeiten für Speicherlecks, reduzierter Array-Overhead durch Vermeidung der zusätzlichen Felder usw. Sie könnten in beide Richtungen gehen.)
Louis Wasserman
Ja, du hast wieder recht (und ich habe nicht versucht, einen Flammenkrieg zu beginnen;)). Das Schneiden macht GC sehr komplex. Und als Java das objektbasierte implizite Schneiden in Strings versuchte, wurde deutlicher, dass dies gefährlich war .
Denys Séguret
10

Du kannst es versuchen:

System.arraycopy(sourceArray, 0, targetArray, 0, targetArray.length);// copies whole array

// copies elements 1 and 2 from sourceArray to targetArray
System.arraycopy(sourceArray, 1, targetArray, 0, 2); 

Siehe javadoc für System .

StvnBrkdll
quelle
3
Ich finde es einfach toll, wie genau Arrays.copyOf () und Arrays.copyOfRange () tatsächlich implementiert werden (ohne Grenzüberprüfung) und dennoch keine Stimmen erhalten, während die etwas höheren Overhead-Utility-Methoden-Wrapper trotz System.arraycopy-Datierung die Stimmen sammeln zurück zu 1995.
Dave
1
Ich denke, es sieht für manche einfach nicht "modern" genug aus.
Dave
Ich gehe gerne auf die alte Schule, keine glänzenden Schnickschnack, nur die erforderlichen Maschinen. Wie memcpy in C
StvnBrkdll
Die Verwendung von arrays.copyOfRange () erhöht jedoch die Lesbarkeit und verringert die Möglichkeit von Fehlern erheblich.
Florian F
7

Wenn Sie Java 1.6 oder höher verwenden, können Sie Arrays.copyOfRangeeinen Teil des Arrays kopieren. Aus dem Javadoc:

Kopiert den angegebenen Bereich des angegebenen Arrays in ein neues Array. Der Anfangsindex des Bereichs (von) muss zwischen Null und original.lengtheinschließlich liegen. Der Wert at original[from]wird in das Anfangselement der Kopie eingefügt (sofern from == original.lengthoder nicht from == to). Werte von nachfolgenden Elementen im ursprünglichen Array werden in nachfolgenden Elementen in der Kopie platziert. Der endgültige Index des Bereichs ( to), der größer oder gleich sein muss from, kann größer sein als original.length. In diesem Fall falsewird er in alle Elemente der Kopie eingefügt, deren Index größer oder gleich ist original.length - from. Die Länge des zurückgegebenen Arrays beträgt to - from.

Hier ist ein einfaches Beispiel :

/**
 * @Program that Copies the specified range of the specified array into a new 
 * array.
 * CopyofRange8Array.java 
 * Author:-RoseIndia Team
 * Date:-15-May-2008
 */
import java.util.*;
public class CopyofRange8Array {
    public static void main(String[] args) {
       //creating a short array
       Object T[]={"Rose","India","Net","Limited","Rohini"};
        // //Copies the specified  short array upto specified range,
        Object T1[] = Arrays.copyOfRange(T, 1,5);
        for (int i = 0; i < T1.length; i++) 
            //Displaying the Copied short array upto specified range
            System.out.println(T1[i]);
    }

}
Justin Ethier
quelle
3

Check out copyOfRange ; und Beispiel:

int[] arr2 = Arrays.copyOfRange(arr,0,3);
dcp
quelle
-2

Sie können die subList(int fromIndex, int toIndex)Methode für Ihre Ganzzahlen arr verwenden, ungefähr so:

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Integer> arr = new ArrayList<>();
        arr.add(1);
        arr.add(2);
        arr.add(3);
        arr.add(4);
        List<Integer> partialArr = arr.subList(1, 3);

        // print the subArr
        for (Integer i: partialArr)
            System.out.println(i + " ");
    }
}

Ausgabe wird sein : 2 3.

Beachten Sie, dass die subList(int fromIndex, int toIndex)Methode für die 2. empfangene Variable (var2 - 1) minus 1 ausführt. Ich weiß nicht genau warum, aber genau das passiert, um möglicherweise die Wahrscheinlichkeit zu verringern, dass die Größe des Arrays überschritten wird.

A. Ab
quelle