Array-Operationen in Java

1. Übersicht

Jeder Java-Entwickler weiß, dass es nicht immer einfach ist, eine saubere und effiziente Lösung für die Arbeit mit Array-Operationen zu erstellen. Trotzdem sind sie ein zentrales Element im Java-Ökosystem - und wir müssen uns mehrmals mit ihnen befassen.

Aus diesem Grund ist es gut, einen „Spickzettel“ zu haben - eine Zusammenfassung der gängigsten Verfahren, mit denen wir das Rätsel schnell lösen können. Dieses Tutorial ist in solchen Situationen hilfreich.

2. Arrays und Hilfsklassen

Bevor Sie fortfahren, sollten Sie wissen, was ein Array in Java ist und wie es verwendet wird. Wenn Sie zum ersten Mal in Java damit arbeiten, empfehlen wir Ihnen, sich diesen vorherigen Beitrag anzusehen, in dem wir alle grundlegenden Konzepte behandelt haben.

Bitte beachten Sie, dass die grundlegenden Operationen, die ein Array unterstützt, in gewisser Weise begrenzt sind. Es ist nicht ungewöhnlich, dass komplexe Algorithmen relativ einfache Aufgaben ausführen, wenn es um Arrays geht.

Aus diesem Grund verwenden wir für die meisten unserer Vorgänge Hilfsklassen und -methoden, um uns zu unterstützen: die von Java bereitgestellte Arrays- Klasse und die ArrayUtils- Klasse von Apache .

Um letzteres in unser Projekt aufzunehmen, müssen wir die Apache Commons-Abhängigkeit hinzufügen:

 org.apache.commons commons-lang3 3.8.1 

Wir können die neueste Version dieses Artefakts auf Maven Central überprüfen.

3. Holen Sie sich das erste und letzte Element eines Arrays

Dies ist eine der häufigsten und einfachsten Aufgaben, da Arrays nach Index sortiert werden.

Beginnen wir mit der Deklaration und Initialisierung eines int- Arrays, das in allen unseren Beispielen verwendet wird (sofern nicht anders angegeben):

int[] array = new int[] { 3, 5, 2, 5, 14, 4 };

Wenn Sie wissen, dass das erste Element eines Arrays dem Indexwert 0 zugeordnet ist und dass es ein Längenattribut hat , das wir verwenden können, ist es einfach herauszufinden, wie wir diese beiden Elemente erhalten können:

int firstItem = array[0]; int lastItem = array[array.length - 1];

4. Holen Sie sich einen zufälligen Wert aus einem Array

Mit dem Objekt java.util.Random können wir leicht jeden Wert aus unserem Array abrufen:

int anyValue = array[new Random().nextInt(array.length)];

5. Hängen Sie ein neues Element an ein Array an

Wie wir wissen, haben Arrays eine feste Größe von Werten. Daher können wir nicht einfach einen Artikel hinzufügen und dieses Limit überschreiten.

Wir müssen zunächst ein neues, größeres Array deklarieren und die Elemente des Basisarrays in das zweite kopieren.

Glücklicherweise bietet die Arrays- Klasse eine praktische Methode, um die Werte eines Arrays in eine neue Struktur unterschiedlicher Größe zu replizieren:

int[] newArray = Arrays.copyOf(array, array.length + 1); newArray[newArray.length - 1] = newItem;

Wenn in unserem Projekt auf die ArrayUtils- Klasse zugegriffen werden kann, können wir optional die add-Methode (oder die addAll- Alternative) verwenden, um unser Ziel in einer einzeiligen Anweisung zu erreichen:

int[] newArray = ArrayUtils.add(array, newItem);

Wie wir uns vorstellen können, ändert diese Methode das ursprüngliche Array- Objekt nicht. wir müssen seine Ausgabe einer neuen Variablen zuweisen.

6. Fügen Sie einen Wert zwischen zwei Werten ein

Aufgrund des Zeichens für indizierte Werte ist das Einfügen eines Elements in ein Array zwischen zwei anderen keine triviale Aufgabe.

Apache betrachtete dies als ein typisches Szenario und implementierte eine Methode in seiner ArrayUtils- Klasse, um die Lösung zu vereinfachen:

int[] largerArray = ArrayUtils.insert(2, array, 77);

Wir müssen den Index angeben, in den wir den Wert einfügen möchten, und die Ausgabe ist ein neues Array, das eine größere Anzahl von Elementen enthält.

Das letzte Argument ist ein variables Argument (auch bekannt als vararg ), daher können wir eine beliebige Anzahl von Elementen in das Array einfügen.

7. Vergleichen Sie zwei Arrays

Obwohl Arrays Objekte sind und daher eine Equals- Methode bereitstellen , verwenden sie die Standardimplementierung und stützen sich nur auf die Referenzgleichheit.

Wir können trotzdem aufrufen , um die java.util.Arrays ' gleich Methode zu überprüfen , ob zwei Array - Objekte , die die gleichen Werte enthalten:

boolean areEqual = Arrays.equals(array1, array2);

Hinweis: Diese Methode ist für gezackte Arrays nicht wirksam. Die geeignete Methode zur Überprüfung der Gleichheit mehrdimensionaler Strukturen ist die von Arrays.deepEquals .

8. Überprüfen Sie, ob ein Array leer ist

Dies ist eine unkomplizierte Zuordnung im Auge hat , dass wir das können Länge Attribut von Arrays:

boolean isEmpty = array == null || array.length == 0;

Darüber hinaus haben wir in der ArrayUtils-Hilfsklasse eine null-sichere Methode , die wir verwenden können:

boolean isEmpty = ArrayUtils.isEmpty(array);

Diese Funktion hängt immer noch von der Länge der Datenstruktur ab, die auch Nullen und leere Unterarrays als gültige Werte betrachtet. Daher müssen wir diese Randfälle im Auge behalten:

// These are empty arrays Integer[] array1 = {}; Integer[] array2 = null; Integer[] array3 = new Integer[0]; // All these will NOT be considered empty Integer[] array3 = { null, null, null }; Integer[][] array4 = { {}, {}, {} }; Integer[] array5 = new Integer[3];

9. So mischen Sie die Elemente eines Arrays

Um die Elemente in einem Array zu mischen, können wir die Funktion von ArrayUtil verwenden :

ArrayUtils.shuffle(array);

This is a void method and operates on the actual values of the array.

10. Box and Unbox Arrays

We often come across methods that support only Object-based arrays.

Again the ArrayUtils helper class comes in handy to get a boxed version of our primitive array:

Integer[] list = ArrayUtils.toObject(array);

The inverse operation is also possible:

Integer[] objectArray = { 3, 5, 2, 5, 14, 4 }; int[] array = ArrayUtils.toPrimitive(objectArray);

11. Remove Duplicates from an Array

The easiest way of removing duplicates is by converting the array to a Set implementation.

As we may know, Collections use Generics and hence don't support primitive types.

For this reason, if we're not handling object-based arrays as in our example, we'll first need to box our values:

// Box Integer[] list = ArrayUtils.toObject(array); // Remove duplicates Set set = new HashSet(Arrays.asList(list)); // Create array and unbox return ArrayUtils.toPrimitive(set.toArray(new Integer[set.size()]));

Note: we can use other techniques to convert between an array and a Set object as well.

Also, if we need to preserve the order of our elements, we must use a different Set implementation, such as a LinkedHashSet.

12. How to Print an Array

Same as with the equals method, the array's toString function uses the default implementation provided by the Object class, which isn't very useful.

Both Arrays and ArrayUtils classes ship with their implementations to convert the data structures to a readable String.

Apart from the slightly different format they use, the most important distinction is how they treat multi-dimensional objects.

The Java Util's class provides two static methods we can use:

  • toString: doesn't work well with jagged arrays
  • deepToString: supports any Object-based arrays but doesn't compile with primitive array arguments

On the other hand, Apache's implementation offers a single toString method that works correctly in any case:

String arrayAsString = ArrayUtils.toString(array);

13. Map an Array to Another Type

It's often useful to apply operations on all array items, possibly converting them to another type of object.

With this objective in mind, we'll try to create a flexible helper method using Generics:

public static  U[] mapObjectArray( T[] array, Function function, Class targetClazz) { U[] newArray = (U[]) Array.newInstance(targetClazz, array.length); for (int i = 0; i < array.length; i++) { newArray[i] = function.apply(array[i]); } return newArray; }

If we don't use Java 8 in our project, we can discard the Function argument, and create a method for each mapping that we need to carry out.

We can now reuse our generic method for different operations. Let's create two test cases to illustrate this:

@Test public void whenMapArrayMultiplyingValues_thenReturnMultipliedArray() { Integer[] multipliedExpectedArray = new Integer[] { 6, 10, 4, 10, 28, 8 }; Integer[] output = MyHelperClass.mapObjectArray(array, value -> value * 2, Integer.class); assertThat(output).containsExactly(multipliedExpectedArray); } @Test public void whenMapDividingObjectArray_thenReturnMultipliedArray() { Double[] multipliedExpectedArray = new Double[] { 1.5, 2.5, 1.0, 2.5, 7.0, 2.0 }; Double[] output = MyHelperClass.mapObjectArray(array, value -> value / 2.0, Double.class); assertThat(output).containsExactly(multipliedExpectedArray); }

For primitive types, we'll have to box our values first.

As an alternative, we can turn to Java 8's Streams to carry out the mapping for us.

We'll need to transform the array into a Stream of Objects first. We can do so with the Arrays.stream method.

For example, if we want to map our int values to a custom String representation, we'll implement this:

String[] stringArray = Arrays.stream(array) .mapToObj(value -> String.format("Value: %s", value)) .toArray(String[]::new);

14. Filter Values in an Array

Filtering out values from a collection is a common task that we might have to perform in more than one occasion.

This is because at the time we create the array that will receive the values, we can't be sure of its final size. Therefore, we'll rely on the Streams approach again.

Imagine we want to remove all odd numbers from an array:

int[] evenArray = Arrays.stream(array) .filter(value -> value % 2 == 0) .toArray();

15. Other Common Array Operations

There are, of course, plenty of other array operations that we might need to perform.

Apart from the ones shown in this tutorial, we've extensively covered other operations in the dedicated posts:

  • Check if a Java Array Contains a Value
  • How to Copy an Array in Java
  • Removing the First Element of an Array
  • Finding the Min and Max in an Array with Java
  • Find Sum and Average in a Java Array
  • How to Invert an Array in Java
  • Verbinden und Teilen von Arrays und Sammlungen in Java
  • Kombinieren verschiedener Arten von Sammlungen in Java
  • Finden Sie alle Zahlenpaare in einem Array, die sich zu einer bestimmten Summe addieren
  • Sortieren in Java
  • Effizienter Worthäufigkeitsrechner in Java
  • Einfügungssortierung in Java

16. Schlussfolgerung

Arrays sind eine der Kernfunktionen von Java. Daher ist es sehr wichtig zu verstehen, wie sie funktionieren, und zu wissen, was wir mit ihnen tun können und was nicht.

In diesem Tutorial haben wir gelernt, wie wir Array-Operationen in gängigen Szenarien angemessen handhaben können.

Wie immer ist der vollständige Quellcode der Arbeitsbeispiele auf unserem Github-Repo verfügbar.