View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  
18  package org.apache.logging.log4j.core.util;
19  
20  import java.lang.reflect.Array;
21  
22  /**
23   * Copied from Apache Commons Lang (including the {@code @since} tags.)
24   */
25  public class ArrayUtils {
26  
27      /**
28       * <p>Returns the length of the specified array.
29       * This method can deal with {@code Object} arrays and with primitive arrays.</p>
30       *
31       * <p>If the input array is {@code null}, {@code 0} is returned.</p>
32       *
33       * <pre>
34       * ArrayUtils.getLength(null)            = 0
35       * ArrayUtils.getLength([])              = 0
36       * ArrayUtils.getLength([null])          = 1
37       * ArrayUtils.getLength([true, false])   = 2
38       * ArrayUtils.getLength([1, 2, 3])       = 3
39       * ArrayUtils.getLength(["a", "b", "c"]) = 3
40       * </pre>
41       *
42       * @param array  the array to retrieve the length from, may be null
43       * @return The length of the array, or {@code 0} if the array is {@code null}
44       * @throws IllegalArgumentException if the object argument is not an array.
45       * @since 2.1
46       */
47      public static int getLength(final Object array) {
48          if (array == null) {
49              return 0;
50          }
51          return Array.getLength(array);
52      }
53  
54      /**
55       * <p>Removes the element at the specified position from the specified array.
56       * All subsequent elements are shifted to the left (subtracts one from
57       * their indices).</p>
58       *
59       * <p>This method returns a new array with the same elements of the input
60       * array except the element on the specified position. The component
61       * type of the returned array is always the same as that of the input
62       * array.</p>
63       *
64       * <p>If the input array is {@code null}, an IndexOutOfBoundsException
65       * will be thrown, because in that case no valid index can be specified.</p>
66       *
67       * @param array  the array to remove the element from, may not be {@code null}
68       * @param index  the position of the element to be removed
69       * @return A new array containing the existing elements except the element
70       *         at the specified position.
71       * @throws IndexOutOfBoundsException if the index is out of range
72       * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
73       * @since 2.1
74       */
75      private static Object remove(final Object array, final int index) {
76          final int length = getLength(array);
77          if (index < 0 || index >= length) {
78              throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
79          }
80  
81          final Object result = Array.newInstance(array.getClass().getComponentType(), length - 1);
82          System.arraycopy(array, 0, result, 0, index);
83          if (index < length - 1) {
84              System.arraycopy(array, index + 1, result, index, length - index - 1);
85          }
86  
87          return result;
88      }
89  
90      /**
91       * <p>Removes the element at the specified position from the specified array.
92       * All subsequent elements are shifted to the left (subtracts one from
93       * their indices).</p>
94       *
95       * <p>This method returns a new array with the same elements of the input
96       * array except the element on the specified position. The component
97       * type of the returned array is always the same as that of the input
98       * array.</p>
99       *
100      * <p>If the input array is {@code null}, an IndexOutOfBoundsException
101      * will be thrown, because in that case no valid index can be specified.</p>
102      *
103      * <pre>
104      * ArrayUtils.remove(["a"], 0)           = []
105      * ArrayUtils.remove(["a", "b"], 0)      = ["b"]
106      * ArrayUtils.remove(["a", "b"], 1)      = ["a"]
107      * ArrayUtils.remove(["a", "b", "c"], 1) = ["a", "c"]
108      * </pre>
109      *
110      * @param <T> the component type of the array
111      * @param array  the array to remove the element from, may not be {@code null}
112      * @param index  the position of the element to be removed
113      * @return A new array containing the existing elements except the element
114      *         at the specified position.
115      * @throws IndexOutOfBoundsException if the index is out of range
116      * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
117      * @since 2.1
118      */
119     @SuppressWarnings("unchecked") // remove() always creates an array of the same type as its input
120     public static <T> T[] remove(final T[] array, final int index) {
121         return (T[]) remove((Object) array, index);
122     }
123 
124 }