All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.juneau.internal.ArrayUtils Maven / Gradle / Ivy

There is a newer version: 9.0.1
Show newest version
// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
// * with the License.  You may obtain a copy of the License at                                                              *
// *                                                                                                                         *
// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
// *                                                                                                                         *
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
// * specific language governing permissions and limitations under the License.                                              *
// ***************************************************************************************************************************
package org.apache.juneau.internal;

import static org.apache.juneau.internal.StringUtils.*;
import static org.apache.juneau.internal.ThrowableUtils.*;

import java.lang.reflect.*;
import java.util.*;

/**
 * Quick and dirty utilities for working with arrays.
 */
public final class ArrayUtils {

	/**
	 * Appends one or more elements to an array.
	 *
	 * @param  The element type.
	 * @param array The array to append to.
	 * @param newElements The new elements to append to the array.
	 * @return A new array with the specified elements appended.
	 */
	@SuppressWarnings("unchecked")
	public static  T[] append(T[] array, T...newElements) {
		if (array == null)
			return newElements;
		if (newElements.length == 0)
			return array;
		T[] a = (T[])Array.newInstance(array.getClass().getComponentType(), array.length + newElements.length);
		for (int i = 0; i < array.length; i++)
			a[i] = array[i];
		for (int i = 0; i < newElements.length; i++)
			a[i+array.length] = newElements[i];
		return a;
	}

	/**
	 * Appends one or more elements to an array.
	 *
	 * @param  The element type.
	 * @param array The array to append to.
	 * @param newElements The new elements to append to the array.
	 * @return A new array with the specified elements appended.
	 */
	@SuppressWarnings("unchecked")
	public static  T[] append(T[] array, Collection newElements) {
		assertFieldNotNull(array, "array");
		if (newElements.size() == 0)
			return array;
		T[] a = (T[])Array.newInstance(array.getClass().getComponentType(), array.length + newElements.size());
		for (int i = 0; i < array.length; i++)
			a[i] = array[i];
		int l = array.length;
		for (T t : newElements)
			a[l++] = t;
		return a;
	}

	/**
	 * Combine an arbitrary number of arrays into a single array.
	 *
	 * @param arrays Collection of arrays to combine.
	 * @return A new combined array, or null if all arrays are null.
	 */
	@SuppressWarnings("unchecked")
	public static  T[] combine(T[]...arrays) {
		assertFieldNotNull(arrays, "arrays");
		int l = 0;
		T[] a1 = null;
		for (T[] a : arrays) {
			if (a1 == null && a != null)
				a1 = a;
			l += (a == null ? 0 : a.length);
		}
		if (a1 == null)
			return null;
		T[] a = (T[])Array.newInstance(a1.getClass().getComponentType(), l);
		int i = 0;
		for (T[] aa : arrays)
			if (aa != null)
				for (T t : aa)
					a[i++] = t;
		return a;
	}

	/**
	 * Creates a new array with reversed entries.
	 *
	 * @param  The class type of the array.
	 * @param array The array to reverse.
	 * @return A new array with reversed entries, or null if the array was null.
	 */
	@SuppressWarnings("unchecked")
	public static  T[] reverse(T[] array) {
		if (array == null)
			return null;
		Class c = (Class)array.getClass().getComponentType();
		T[] a2 = (T[])Array.newInstance(c, array.length);
		for (int i = 0; i < array.length; i++)
			a2[a2.length-i-1] = array[i];
		return a2;
	}

	/**
	 * Sorts the elements in an array without creating a new array.
	 *
	 * @param array The array to sort.
	 * @return The same array.
	 */
	public static  T[] reverseInline(T[] array) {
		if (array == null)
			return null;
		T t;
		for (int i = 0, j = array.length-1; i < j; i++, j--) {
			t = array[i];
			array[i] = array[j];
			array[j] = t;
		}
		return array;
	}

	/**
	 * Converts the specified array to a Set.
	 *
	 * 

* The order of the entries in the set are the same as the array. * * @param The entry type of the array. * @param array The array being wrapped in a Set interface. * @return The new set. */ public static Set asSet(final T[] array) { assertFieldNotNull(array, "array"); return new AbstractSet() { @Override /* Set */ public Iterator iterator() { return new Iterator() { int i = 0; @Override /* Iterator */ public boolean hasNext() { return i < array.length; } @Override /* Iterator */ public T next() { if (i >= array.length) throw new NoSuchElementException(); T t = array[i]; i++; return t; } @Override /* Iterator */ public void remove() { throw new UnsupportedOperationException(); } }; } @Override /* Set */ public int size() { return array.length; } }; } /** * Returns an iterator against an array. * *

* This works with any array type (e.g. String[], Object[], * int[], etc...). * * @param array The array to create an iterator over. * @return An iterator over the specified array. */ public static Iterator iterator(final Object array) { return new Iterator() { int i = 0; int length = array == null ? 0 : Array.getLength(array); @Override /* Iterator */ public boolean hasNext() { return i < length; } @Override /* Iterator */ public Object next() { if (i >= length) throw new NoSuchElementException(); return Array.get(array, i++); } @Override /* Iterator */ public void remove() { throw new UnsupportedOperationException(); } }; } /** * Converts the specified collection to an array. * *

* Works on both object and primitive arrays. * * @param c The collection to convert to an array. * @param componentType The component type of the collection. * @return A new array. */ public static Object toArray(Collection c, Class componentType) { Object a = Array.newInstance(componentType, c.size()); Iterator it = c.iterator(); int i = 0; while (it.hasNext()) Array.set(a, i++, it.next()); return a; } /** * Returns true if the specified object is an array. * * @param array The array to test. * @return true if the specified object is an array. */ public static boolean isArray(Object array) { return array != null && array.getClass().isArray(); } /** * Converts the specified array to an ArrayList * * @param array The array to convert. * @param componentType * The type of objects in the array. * It must match the actual component type in the array. * @return A new {@link ArrayList} */ @SuppressWarnings("unchecked") public static List toList(Object array, Class componentType) { List l = new ArrayList<>(Array.getLength(array)); for (int i = 0; i < Array.getLength(array); i++) l.add((T)Array.get(array, i)); return l; } /** * Shortcut for calling myList.toArray(new T[myList.size()]); * * @param c The collection being converted to an array. * @param componentType The component type of the array. * @return The collection converted to an array. */ @SuppressWarnings("unchecked") public static T[] toObjectArray(Collection c, Class componentType) { Object a = Array.newInstance(componentType, c.size()); Iterator it = c.iterator(); int i = 0; while (it.hasNext()) Array.set(a, i++, it.next()); return (T[])a; } /** * Copies the specified array into the specified list. * *

* Works on both object and primitive arrays. * * @param array The array to copy into a list. * @param list The list to copy the values into. * @return The same list passed in. */ @SuppressWarnings({"unchecked","rawtypes"}) public static List copyToList(Object array, List list) { if (array != null) { int length = Array.getLength(array); for (int i = 0; i < length; i++) list.add(Array.get(array, i)); } return list; } /** * Returns true if the specified array contains the specified element using the {@link Object#equals(Object)} * method. * * @param element The element to check for. * @param array The array to check. * @return * true if the specified array contains the specified element, * false if the array or element is null. */ public static boolean contains(T element, T[] array) { return indexOf(element, array) != -1; } /** * Returns the index position of the element in the specified array using the {@link Object#equals(Object)} method. * * @param element The element to check for. * @param array The array to check. * @return * The index position of the element in the specified array, or -1 if the array doesn't contain the * element, or the array or element is null. */ public static int indexOf(T element, T[] array) { if (element == null) return -1; if (array == null) return -1; for (int i = 0; i < array.length; i++) if (element.equals(array[i])) return i; return -1; } /** * Returns true if the specified array contains the specified element using the {@link String#equals(Object)} * method. * * @param element The element to check for. * @param array The array to check. * @return * true if the specified array contains the specified element, * false if the array or element is null. */ public static boolean contains(String element, String[] array) { return indexOf(element, array) != -1; } /** * Returns the index position of the element in the specified array using the {@link String#equals(Object)} method. * * @param element The element to check for. * @param array The array to check. * @return * The index position of the element in the specified array, or * -1 if the array doesn't contain the element, or the array or element is null. */ public static int indexOf(String element, String[] array) { if (element == null) return -1; if (array == null) return -1; for (int i = 0; i < array.length; i++) if (element.equals(array[i])) return i; return -1; } /** * Converts a primitive wrapper array (e.g. Integer[]) to a primitive array (e.g. int[]). * * @param o The array to convert. Must be a primitive wrapper array. * @return A new array. * @throws IllegalArgumentException If object is not a wrapper object array. */ public static Object toPrimitiveArray(Object o) { Class c = o.getClass(); if (! c.isArray()) throw new IllegalArgumentException("Cannot pass non-array objects to toPrimitiveArray()"); int l = Array.getLength(o); Class tc = ClassUtils.getPrimitiveForWrapper(c.getComponentType()); if (tc == null) throw new IllegalArgumentException("Array type is not a primitive wrapper array."); Object a = Array.newInstance(tc, l); for (int i = 0; i < l; i++) Array.set(a, i, Array.get(o, i)); return a; } /** * Converts an Iterable to a list. * * @param i The iterable to convert. * @return A new list of objects copied from the iterable. */ public static List toList(Iterable i) { List l = new ArrayList<>(); Iterator i2 = i.iterator(); while (i2.hasNext()) l.add(i2.next()); return l; } /** * Returns the first object in the specified collection or array. * * @param val The collection or array object. * @return * The first object, or null if the collection or array is empty or null or the value * isn't a collection or array. */ public static Object getFirst(Object val) { if (val != null) { if (val instanceof Collection) { Collection c = (Collection)val; if (c.isEmpty()) return null; return c.iterator().next(); } if (val.getClass().isArray()) return Array.getLength(val) == 0 ? null : Array.get(val, 0); } return null; } /** * Converts the specified collection to an array of strings. * *

* Entries are converted to strings using {@link #toString()}. * null values remain null. * * @param c The collection to convert. * @return The collection as a string array. */ public static String[] toStringArray(Collection c) { String[] r = new String[c.size()]; int i = 0; for (Object o : c) r[i++] = asString(o); return r; } /** * Returns true if the following sorted arrays are equals. * * @param a1 Array #1. * @param a2 Array #2. * @return true if the following sorted arrays are equals. */ public static boolean equals(String[] a1, String[] a2) { if (a1.length != a2.length) return false; for (int i = 0; i < a1.length; i++) if (! StringUtils.isEquals(a1[i], a2[i])) return false; return true; } /** * Converts a collection to an array containing the elements in reversed order. * * @param c The component type of the array. * @param l * The collection to convert. *
The collection is not modified. * @return * A new array, or null if the collection was null. */ @SuppressWarnings("unchecked") public static T[] toReverseArray(Class c, Collection l) { if (l == null) return null; Object a = Array.newInstance(c, l.size()); Iterator i = l.iterator(); int j = l.size(); while (i.hasNext()) Array.set(a, --j, i.next()); return (T[])a; } /** * Removes the specified element from the specified array. * * @param element The element to remove from the array. * @param array The array to remove the element from. * @return A new array with the element removed, or the original array if the array did not contain the element. */ public static Object[] remove(Object element, Object[] array) { if (! contains(element, array)) return array; List l = new ArrayList<>(array.length); for (Object o2 : array) { if (! element.equals(o2)) l.add(o2); } return l.toArray(new Object[l.size()]); } }