Wie kann man ein Array kürzen? v.5.0
Arrays haben fixe Größen. Sie können auf einfache Weise weder verlängert noch gekürzt werden. Eine Längenänderung erfordert somit ein klein wenig mehr Aufwand und kann nur durch ein Kopieren der relevanten Inhalte erfolgen.
Die einfachste Form besteht wohl darin, die Anzahl der neu zu speichernden Elemente auszulesen und ein neues Array dieser Länge zu erzeugen, in das die Werte anschließend eingelesen werden. Diese Methode ist bei bei primitiven Datentypen und begrenzter Arraylänge ausreichend schnell.
Im Beispiel wird ein int
-Array der Größe
10 erstellt, von dem nur die geraden Werte in einem entsprechend
kürzeren Array gespeichert werden sollen. Hierzu wird die
Länge des benötigten Arrays in einer Schleife durch
eine Zählvariable ermittelt, ein zweites dieser Länge
erstellt und anschließend die Daten eingelesen.
public class ArrayKuerzen {
public static void main(String[] args) {
int[] longArr = {5, 17, 23, 8, 18, 36, 56, 9, 10, 12};
int count = 0;
for(int i : longArr) {
if(i%2==0)
count++;
}
int[] shortArr = new int[count];
int k=0;
for(int i : longArr) {
if(i%2==0) {
shortArr[k] = i;
k++;
}
}
for(int i : shortArr)
System.out.println(i);
}
}
Im zweiten Beispiel wird zunächst ein leeres
temporäres Array identischer Länge erstellt. In einer
for-Schleife wird das Ausgangs-Array ebenfalls durchlaufen und
alle geraden Werte der Reihe nach im temporären Array
gespeichert. Wie oben erfasst dabei die Zählvariable count
nach Beendigung der Schleife die Länge des kurzen
Zielarrays.
Im nächsten Schritt wird das Zielarray als
leeres Array gleichen Typs mit Hilfe der Zählvariablen
erstellt. Es besitzt somit nur die gewünschte kürzere
Länge. Die statische Methode arraycopy()
der
Klasse System
erstellt schließlich das
endgültige gekürzte Array. Hierzu werden ihr fünf
Parameter übergeben. Der Reihe nach sind dies:
- das temporäre Array
- die Startposition im temporären Array (hier 0)
- das noch leere Zielarray
- die Startposition im Zielarray (hier 0)
- die Länge des zu kopierenden Abschnitts (hier die Gesamtlänge des temporären Arrays)
Die Methode erstellt schließlich eine Kopie des gewünschten Arrays, deren Werte im Beispiel ausgegeben werden.
public class ArrayKuerzen1 {
public static void main(String[] args) {
int[] longArr = {5, 17, 23, 8, 18, 36, 56, 9, 10, 12};
int[] evenArr = new int[longArr.length];
int count = 0;
for(int i : longArr) {
if(i%2==0)
evenArr[count++] = i;
}
int[] shortArr = new int[count];
System.arraycopy(evenArr, 0, shortArr, 0, count);
for(int i : shortArr)
System.out.println(i);
}
}
Beide Varianten nehmen sich nicht viel hinsichtlich ihrer
Geschwindigkeit, wenn es um primitive Datentypen geht.
Vergleicht man das Tempo jedoch bei beiden Varianten z.B.
für String
‑Arrays großer
Länge, so besitzt die zweite Möglichkeit erhebliche
Geschwindigkeitsvorteile.
Die beiden folgenden Beispiele beruhen darauf, dass
zunächst ein Array der Größe 10000000 mit
Pseudo-Zufalls-Strings der Länge 4 erzeugt wird. Dies
geschieht bei beiden identisch über den Umweg der
Generierung von Character-Arrays, die den Bereich der
lateinischen Kleinbuchstaben abdecken. Nach deren Fertigstellung
beginnt die Zeitmessung. Wie auch beim Beispiel mit primitiven int
‑Typen
wird über den Stringvergleich die Anzahl der zum Kopieren
relevanten Elemente ermittelt, ein entsprechendes
verkürztes Array erstellt und dann die Werte dort
eingelesen. Nach Abschluss dieses Vorgangs wird die Zeitmessung
gestoppt. Bei mehreren Versuchen ergaben sich hierbei Laufzeiten
von ca. 130 ms.
import java.util.Random;
public class ArrayKuerzen2 {
public static void main(String[] args) {
String[] longArr = new String[10000000];
char[] cArr;
for(int i=0; i< longArr.length; i++){
cArr = new char[4];
for(int j=0; j< cArr.length; j++)
cArr[j] = (char) (new Random().nextInt(26) + 97);
longArr[i] = new String(cArr);
}
int count = 0;
final long timeStart = System.currentTimeMillis();
for(String s : longArr) {
if(s.equals("abcd"))
count++;
}
String[] shortArr = new String[count];
int k=0;
for(String s : longArr) {
if(s.equals("abcd")) {
shortArr[k++] = s;
}
}
final long timeEnd = System.currentTimeMillis();
System.out.println("Verlaufszeit des Kopierens: " + (timeEnd - timeStart) + " Millisek.");
System.out.println("L\u00e4nge des neuen Arrays: " + count);
}
}
Das letzte Beispiel entspricht, abgesehen vom oben geschilderten
Erzeugen des Ausgangsarrays, dem analogen Beispiel mit int
‑Werten.
Wie bei diesem wird hier die Methode System.arraycopy()
verwendet. Die Laufzeit beträgt bei Versuchen hier ca. 70
bis 90 ms und ist somit signifikant kürzer. Man beachte,
dass der String-Vergleich mit equals()
bei den
beiden letzten Beispielen identisch ist, sodass der zeitliche
Unterschied auf den Kopiervorgang zurückzuführen ist.
import java.util.Random;
public class ArrayKuerzen3 {
public static void main(String[] args) {
String[] longArr = new String[10000000];
String[] evenArr = new String[longArr.length];
char[] cArr;
for (int i = 0; i < longArr.length; i++) {
cArr = new char[4];
for (int j = 0; j < cArr.length; j++)
cArr[j] = (char) (new Random().nextInt(26) + 97);
longArr[i] = new String(cArr);
}
int count = 0;
final long timeStart = System.currentTimeMillis();
for (String s : longArr) {
if (s.equals("abcd")) {
evenArr[count++] = s;
}
}
String[] shortArr = new String[count];
System.arraycopy(evenArr, 0, shortArr, 0, count);
final long timeEnd = System.currentTimeMillis();
System.out.println("Verlaufszeit des Kopierens: "
+ (timeEnd - timeStart) + " Millisek.");
System.out.println("L\u00e4nge des neuen Arrays: " + count);
}
}
Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.