杰瑞科技汇

Java ArrayUtils如何高效操作数组?

Of course! ArrayUtils is a very useful utility class, but it's important to know that it's not part of the standard Java Development Kit (JDK).

Java ArrayUtils如何高效操作数组?-图1
(图片来源网络,侵删)

It comes from the Apache Commons Lang library, which is a set of helper utilities for the core Java API. It's extremely popular and widely used in Java projects to simplify common array operations.

Here’s a complete guide covering what it is, why it's useful, and how to use it.


What is ArrayUtils?

ArrayUtils is a static utility class in the org.apache.commons.lang3 package. It provides a wide range of static methods for working with arrays of different primitive types (like int, long, double) and object types (like String, Integer, etc.).

Why Use ArrayUtils?

The primary reason is convenience and reducing boilerplate code. Standard Java arrays have several limitations:

Java ArrayUtils如何高效操作数组?-图2
(图片来源网络,侵删)
  • No Size Information: An array's length is fixed, but there's no built-in, safe way to add or remove elements.
  • No toString(), equals(), or hashCode(): Arrays inherit these methods from Object. For example, int[] array = {1, 2, 3}; System.out.println(array); prints something like [I@15db9742, which is not useful.
  • No Search Methods: You have to manually loop through an array to find an element.
  • No Conversion to Collections: Converting an array to a List requires a manual loop or Arrays.asList(), which has its own quirks (e.g., it returns a fixed-size list).

ArrayUtils elegantly solves these problems.


How to Add ArrayUtils to Your Project

You need to add the Apache Commons Lang dependency to your project. Here are the instructions for the most popular build tools.

Using Maven (pom.xml)

Add this dependency to your pom.xml file:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.14.0</version> <!-- Check for the latest version -->
</dependency>

Using Gradle (build.gradle)

Add this dependency to your build.gradle file (for Groovy DSL):

implementation 'org.apache.commons:commons-lang3:3.14.0' // Check for the latest version

For Kotlin DSL (build.gradle.kts):

implementation("org.apache.commons:commons-lang3:3.14.0") // Check for the latest version

Common ArrayUtils Methods (with Examples)

Let's explore the most useful methods. We'll use String arrays for the examples, but the same principles apply to primitive arrays.

a. Converting Between Primitives and Objects

This is one of the most powerful features. You can't have a List<int>, but you can have a List<Integer>.

import org.apache.commons.lang3.ArrayUtils;
public class PrimitiveToObjectExample {
    public static void main(String[] args) {
        // Convert a primitive int array to an Integer object array
        int[] primitiveArray = {1, 2, 3, 4, 5};
        Integer[] objectArray = ArrayUtils.toObject(primitiveArray);
        System.out.println("Primitive Array: " + Arrays.toString(primitiveArray));
        System.out.println("Object Array: " + Arrays.toString(objectArray));
        System.out.println("Type of objectArray[0]: " + objectArray[0].getClass().getSimpleName());
        // Convert an Integer object array back to a primitive int array
        Integer[] anotherObjectArray = {10, 20, 30};
        int[] anotherPrimitiveArray = ArrayUtils.toPrimitive(anotherObjectArray);
        System.out.println("Back to Primitive: " + Arrays.toString(anotherPrimitiveArray));
    }
}

Output:

Primitive Array: [1, 2, 3, 4, 5]
Object Array: [1, 2, 3, 4, 5]
Type of objectArray[0]: Integer
Back to Primitive: [10, 20, 30]

b. Adding and Removing Elements

You can't actually change the size of the original array, but ArrayUtils returns a new array with the element added or removed.

import org.apache.commons.lang3.ArrayUtils;
public class AddRemoveExample {
    public static void main(String[] args) {
        String[] names = {"Alice", "Bob", "Charlie"};
        // Add an element to the end
        String[] namesWithDavid = ArrayUtils.add(names, "David");
        System.out.println("After adding David: " + Arrays.toString(namesWithDavid));
        // Add an element at a specific index
        String[] namesWithEve = ArrayUtils.add(namesWithDavid, 1, "Eve");
        System.out.println("After adding Eve at index 1: " + Arrays.toString(namesWithEve));
        // Remove an element by its value
        String[] namesWithoutBob = ArrayUtils.removeElement(namesWithEve, "Bob");
        System.out.println("After removing Bob: " + Arrays.toString(namesWithoutBob));
        // Remove an element by its index
        String[] namesWithoutFirst = ArrayUtils.remove(namesWithoutBob, 0);
        System.out.println("After removing element at index 0: " + Arrays.toString(namesWithoutFirst));
    }
}

Output:

After adding David: [Alice, Bob, Charlie, David]
After adding Eve at index 1: [Alice, Eve, Bob, Charlie, David]
After removing Bob: [Alice, Eve, Charlie, David]
After removing element at index 0: [Eve, Charlie, David]

c. Searching and Checking for Elements

import org.apache.commons.lang3.ArrayUtils;
import java.util.Arrays;
public class SearchExample {
    public static void main(String[] args) {
        String[] tools = {"Maven", "Gradle", "Jenkins", "Docker"};
        // Check if an array contains a specific element
        boolean hasGradle = ArrayUtils.contains(tools, "Gradle");
        System.out.println("Does the array contain 'Gradle'? " + hasGradle);
        // Find the index of an element
        int jenkinsIndex = ArrayUtils.indexOf(tools, "Jenkins");
        System.out.println("Index of 'Jenkins': " + jenkinsIndex);
        // Find the last index of an element (useful for duplicates)
        int lastMavenIndex = ArrayUtils.lastIndexOf(tools, "Maven");
        System.out.println("Last index of 'Maven': " + lastMavenIndex);
    }
}

Output:

Does the array contain 'Gradle'? true
Index of 'Jenkins': 2
Last index of 'Maven': 0

d. Converting to a String

This is incredibly useful for logging and debugging.

import org.apache.commons.lang3.ArrayUtils;
public class ToStringExample {
    public static void main(String[] args) {
        int[] numbers = {100, 200, 300};
        String[] frameworks = {"Spring", "Hibernate", "JPA"};
        // Get a nicely formatted string representation
        String numbersString = ArrayUtils.toString(numbers);
        String frameworksString = ArrayUtils.toString(frameworks);
        System.out.println(numbersString); // Prints "{100,200,300}"
        System.out.println(frameworksString); // Prints "{Spring,Hibernate,JPA}"
    }
}

e. Reversing and Shuffling

import org.apache.commons.lang3.ArrayUtils;
import java.util.Arrays;
public class ReverseShuffleExample {
    public static void main(String[] args) {
        String[] colors = {"Red", "Green", "Blue", "Yellow"};
        // Reverse the array
        ArrayUtils.reverse(colors);
        System.out.println("Reversed: " + Arrays.toString(colors));
        // Shuffle the array (random order)
        ArrayUtils.shuffle(colors);
        System.out.println("Shuffled: " + Arrays.toString(colors));
    }
}

Example Output (will vary on shuffle):

Reversed: [Yellow, Blue, Green, Red]
Shuffled: [Green, Red, Yellow, Blue]

f. Null-Safe Operations

This is a key benefit. Many ArrayUtils methods are null-safe, meaning they won't throw a NullPointerException if the input array is null.

import org.apache.commons.lang3.ArrayUtils;
public class NullSafeExample {
    public static void main(String[] args) {
        String[] nullArray = null;
        String[] regularArray = {"A", "B"};
        // This would throw NPE with standard Java: Arrays.toString(nullArray);
        // But ArrayUtils handles it gracefully.
        System.out.println("Null array as string: " + ArrayUtils.toString(nullArray, "ARRAY IS NULL"));
        System.out.println("Contains 'A' in null array? " + ArrayUtils.contains(nullArray, "A")); // false
        // This works perfectly fine
        System.out.println("Contains 'A' in regular array? " + ArrayUtils.contains(regularArray, "A")); // true
    }
}

Output:

Null array as string: ARRAY IS NULL
Contains 'A' in null array? false
Contains 'A' in regular array? true

When NOT to Use ArrayUtils

While powerful, it's not always the right tool.

  • Performance in Hot Loops: For performance-critical code that runs millions of times in a tight loop, the overhead of a method call (even a static one) might be slower than writing a manual loop. However, this is a rare exception.
  • When Java 8+ Streams are Better: For transformations, filtering, and aggregations, Java 8 Streams are often more expressive and readable.

Example: Using Java 8 Streams vs. ArrayUtils

Let's say you want to get the first element of an array, or a default value if it's empty or null.

With ArrayUtils:

String[] names = {"Alice"};
String firstOrDefault = ArrayUtils.isEmpty(names) ? "Default" : names[0];

With Java 8 Streams:

import java.util.Arrays;
import java.util.Optional;
String[] names = {"Alice"};
String firstOrDefault = Arrays.stream(names).findFirst().orElse("Default");

The Stream version is very declarative and elegant for this kind of data processing.


Summary

Feature Standard Java ArrayUtils (Apache Commons Lang)
Print Array Arrays.toString(array) ArrayUtils.toString(array)
Add Element Manual (create new array, copy) ArrayUtils.add(array, element)
Remove Element Manual (create new array, copy) ArrayUtils.removeElement(array, element)
Contains Element Manual loop ArrayUtils.contains(array, element)
Primitive to Object Manual loop ArrayUtils.toObject(primitiveArray)
Null-Safe Objects.requireNonNull() or checks Many methods are null-safe by default
Conversion to List Arrays.asList(array) (fixed-size) Arrays.asList(ArrayUtils.toObject(array))

In conclusion, ArrayUtils is an excellent tool to have in your Java utility belt. It simplifies common array operations, makes your code more readable, and helps you avoid writing boilerplate code. For most general-purpose array manipulation, it's the go-to solution. For complex data processing, modern Java Streams are often a better fit.

分享:
扫描分享到社交APP
上一篇
下一篇