001 /*
002 * Created on May 13, 2007
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
005 * the License. You may obtain a copy of the License at
006 *
007 * http://www.apache.org/licenses/LICENSE-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
010 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
011 * specific language governing permissions and limitations under the License.
012 *
013 * Copyright @2007-2011 the original author or authors.
014 */
015 package org.fest.util;
016
017 import static java.lang.System.arraycopy;
018
019 import java.lang.reflect.Array;
020 import java.util.*;
021
022 /**
023 * Utility methods related to arrays.
024 *
025 * @author Alex Ruiz
026 * @author Joel Costigliola
027 */
028 public class Arrays {
029
030 private static final ArrayFormatter formatter = new ArrayFormatter();
031
032 /**
033 * Returns {@code true} if the given object is not {@code null} and is an array.
034 * @param o the given object.
035 * @return {@code true} if the given object is not {@code null} and is an array, otherwise {@code false}.
036 */
037 public static boolean isArray(Object o) {
038 return o != null && o.getClass().isArray();
039 }
040
041 /**
042 * Returns {@code true} if the given array is {@code null} or empty.
043 * @param <T> the type of elements of the array.
044 * @param array the array to check.
045 * @return {@code true} if the given array is {@code null} or empty, otherwise {@code false}.
046 */
047 public static <T> boolean isEmpty(T[] array) {
048 return array == null || !hasElements(array);
049 }
050
051 /**
052 * Returns an array containing the given arguments.
053 * @param <T> the type of the array to return.
054 * @param values the values to store in the array.
055 * @return an array containing the given arguments.
056 */
057 public static <T> T[] array(T... values) {
058 return values;
059 }
060
061 /**
062 * Returns the {@code String} representation of the given array, or {@code null} if the given object is either
063 * {@code null} or not an array. This method supports arrays having other arrays as elements.
064 * @param array the object that is expected to be an array.
065 * @return the {@code String} representation of the given array.
066 */
067 public static String format(Object array) {
068 return formatter.format(array);
069 }
070
071 /**
072 * Returns a new array containing the non-null elements of the given array. This method returns an empty array if the
073 * given array has only {@code null} elements or if it is empty. This method returns {@code null} if the given array
074 * is {@code null}.
075 * @param <T> the type of elements of the array.
076 * @param array the array we want to extract the non-null elements from.
077 * @return a new array containing the non-null elements of the given array, or {@code null} if the given array is
078 * {@code null}.
079 * @since 1.1.3
080 */
081 @SuppressWarnings("unchecked")
082 public static <T> T[] nonNullElements(T[] array) {
083 if (array == null) return null;
084 List<T> nonNullElements = new ArrayList<T>();
085 for (T o : array)
086 if (o != null) nonNullElements.add(o);
087 int elementCount = nonNullElements.size();
088 T[] newArray = (T[]) Array.newInstance(array.getClass().getComponentType(), elementCount);
089 arraycopy(nonNullElements.toArray(), 0, newArray, 0, elementCount);
090 return newArray;
091 }
092
093 /**
094 * Returns {@code true} if the given array has only {@code null} elements, {@code false} otherwise. If given array is
095 * empty, this method returns {@code true}.
096 * @param <T> the type of elements of the array.
097 * @param array the given array. <b>It must not be null</b>.
098 * @return {@code true} if the given array has only {@code null} elements or is empty, {@code false} otherwise.
099 * @throws NullPointerException if the given array is {@code null}.
100 * @since 1.1.3
101 */
102 public static <T> boolean hasOnlyNullElements(T[] array) {
103 if (array == null) throw new NullPointerException("The array to check should not be null");
104 if (!hasElements(array)) return false;
105 for (T o : array)
106 if (o != null) return false;
107 return true;
108 }
109
110 private static <T> boolean hasElements(T[] array) {
111 return array.length > 0;
112 }
113
114 /**
115 * Copies the specified array, truncating or padding with nulls (if necessary) so the copy has the specified length.
116 * For all indices that are valid in both the original array and the copy, the two arrays will contain identical
117 * values. For any indices that are valid in the copy but not the original, the copy will contain {@code null}. Such
118 * indices will exist if and only if the specified length is greater than that of the original array.
119 * @param <T> the component type of the array.
120 * @param original the array to be copied.
121 * @param newLength the length of the copy to be returned.
122 * @return a copy of the original array, truncated or padded with nulls to obtain the specified length.
123 * @throws NegativeArraySizeException if {@code newLength} is negative.
124 * @throws NullPointerException if {@code original} is {@code null}.
125 * @since 1.1.5
126 */
127 @SuppressWarnings("unchecked")
128 public static <T> T[] copyOf(T[] original, int newLength) {
129 // TODO test
130 T[] copy = (T[]) Array.newInstance(original.getClass().getComponentType(), newLength);
131 arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
132 return copy;
133 }
134
135 private Arrays() {}
136 }