Implementation:Apache Paimon ArrayUtils
| Knowledge Sources | |
|---|---|
| Domains | Utilities, Array Operations |
| Last Updated | 2026-02-08 00:00 GMT |
Overview
ArrayUtils provides utility methods for array manipulation, including empty array constants, primitive-to-object conversions, and byte array merging.
Description
ArrayUtils is a general-purpose utility class that reduces code duplication and improves performance for common array operations throughout Paimon. It defines static final empty array constants (EMPTY_STRING_ARRAY, EMPTY_LONG_ARRAY, etc.) for all primitive and wrapper types, avoiding repeated allocation and enabling reference equality checks.
The class provides overloaded toObject() methods that convert primitive arrays (boolean[], byte[], int[], long[], etc.) to their wrapper equivalents (Boolean[], Byte[], Integer[], Long[], etc.), which is necessary when working with generic collections or reflection. Conversely, toPrimitive*() methods convert wrapper arrays back to primitives using direct casting. These conversions handle null input gracefully by returning null, and optimize empty arrays by returning the appropriate empty constant.
The mergeByteArrays() method efficiently concatenates a list of byte arrays using System.arraycopy, with optimizations for empty lists and single-element lists. This is particularly useful in serialization, I/O operations, and data processing pipelines where multiple byte buffers need to be combined.
Usage
Use ArrayUtils when working with arrays that need type conversion, when empty arrays are needed (use the constants instead of new allocations), or when merging byte arrays. This class is used throughout Paimon for efficient array operations in serialization, data type handling, and string splitting.
Code Reference
Source Location
- Repository: Apache_Paimon
- File: paimon-api/src/main/java/org/apache/paimon/utils/ArrayUtils.java
- Lines: 24-380
Signature
public class ArrayUtils {
// Empty array constants
public static final String[] EMPTY_STRING_ARRAY;
public static final long[] EMPTY_LONG_ARRAY;
public static final int[] EMPTY_INT_ARRAY;
public static final byte[] EMPTY_BYTE_ARRAY;
// ... additional empty array constants for all primitive types
// Primitive to object conversions
public static Boolean[] toObject(final boolean[] array);
public static Byte[] toObject(final byte[] array);
public static Integer[] toObject(final int[] array);
public static Long[] toObject(final long[] array);
// ... additional toObject overloads
// Object to primitive conversions
public static boolean[] toPrimitiveBoolean(final Object[] array);
public static byte[] toPrimitiveByte(final Object[] array);
public static int[] toPrimitiveInteger(final Object[] array);
public static long[] toPrimitiveLong(final Object[] array);
// ... additional toPrimitive* methods
// Byte array merging
public static byte[] mergeByteArrays(List<byte[]> byteList);
}
Import
import org.apache.paimon.utils.ArrayUtils;
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| array | primitive[] or Object[] | yes | Array to convert between primitive and wrapper types |
| byteList | List<byte[]> | yes | List of byte arrays to merge |
Outputs
| Name | Type | Description |
|---|---|---|
| wrapperArray | Object[] | Wrapper type array from primitive input |
| primitiveArray | primitive[] | Primitive type array from wrapper input |
| mergedBytes | byte[] | Single concatenated byte array |
Usage Examples
Using Empty Array Constants
// Use constants instead of creating new empty arrays
String[] emptyStrings = ArrayUtils.EMPTY_STRING_ARRAY;
int[] emptyInts = ArrayUtils.EMPTY_INT_ARRAY;
byte[] emptyBytes = ArrayUtils.EMPTY_BYTE_ARRAY;
// Check if array is empty
boolean isEmpty = (array.length == 0) || (array == ArrayUtils.EMPTY_STRING_ARRAY);
// Return empty array from method
public String[] getFieldNames() {
if (fields.isEmpty()) {
return ArrayUtils.EMPTY_STRING_ARRAY;
}
return fields.toArray(new String[0]);
}
Primitive to Object Conversion
// Convert int array to Integer array
int[] primitiveInts = {1, 2, 3, 4, 5};
Integer[] wrapperInts = ArrayUtils.toObject(primitiveInts);
// Convert long array to Long array
long[] primitiveLongs = {100L, 200L, 300L};
Long[] wrapperLongs = ArrayUtils.toObject(primitiveLongs);
// Handle null input
int[] nullArray = null;
Integer[] result = ArrayUtils.toObject(nullArray);
// Returns: null
// Handle empty array
int[] emptyArray = new int[0];
Integer[] emptyResult = ArrayUtils.toObject(emptyArray);
// Returns: ArrayUtils.EMPTY_INTEGER_OBJECT_ARRAY
Object to Primitive Conversion
// Convert Integer array to int array
Object[] wrapperInts = {1, 2, 3, 4, 5};
int[] primitiveInts = ArrayUtils.toPrimitiveInteger(wrapperInts);
// Convert Long array to long array
Object[] wrapperLongs = {100L, 200L, 300L};
long[] primitiveLongs = ArrayUtils.toPrimitiveLong(wrapperLongs);
// Convert Boolean array to boolean array
Object[] wrapperBools = {true, false, true};
boolean[] primitiveBools = ArrayUtils.toPrimitiveBoolean(wrapperBools);
// Null handling
Object[] nullArray = null;
int[] result = ArrayUtils.toPrimitiveInteger(nullArray);
// Returns: null
Merging Byte Arrays
// Merge multiple byte arrays
List<byte[]> byteArrays = Arrays.asList(
new byte[]{1, 2, 3},
new byte[]{4, 5},
new byte[]{6, 7, 8, 9}
);
byte[] merged = ArrayUtils.mergeByteArrays(byteArrays);
// Returns: [1, 2, 3, 4, 5, 6, 7, 8, 9]
// Handle empty list
List<byte[]> emptyList = Collections.emptyList();
byte[] emptyMerged = ArrayUtils.mergeByteArrays(emptyList);
// Returns: new byte[0]
// Handle single element (no copy)
List<byte[]> singleElement = Collections.singletonList(new byte[]{1, 2, 3});
byte[] single = ArrayUtils.mergeByteArrays(singleElement);
// Returns: original array without copying
Serialization Use Case
// Serialize multiple data chunks
public byte[] serializeData(List<DataChunk> chunks) {
List<byte[]> serializedChunks = new ArrayList<>();
for (DataChunk chunk : chunks) {
byte[] chunkBytes = chunk.toBytes();
serializedChunks.add(chunkBytes);
}
// Merge all serialized chunks into single byte array
return ArrayUtils.mergeByteArrays(serializedChunks);
}
Collection Conversion
// Convert primitive array to List (requires wrapper types)
int[] primitiveArray = {1, 2, 3, 4, 5};
Integer[] wrapperArray = ArrayUtils.toObject(primitiveArray);
List<Integer> list = Arrays.asList(wrapperArray);
// Convert List back to primitive array
List<Integer> intList = Arrays.asList(10, 20, 30);
Object[] objectArray = intList.toArray();
int[] primitiveResult = ArrayUtils.toPrimitiveInteger(objectArray);
Working with All Primitive Types
// Boolean conversions
boolean[] bools = {true, false, true};
Boolean[] boolObjects = ArrayUtils.toObject(bools);
boolean[] boolsPrimitive = ArrayUtils.toPrimitiveBoolean(
new Object[]{true, false}
);
// Byte conversions
byte[] bytes = {0x01, 0x02, 0x03};
Byte[] byteObjects = ArrayUtils.toObject(bytes);
// Short conversions
short[] shorts = {1, 2, 3};
Short[] shortObjects = ArrayUtils.toObject(shorts);
// Float conversions
float[] floats = {1.5f, 2.5f, 3.5f};
Float[] floatObjects = ArrayUtils.toObject(floats);
// Double conversions
double[] doubles = {1.5, 2.5, 3.5};
Double[] doubleObjects = ArrayUtils.toObject(doubles);