Operasi Array di Jawa

1. Gambaran keseluruhan

Mana-mana pemaju Java tahu bahawa menghasilkan penyelesaian yang bersih dan cekap ketika bekerja dengan operasi array tidak selalu mudah dicapai. Namun, mereka adalah bahagian utama dalam ekosistem Jawa - dan kita harus berurusan dengan mereka dalam beberapa kesempatan.

Atas sebab ini, ada baiknya 'cheat sheet' - ringkasan prosedur yang paling biasa untuk membantu kita mengatasi teka-teki dengan cepat. Tutorial ini akan sangat berguna dalam situasi tersebut.

2. Kelas Susun atur dan Penolong

Sebelum meneruskan, adalah berguna untuk memahami apa itu array di Java, dan bagaimana menggunakannya. Sekiranya ini pertama kalinya anda bekerja dengannya di Java, kami sarankan untuk melihat catatan sebelumnya di mana kami merangkumi semua konsep asas.

Harap maklum bahawa operasi asas yang disokong oleh larik, dengan cara tertentu, adalah terhad. Tidak biasa melihat algoritma yang kompleks untuk melaksanakan tugas yang agak mudah ketika berkaitan dengan tatasusunan.

Atas sebab ini, untuk kebanyakan operasi kami, kami akan menggunakan kelas penolong dan kaedah untuk membantu kami: kelas Arrays yang disediakan oleh Java dan Apache's ArrayUtils satu.

Untuk memasukkan yang terakhir dalam projek kami, kami harus menambahkan kebergantungan Apache Commons:

 org.apache.commons commons-lang3 3.8.1 

Kita boleh melihat versi terbaru artifak ini di Maven Central.

3. Dapatkan Elemen Pertama dan Terakhir Array

Ini adalah salah satu tugas yang paling biasa dan sederhana kerana sifat susunan akses mengikut indeks.

Mari mulakan dengan menyatakan dan menginisialisasi array int yang akan digunakan dalam semua contoh kami (kecuali jika kami menyatakan sebaliknya):

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

Mengetahui bahawa item pertama array dikaitkan dengan nilai indeks 0 dan ia mempunyai atribut panjang yang boleh kita gunakan, maka mudah untuk mengetahui bagaimana kita dapat memperoleh dua elemen ini:

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

4. Dapatkan Nilai Rawak dari Array

Dengan menggunakan objek java.util.Random kita dapat memperoleh nilai dari array kita dengan mudah:

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

5. Tambahkan Item Baru ke Array

Seperti yang kita ketahui, tatasusunan mempunyai nilai ukuran yang tetap. Oleh itu, kami tidak boleh menambahkan item dan melebihi had ini.

Kita perlu memulakan dengan menyatakan susunan yang baru dan lebih besar, dan menyalin unsur-unsur array asas ke yang kedua.

Nasib baik, kelas Arrays menyediakan kaedah yang berguna untuk meniru nilai array ke struktur bersaiz baru yang baru:

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

Secara pilihan, jika ArrayUtils kelas boleh diakses di projek kami, kami boleh menggunakan yang kaedah add (atau mana- addAll alternatif) untuk mencapai objektif kami dalam kenyataan satu line:

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

Seperti yang kita bayangkan, kaedah ini tidak mengubah objek array asal ; kita harus menetapkan outputnya ke pemboleh ubah baru.

6. Masukkan Nilai Antara Dua Nilai

Kerana wataknya yang diindeks-nilai, memasukkan item dalam tatasusunan antara dua yang lain bukanlah pekerjaan yang remeh.

Apache menganggap ini sebagai senario biasa dan menerapkan kaedah di kelas ArrayUtils untuk mempermudah penyelesaiannya:

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

Kita harus menentukan indeks di mana kita ingin memasukkan nilai, dan outputnya akan menjadi array baru yang mengandungi sebilangan besar elemen.

Argumen terakhir adalah argumen pemboleh ubah (aka vararg ) sehingga kita dapat memasukkan sebilangan besar item dalam larik .

7. Bandingkan Dua Susunan

Walaupun tatasusunan adalah Objek s dan oleh itu memberikan kaedah yang sama , mereka menggunakan pelaksanaannya secara lalai, hanya bergantung pada persamaan rujukan.

Kami bagaimanapun boleh sembah yang java.util.Arrays ' sama dengan kaedah untuk memeriksa jika dua objek pelbagai mengandungi nilai yang sama:

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

Catatan: kaedah ini tidak berkesan untuk tatasusunan bergerigi. Kaedah yang sesuai untuk mengesahkan persamaan struktur pelbagai dimensi ialah Arrays.deepEquals .

8. Periksa sama ada Array Kosong

Ini adalah tugas yang tidak rumit dengan mengingat bahawa kita dapat menggunakan atribut panjang array:

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

Lebih-lebih lagi, kami juga mempunyai kaedah selamat null di kelas penolong ArrayUtils yang boleh kami gunakan:

boolean isEmpty = ArrayUtils.isEmpty(array);

Fungsi ini masih bergantung pada panjang struktur data, yang menganggap null dan sub-array kosong sebagai nilai yang sah juga, jadi kita harus mengawasi kes-kes tepi ini:

// 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. Cara Mengacak Elemen Array

Untuk mengubah item dalam array, kita dapat menggunakan fitur ArrayUtil :

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
  • Sertailah dan Pisahkan Susunan dan Koleksi di Java
  • Menggabungkan Berbagai Jenis Koleksi di Jawa
  • Cari Semua Pasangan Nombor dalam Array yang Menambah Hingga Jumlah yang Diberikan
  • Menyusun di Jawa
  • Kalkulator Frekuensi Kata Cekap di Jawa
  • Penyisipan Penyisipan di Java

16. Kesimpulannya

Susun atur adalah salah satu fungsi utama Java, dan oleh itu sangat penting untuk memahami cara kerjanya dan mengetahui apa yang boleh dan tidak boleh kita lakukan dengannya.

Dalam tutorial ini, kami belajar bagaimana kami dapat menangani operasi array dengan tepat dalam senario biasa.

Seperti biasa, kod sumber penuh contoh kerja boleh didapati di repo Github kami.