/* * Copyright 2011 Eric F. Savage, code@efsavage.com * * Licensed 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 com.ajah.util; import java.util.ArrayList; import java.util.Arrays; import java.util.logging.Level; import lombok.extern.java.Log; /** * Utility methods for arrays. * * @author <a href="http://efsavage.com">Eric F. Savage</a>, * <a href="mailto:code@efsavage.com">code@efsavage.com</a>. */ @Log public class ArrayUtils { /** * Appends an element to an array, filling the first null spot. If no spots * are available, expands the array and puts the new element as the last * entry. * * @param array * The array to add to or copy. * @param object * The object to add. * @return The original array if a spot was found, otherwise a new array * that is one size larger. */ public static <T> T[] append(final T[] array, final T object) { for (int i = 0; i < array.length; i++) { if (array[i] == null) { array[i] = object; return array; } } final T[] newArray = Arrays.copyOf(array, array.length + 1); newArray[newArray.length - 1] = object; return newArray; } /** * Checks to see if an array contains a given object. * * @see Object#equals(Object) * @param array * The array to check. * @param member * The object to look for in the array. * @return true if the parameters are not null and the object was found, * otherwise false. */ public static <T> boolean contains(final T[] array, final T member) { if (array == null || array.length == 0 || member == null) { return false; } for (final T t : array) { if (t.equals(member)) { return true; } } return false; } /** * Checks to see if an array contains a given int. * * @see Object#equals(Object) * @param array * The array to check. * @param member * The int to look for in the array. * @return true if the parameters are not null and the object was found, * otherwise false. */ public static boolean contains(final int[] array, final int member) { if (array == null || array.length == 0) { return false; } for (final int t : array) { if (t == member) { return true; } } return false; } /** * Exception-free way to get an element from an array. Will return null if * the array is null or if the array is not large enough to contain the * index requested. * * @param <T> * The class of object to return. * @param array * The array to look at, may be null. * @param index * The index of the array to return. * @return The object to return, may be null. */ public static <T> T get(final T[] array, final int index) { if (array == null || index < 0 || array.length < index + 1) { return null; } try { return array[index]; } catch (final ArrayIndexOutOfBoundsException e) { // This should not be able to happen, it's here for emphasis. log.log(Level.SEVERE, e.getMessage(), e); } return null; } /** * Find the largest value in the array and returns the index of it. If two * values are equal, will return the first index. * * @param values * The array of integers. * @return Index of the first occurrence of the largest value. * @throws IllegalArgumentException * if values is null. */ public static int indexOfLargest(final int[] values) { AjahUtils.requireParam(values, "values"); int index = 0; final int largest = values[0]; for (int i = 1; i < values.length; i++) { if (values[i] > largest) { index = i; } } return index; } /** * Determines if an array has any actual objects in it. Will return true if: * <ul> * <li>The array is null.</li> * <li>The array's length is zero.</li> * <li>The array's contains only nulls.</li> * </ul> * * @param array * The array to test. * @return Returns true if the array is empty as specified above, otherwise * false. */ public static boolean isEmpty(final Object[] array) { if (array == null || array.length < 1) { return true; } for (final Object object : array) { if (object != null) { return false; } } return true; } /** * A variation of {@link #isEmpty(Object[])} for Strings that checks for * empty/blank strings. * * @see StringUtils#isBlank(String) * @param array * The array to test. * @return Returns true if the array is empty as specified above, otherwise * false. */ public static boolean isEmpty(final String[] array) { if (array == null || array.length < 1) { return true; } for (final String string : array) { if (!StringUtils.isBlank(string)) { return false; } } return true; } /** * Joins the result of calling {@link #toString()} on each element of an * array. * * @param array * The array, may be null or empty. * @return The joined result of calling {@link #toString()} on each element * of an array, or null if the supplied array was null or empty. */ public static String joinToString(final Object[] array) { if (array == null || array.length == 0) { return null; } final StringBuilder string = new StringBuilder(); for (final Object object : array) { string.append(object.toString()); } return string.toString(); } /** * Parses each element of a String array into an int array. * * @param array * The array to parse. * @return Returns An int array of the same size with each string parsed as * an integer. * @throws NumberFormatException * If a string could not be parsed. */ public static int[] parseInt(final String[] array) { if (array == null || array.length < 1) { return new int[0]; } final int[] retVal = new int[array.length]; for (int i = 0; i < array.length; i++) { retVal[i] = Integer.parseInt(array[i]); } return retVal; } /** * Returns the length of an array, or zero if he array is null. * * @param array * The array to find the length of, may be null. * @return The length of an array, or zero if he array is null. */ public static int safeLength(final Object[] array) { if (array == null) { return 0; } return array.length; } /** * Sums an array of bytes. * * @param array * Byte array. * @return The sum of the values of the array. Returns 0 if the array is 0 * or empty. */ public static long sum(final byte[] array) { if (array == null || array.length == 0) { return 0; } int retVal = array[0]; for (int i = 1; i < array.length; i++) { retVal += array[i]; } return retVal; } /** * Sums an array of doubles. * * @param array * Double array. * @return The sum of the values of the array. Returns 0 if the array is 0 * or empty. */ public static double sum(final double[] array) { if (array == null || array.length == 0) { return 0; } double retVal = array[0]; for (int i = 1; i < array.length; i++) { retVal += array[i]; } return retVal; } /** * Sums an array of integers. * * @param array * Integer array. * @return The sum of the values of the array. Returns 0 if the array is 0 * or empty. */ public static long sum(final int[] array) { if (array == null || array.length == 0) { return 0; } int retVal = array[0]; for (int i = 1; i < array.length; i++) { retVal += array[i]; } return retVal; } /** * Trims each element in an array of strings, and removes any null or blank * values. * * @param array * The array to trim. May be null or empty. * @return The trimmed array, which may be shorter than the original. If a * null or empty array is passed in, the same value will be * returned. */ public static String[] trim(final String[] array) { if (array == null || array.length == 0) { return array; } final ArrayList<String> trimmed = new ArrayList<>(); for (final String string : array) { if (!StringUtils.isBlank(string)) { trimmed.add(string.trim()); } } return trimmed.toArray(new String[trimmed.size()]); } /** * Converts an array of Integer to an array of int. * * @param integers * The array of Integers. * @return The equivalent array of ints, or null if the parameter is null. */ public static int[] toIntArray(Integer[] integers) { if (integers == null) { return null; } int[] ints = new int[integers.length]; for (int i = 0; i < integers.length; i++) { ints[i] = integers[i].intValue(); } return ints; } /** * A shortcut to do sorting inline since the {@link Arrays#sort(Object[]))} * method returns void. Also requires a comparable object, which the Arrays * method does not. * * @See {@link Arrays#sort(Object[]))} * @param array * The array to sort. * @return The sorted array. */ public static <T extends Comparable<? super T>> T[] sort(T[] array) { Arrays.sort(array); return array; } }