commit be82ec268d1543ac645b915a39708093af13b303 Author: richie Date: Tue Dec 4 07:33:19 2018 +0800 http认证示例 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3b70219 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.iml +.idea/ +.DS_Store +.classpath \ No newline at end of file diff --git a/dist/http.jar b/dist/http.jar new file mode 100644 index 0000000..950e705 Binary files /dev/null and b/dist/http.jar differ diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..a5be5c3 --- /dev/null +++ b/readme.md @@ -0,0 +1,20 @@ +# http认证示例 + +在决策平台中做如下配置: + +![setting](screenshots/1.png) + +启动dist下的java应用程序: + +``` + java -jar http.jar + +``` + +可以看到类似的输出: + +![2](screenshots/2.png) + +这个时候登录决策平台,能看到测试认证服务器的一些提示输出: + +![3](screenshots/3.png) diff --git a/screenshots/1.png b/screenshots/1.png new file mode 100644 index 0000000..0ae6ac9 Binary files /dev/null and b/screenshots/1.png differ diff --git a/screenshots/2.png b/screenshots/2.png new file mode 100644 index 0000000..8d48fdc Binary files /dev/null and b/screenshots/2.png differ diff --git a/screenshots/3.png b/screenshots/3.png new file mode 100644 index 0000000..2bf5f56 Binary files /dev/null and b/screenshots/3.png differ diff --git a/src/Http.java b/src/Http.java new file mode 100644 index 0000000..71d614f --- /dev/null +++ b/src/Http.java @@ -0,0 +1,121 @@ +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; +import helper.KeyReader; +import helper.RSAUtils; +import helper.StringUtils; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.net.InetSocketAddress; +import java.net.URI; +import java.net.URLDecoder; +import java.util.HashMap; +import java.util.Map; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2018-12-03 + * http认证demo服务器 + */ +public class Http { + + public static void main(String... args) throws IOException { + HttpServer server = HttpServer.create(new InetSocketAddress(8001), 0); + server.createContext("/demo", new AuthHandler()); + server.start(); + System.out.println("Server is started, please visit:http://localhost:8001/demo"); + } + + private static class AuthHandler implements HttpHandler { + + @Override + public void handle(HttpExchange exchange) throws IOException { + exchange.sendResponseHeaders(200, 0); + URI uri = exchange.getRequestURI(); + Map parameters = parserQueryText(uri.getQuery()); + + String data = parameters.get("data"); + + // (必须)http认证的地方填的是公钥,则这里需要用私钥进行解密 + String text = RSAUtils.decrypt(data, KeyReader.getPrivateKey()); + + System.out.println("data:" + text); + + Map map = parserText(text); + + String responseText; + + // username参数是从报表登录界面输入的地方获取的 + String username = map.get("username"); + // password参数是从报表登录界面输入的地方获取的 + String password = map.get("password"); + // uuid参数是报表发送http认证请求的时候生成的随机数 + String uuid = map.get("uuid"); + + if (isValidUser(username, password)) { + // (必须)认证成功时返回的文本格式{"success":"true","uuid":"xxx-yyy-zzz-dddd"} + responseText = String.format("{\"success\":\"true\",\"uuid\":\"%s\"}", uuid); + } else { + responseText = "{\"success\":\"false\"}"; + } + + System.out.println("responseText:" + responseText); + + // (必须)这里需要把返回值用私钥进行加密,在报表服务器中,会自动使用公钥进行解密 + String returnValue = RSAUtils.encrypt(responseText, KeyReader.getPrivateKey()); + + OutputStream os = exchange.getResponseBody(); + os.write(returnValue.getBytes()); + os.close(); + } + } + + /** + * 判断username和password是否可以正确的登录 + * @param username 用户名 + * @param password 密码 + * @return 如果能正确登录,则这里返回true表示,如果不能正确登录,则这里返回false表示 + */ + private static boolean isValidUser(String username, String password) { + if (username == null || password == null) { + return false; + } + // 这里只是一个示例,当用户名和密码输入一样的时候,我们假设认证成功,允许登录 + return username.equals(password); + } + + private static Map parserQueryText(String query) throws UnsupportedEncodingException { + Map map = new HashMap(); + if (query == null) { + return map; + } + String[] pairs = query.split("&"); + for (String pair : pairs) { + int idx = pair.indexOf("="); + map.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"), URLDecoder.decode(pair.substring(idx + 1), "UTF-8")); + } + return map; + } + + private static Map parserText(String text) { + Map map = new HashMap<>(); + if (StringUtils.isEmpty(text)) { + return map; + } + if (text.startsWith("{") && text.endsWith("}")) { + String[] arr = text.substring(1, text.length() - 1).split(","); + for (String child : arr) { + String[] pair = child.split(":"); + String key = pair[0]; + String value = pair[1]; + map.put(key.substring(1, key.length() - 1), value.substring(1, value.length() - 1)); + } + return map; + } else { + return map; + } + } +} diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF new file mode 100644 index 0000000..44414ae --- /dev/null +++ b/src/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: Http + diff --git a/src/helper/ArrayUtils.java b/src/helper/ArrayUtils.java new file mode 100644 index 0000000..afdb59a --- /dev/null +++ b/src/helper/ArrayUtils.java @@ -0,0 +1,4300 @@ +package helper;/* + * 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. + */ + +import java.lang.reflect.Array; +import java.util.HashMap; +import java.util.Map; +import java.util.ArrayList; +import java.util.List; +import java.util.Collections; + +/** + *

Operations on arrays, primitive arrays (like int[]) and + * primitive wrapper arrays (like Integer[]).

+ *

+ *

This class tries to handle null input gracefully. + * An exception will not be thrown for a null + * array input. However, an Object array that contains a null + * element may throw an exception. Each method documents its behaviour.

+ * + * @author Stephen Colebourne + * @author Moritz Petersen + * @author Fredrik Westermarck + * @author Nikolay Metchev + * @author Matthew Hawthorne + * @author Tim O'Brien + * @author Pete Gieser + * @author Gary Gregory + * @author Ashwin S + * @author Maarten Coene + * @version $Id: helper.ArrayUtils.java 632503 2008-03-01 00:21:52Z ggregory $ + * @since 2.0 + */ +public class ArrayUtils { + + /** + * An empty immutable Object array. + */ + public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; + /** + * An empty immutable Class array. + */ + public static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; + /** + * An empty immutable String array. + */ + public static final String[] EMPTY_STRING_ARRAY = new String[0]; + /** + * An empty immutable long array. + */ + public static final long[] EMPTY_LONG_ARRAY = new long[0]; + /** + * An empty immutable Long array. + */ + public static final Long[] EMPTY_LONG_OBJECT_ARRAY = new Long[0]; + /** + * An empty immutable int array. + */ + public static final int[] EMPTY_INT_ARRAY = new int[0]; + /** + * An empty immutable Integer array. + */ + public static final Integer[] EMPTY_INTEGER_OBJECT_ARRAY = new Integer[0]; + /** + * An empty immutable short array. + */ + public static final short[] EMPTY_SHORT_ARRAY = new short[0]; + /** + * An empty immutable Short array. + */ + public static final Short[] EMPTY_SHORT_OBJECT_ARRAY = new Short[0]; + /** + * An empty immutable byte array. + */ + public static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; + /** + * An empty immutable Byte array. + */ + public static final Byte[] EMPTY_BYTE_OBJECT_ARRAY = new Byte[0]; + /** + * An empty immutable double array. + */ + public static final double[] EMPTY_DOUBLE_ARRAY = new double[0]; + /** + * An empty immutable Double array. + */ + public static final Double[] EMPTY_DOUBLE_OBJECT_ARRAY = new Double[0]; + /** + * An empty immutable float array. + */ + public static final float[] EMPTY_FLOAT_ARRAY = new float[0]; + /** + * An empty immutable Float array. + */ + public static final Float[] EMPTY_FLOAT_OBJECT_ARRAY = new Float[0]; + /** + * An empty immutable boolean array. + */ + public static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0]; + /** + * An empty immutable Boolean array. + */ + public static final Boolean[] EMPTY_BOOLEAN_OBJECT_ARRAY = new Boolean[0]; + /** + * An empty immutable char array. + */ + public static final char[] EMPTY_CHAR_ARRAY = new char[0]; + /** + * An empty immutable Character array. + */ + public static final Character[] EMPTY_CHARACTER_OBJECT_ARRAY = new Character[0]; + + /** + * The index value when an element is not found in a list or array: -1. + * This value is returned by methods in this class and can also be used in comparisons with values returned by + * various method from {@link java.util.List}. + */ + public static final int INDEX_NOT_FOUND = -1; + + /** + *

helper.ArrayUtils instances should NOT be constructed in standard programming. + * Instead, the class should be used as helper.ArrayUtils.clone(new int[] {2}).

+ *

+ *

This constructor is public to permit tools that require a JavaBean instance + * to operate.

+ */ + private ArrayUtils() { + } + + // To map + //----------------------------------------------------------------------- + + /** + *

Converts the given array into a {@link Map}. Each element of the array + * must be either a {@link Map.Entry} or an Array, containing at least two + * elements, where the first element is used as key and the second as + * value.

+ *

+ *

This method can be used to initialize:

+ *
+     * // Create a Map mapping colors.
+     * Map colorMap = MapUtils.toMap(new String[][] {{
+     *     {"RED", "#FF0000"},
+     *     {"GREEN", "#00FF00"},
+     *     {"BLUE", "#0000FF"}});
+     * 
+ *

+ *

This method returns null for a null input array.

+ * + * @param array an array whose elements are either a {@link Map.Entry} or + * an Array containing at least two elements, may be null + * @return a Map that was created from the array + * @throws IllegalArgumentException if one element of this Array is + * itself an Array containing less then two elements + * @throws IllegalArgumentException if the array contains elements other + * than {@link Map.Entry} and an Array + */ + public static Map toMap(Object[] array) { + if (array == null) { + return null; + } + final Map map = new HashMap((int) (array.length * 1.5)); + for (int i = 0; i < array.length; i++) { + Object object = array[i]; + if (object instanceof Map.Entry) { + Map.Entry entry = (Map.Entry) object; + map.put(entry.getKey(), entry.getValue()); + } else if (object instanceof Object[]) { + Object[] entry = (Object[]) object; + if (entry.length < 2) { + throw new IllegalArgumentException("Array element " + i + ", '" + + object + + "', has a length less than 2"); + } + map.put(entry[0], entry[1]); + } else { + throw new IllegalArgumentException("Array element " + i + ", '" + + object + + "', is neither of type Map.Entry nor an Array"); + } + } + return map; + } + + // Clone + //----------------------------------------------------------------------- + + /** + *

Shallow clones an array returning a typecast result and handling + * null.

+ *

+ *

The objects in the array are not cloned, thus there is no special + * handling for multi-dimensional arrays.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array the array to shallow clone, may be null + * @return the cloned array, null if null input + */ + public static T[] clone(T[] array) { + if (array == null) { + return null; + } + return array.clone(); + } + + /** + *

Clones an array returning a typecast result and handling + * null.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array the array to clone, may be null + * @return the cloned array, null if null input + */ + public static long[] clone(long[] array) { + if (array == null) { + return null; + } + return array.clone(); + } + + /** + *

Clones an array returning a typecast result and handling + * null.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array the array to clone, may be null + * @return the cloned array, null if null input + */ + public static int[] clone(int[] array) { + if (array == null) { + return null; + } + return array.clone(); + } + + /** + *

Clones an array returning a typecast result and handling + * null.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array the array to clone, may be null + * @return the cloned array, null if null input + */ + public static short[] clone(short[] array) { + if (array == null) { + return null; + } + return array.clone(); + } + + /** + *

Clones an array returning a typecast result and handling + * null.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array the array to clone, may be null + * @return the cloned array, null if null input + */ + public static char[] clone(char[] array) { + if (array == null) { + return null; + } + return array.clone(); + } + + /** + *

Clones an array returning a typecast result and handling + * null.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array the array to clone, may be null + * @return the cloned array, null if null input + */ + public static byte[] clone(byte[] array) { + if (array == null) { + return null; + } + return array.clone(); + } + + /** + *

Clones an array returning a typecast result and handling + * null.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array the array to clone, may be null + * @return the cloned array, null if null input + */ + public static double[] clone(double[] array) { + if (array == null) { + return null; + } + return array.clone(); + } + + /** + *

Clones an array returning a typecast result and handling + * null.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array the array to clone, may be null + * @return the cloned array, null if null input + */ + public static float[] clone(float[] array) { + if (array == null) { + return null; + } + return array.clone(); + } + + /** + *

Clones an array returning a typecast result and handling + * null.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array the array to clone, may be null + * @return the cloned array, null if null input + */ + public static boolean[] clone(boolean[] array) { + if (array == null) { + return null; + } + return array.clone(); + } + + // Subarrays + //----------------------------------------------------------------------- + + /** + *

Produces a new array containing the elements between + * the start and end indices.

+ *

+ *

The start index is inclusive, the end index exclusive. + * Null array input produces null output.

+ *

+ *

The component type of the subarray is always the same as + * that of the input array. Thus, if the input is an array of type + * Date, the following usage is envisaged:

+ *

+ *

+     * Date[] someDates = (Date[])helper.ArrayUtils.subarray(allDates, 2, 5);
+     * 
+ * + * @param array the array + * @param startIndexInclusive the starting index. Undervalue (<0) + * is promoted to 0, overvalue (>array.length) results + * in an empty array. + * @param endIndexExclusive elements up to endIndex-1 are present in the + * returned subarray. Undervalue (< startIndex) produces + * empty array, overvalue (>array.length) is demoted to + * array length. + * @return a new array containing the elements between + * the start and end indices. + * @since 2.1 + */ + public static Object[] subarray(Object[] array, int startIndexInclusive, int endIndexExclusive) { + if (array == null) { + return null; + } + if (startIndexInclusive < 0) { + startIndexInclusive = 0; + } + if (endIndexExclusive > array.length) { + endIndexExclusive = array.length; + } + int newSize = endIndexExclusive - startIndexInclusive; + Class type = array.getClass().getComponentType(); + if (newSize <= 0) { + return (Object[]) Array.newInstance(type, 0); + } + Object[] subarray = (Object[]) Array.newInstance(type, newSize); + System.arraycopy(array, startIndexInclusive, subarray, 0, newSize); + return subarray; + } + + /** + *

Produces a new long array containing the elements + * between the start and end indices.

+ *

+ *

The start index is inclusive, the end index exclusive. + * Null array input produces null output.

+ * + * @param array the array + * @param startIndexInclusive the starting index. Undervalue (<0) + * is promoted to 0, overvalue (>array.length) results + * in an empty array. + * @param endIndexExclusive elements up to endIndex-1 are present in the + * returned subarray. Undervalue (< startIndex) produces + * empty array, overvalue (>array.length) is demoted to + * array length. + * @return a new array containing the elements between + * the start and end indices. + * @since 2.1 + */ + public static long[] subarray(long[] array, int startIndexInclusive, int endIndexExclusive) { + if (array == null) { + return null; + } + if (startIndexInclusive < 0) { + startIndexInclusive = 0; + } + if (endIndexExclusive > array.length) { + endIndexExclusive = array.length; + } + int newSize = endIndexExclusive - startIndexInclusive; + if (newSize <= 0) { + return EMPTY_LONG_ARRAY; + } + + long[] subarray = new long[newSize]; + System.arraycopy(array, startIndexInclusive, subarray, 0, newSize); + return subarray; + } + + /** + *

Produces a new int array containing the elements + * between the start and end indices.

+ *

+ *

The start index is inclusive, the end index exclusive. + * Null array input produces null output.

+ * + * @param array the array + * @param startIndexInclusive the starting index. Undervalue (<0) + * is promoted to 0, overvalue (>array.length) results + * in an empty array. + * @param endIndexExclusive elements up to endIndex-1 are present in the + * returned subarray. Undervalue (< startIndex) produces + * empty array, overvalue (>array.length) is demoted to + * array length. + * @return a new array containing the elements between + * the start and end indices. + * @since 2.1 + */ + public static int[] subarray(int[] array, int startIndexInclusive, int endIndexExclusive) { + if (array == null) { + return null; + } + if (startIndexInclusive < 0) { + startIndexInclusive = 0; + } + if (endIndexExclusive > array.length) { + endIndexExclusive = array.length; + } + int newSize = endIndexExclusive - startIndexInclusive; + if (newSize <= 0) { + return EMPTY_INT_ARRAY; + } + + int[] subarray = new int[newSize]; + System.arraycopy(array, startIndexInclusive, subarray, 0, newSize); + return subarray; + } + + /** + *

Produces a new short array containing the elements + * between the start and end indices.

+ *

+ *

The start index is inclusive, the end index exclusive. + * Null array input produces null output.

+ * + * @param array the array + * @param startIndexInclusive the starting index. Undervalue (<0) + * is promoted to 0, overvalue (>array.length) results + * in an empty array. + * @param endIndexExclusive elements up to endIndex-1 are present in the + * returned subarray. Undervalue (< startIndex) produces + * empty array, overvalue (>array.length) is demoted to + * array length. + * @return a new array containing the elements between + * the start and end indices. + * @since 2.1 + */ + public static short[] subarray(short[] array, int startIndexInclusive, int endIndexExclusive) { + if (array == null) { + return null; + } + if (startIndexInclusive < 0) { + startIndexInclusive = 0; + } + if (endIndexExclusive > array.length) { + endIndexExclusive = array.length; + } + int newSize = endIndexExclusive - startIndexInclusive; + if (newSize <= 0) { + return EMPTY_SHORT_ARRAY; + } + + short[] subarray = new short[newSize]; + System.arraycopy(array, startIndexInclusive, subarray, 0, newSize); + return subarray; + } + + /** + *

Produces a new char array containing the elements + * between the start and end indices.

+ *

+ *

The start index is inclusive, the end index exclusive. + * Null array input produces null output.

+ * + * @param array the array + * @param startIndexInclusive the starting index. Undervalue (<0) + * is promoted to 0, overvalue (>array.length) results + * in an empty array. + * @param endIndexExclusive elements up to endIndex-1 are present in the + * returned subarray. Undervalue (< startIndex) produces + * empty array, overvalue (>array.length) is demoted to + * array length. + * @return a new array containing the elements between + * the start and end indices. + * @since 2.1 + */ + public static char[] subarray(char[] array, int startIndexInclusive, int endIndexExclusive) { + if (array == null) { + return null; + } + if (startIndexInclusive < 0) { + startIndexInclusive = 0; + } + if (endIndexExclusive > array.length) { + endIndexExclusive = array.length; + } + int newSize = endIndexExclusive - startIndexInclusive; + if (newSize <= 0) { + return EMPTY_CHAR_ARRAY; + } + + char[] subarray = new char[newSize]; + System.arraycopy(array, startIndexInclusive, subarray, 0, newSize); + return subarray; + } + + /** + *

Produces a new byte array containing the elements + * between the start and end indices.

+ *

+ *

The start index is inclusive, the end index exclusive. + * Null array input produces null output.

+ * + * @param array the array + * @param startIndexInclusive the starting index. Undervalue (<0) + * is promoted to 0, overvalue (>array.length) results + * in an empty array. + * @param endIndexExclusive elements up to endIndex-1 are present in the + * returned subarray. Undervalue (< startIndex) produces + * empty array, overvalue (>array.length) is demoted to + * array length. + * @return a new array containing the elements between + * the start and end indices. + * @since 2.1 + */ + public static byte[] subarray(byte[] array, int startIndexInclusive, int endIndexExclusive) { + if (array == null) { + return null; + } + if (startIndexInclusive < 0) { + startIndexInclusive = 0; + } + if (endIndexExclusive > array.length) { + endIndexExclusive = array.length; + } + int newSize = endIndexExclusive - startIndexInclusive; + if (newSize <= 0) { + return EMPTY_BYTE_ARRAY; + } + + byte[] subarray = new byte[newSize]; + System.arraycopy(array, startIndexInclusive, subarray, 0, newSize); + return subarray; + } + + /** + *

Produces a new double array containing the elements + * between the start and end indices.

+ *

+ *

The start index is inclusive, the end index exclusive. + * Null array input produces null output.

+ * + * @param array the array + * @param startIndexInclusive the starting index. Undervalue (<0) + * is promoted to 0, overvalue (>array.length) results + * in an empty array. + * @param endIndexExclusive elements up to endIndex-1 are present in the + * returned subarray. Undervalue (< startIndex) produces + * empty array, overvalue (>array.length) is demoted to + * array length. + * @return a new array containing the elements between + * the start and end indices. + * @since 2.1 + */ + public static double[] subarray(double[] array, int startIndexInclusive, int endIndexExclusive) { + if (array == null) { + return null; + } + if (startIndexInclusive < 0) { + startIndexInclusive = 0; + } + if (endIndexExclusive > array.length) { + endIndexExclusive = array.length; + } + int newSize = endIndexExclusive - startIndexInclusive; + if (newSize <= 0) { + return EMPTY_DOUBLE_ARRAY; + } + + double[] subarray = new double[newSize]; + System.arraycopy(array, startIndexInclusive, subarray, 0, newSize); + return subarray; + } + + /** + *

Produces a new float array containing the elements + * between the start and end indices.

+ *

+ *

The start index is inclusive, the end index exclusive. + * Null array input produces null output.

+ * + * @param array the array + * @param startIndexInclusive the starting index. Undervalue (<0) + * is promoted to 0, overvalue (>array.length) results + * in an empty array. + * @param endIndexExclusive elements up to endIndex-1 are present in the + * returned subarray. Undervalue (< startIndex) produces + * empty array, overvalue (>array.length) is demoted to + * array length. + * @return a new array containing the elements between + * the start and end indices. + * @since 2.1 + */ + public static float[] subarray(float[] array, int startIndexInclusive, int endIndexExclusive) { + if (array == null) { + return null; + } + if (startIndexInclusive < 0) { + startIndexInclusive = 0; + } + if (endIndexExclusive > array.length) { + endIndexExclusive = array.length; + } + int newSize = endIndexExclusive - startIndexInclusive; + if (newSize <= 0) { + return EMPTY_FLOAT_ARRAY; + } + + float[] subarray = new float[newSize]; + System.arraycopy(array, startIndexInclusive, subarray, 0, newSize); + return subarray; + } + + /** + *

Produces a new boolean array containing the elements + * between the start and end indices.

+ *

+ *

The start index is inclusive, the end index exclusive. + * Null array input produces null output.

+ * + * @param array the array + * @param startIndexInclusive the starting index. Undervalue (<0) + * is promoted to 0, overvalue (>array.length) results + * in an empty array. + * @param endIndexExclusive elements up to endIndex-1 are present in the + * returned subarray. Undervalue (< startIndex) produces + * empty array, overvalue (>array.length) is demoted to + * array length. + * @return a new array containing the elements between + * the start and end indices. + * @since 2.1 + */ + public static boolean[] subarray(boolean[] array, int startIndexInclusive, int endIndexExclusive) { + if (array == null) { + return null; + } + if (startIndexInclusive < 0) { + startIndexInclusive = 0; + } + if (endIndexExclusive > array.length) { + endIndexExclusive = array.length; + } + int newSize = endIndexExclusive - startIndexInclusive; + if (newSize <= 0) { + return EMPTY_BOOLEAN_ARRAY; + } + + boolean[] subarray = new boolean[newSize]; + System.arraycopy(array, startIndexInclusive, subarray, 0, newSize); + return subarray; + } + + // Is same length + //----------------------------------------------------------------------- + + /** + *

Checks whether two arrays are the same length, treating + * null arrays as length 0. + *

+ *

Any multi-dimensional aspects of the arrays are ignored.

+ * + * @param array1 the first array, may be null + * @param array2 the second array, may be null + * @return true if length of arrays matches, treating + * null as an empty array + */ + public static boolean isSameLength(Object[] array1, Object[] array2) { + return ArrayUtils.getLength(array1) == ArrayUtils.getLength(array2); + } + + public static boolean isSameArray(int[] array1, int[] array2) { + int len1 = array1 == null ? 0 : array1.length; + int len2 = array2 == null ? 0 : array2.length; + if (len1 != len2) { + return false; + } + + for (int i = 0; i < len1; i++) { + if (array1[i] != array2[i]) { + return false; + } + } + + return true; + } + + public static boolean isSameArray(byte[] array1, byte[] array2) { + int len1 = array1 == null ? 0 : array1.length; + int len2 = array2 == null ? 0 : array2.length; + if (len1 != len2) { + return false; + } + + for (int i = 0; i < len1; i++) { + if (array1[i] != array2[i]) { + return false; + } + } + + return true; + } + + //----------------------------------------------------------------------- + + /** + *

Returns the length of the specified array. + * This method can deal with Object arrays and with primitive arrays.

+ *

+ *

If the input array is null, 0 is returned.

+ *

+ *

+     * helper.ArrayUtils.getLength(null)            = 0
+     * helper.ArrayUtils.getLength([])              = 0
+     * helper.ArrayUtils.getLength([null])          = 1
+     * helper.ArrayUtils.getLength([true, false])   = 2
+     * helper.ArrayUtils.getLength([1, 2, 3])       = 3
+     * helper.ArrayUtils.getLength(["a", "b", "c"]) = 3
+     * 
+ * + * @param array the array to retrieve the length from, may be null + * @return The length of the array, or 0 if the array is null + * @throws IllegalArgumentException if the object arguement is not an array. + * @since 2.1 + */ + public static int getLength(Object array) { + if (array == null) { + return 0; + } + return Array.getLength(array); + } + + /** + *

Checks whether two arrays are the same type taking into account + * multi-dimensional arrays.

+ * + * @param array1 the first array, must not be null + * @param array2 the second array, must not be null + * @return true if type of arrays matches + * @throws IllegalArgumentException if either array is null + */ + public static boolean isSameType(Object array1, Object array2) { + if (array1 == null || array2 == null) { + throw new IllegalArgumentException("The Array must not be null"); + } + return array1.getClass().getName().equals(array2.getClass().getName()); + } + + // Reverse + //----------------------------------------------------------------------- + + /** + *

Reverses the order of the given array.

+ *

+ *

There is no special handling for multi-dimensional arrays.

+ *

+ *

This method does nothing for a null input array.

+ * + * @param array the array to reverse, may be null + */ + public static void reverse(Object[] array) { + if (array == null) { + return; + } + int i = 0; + int j = array.length - 1; + Object tmp; + while (j > i) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + j--; + i++; + } + } + + /** + *

Reverses the order of the given array.

+ *

+ *

This method does nothing for a null input array.

+ * + * @param array the array to reverse, may be null + */ + public static void reverse(long[] array) { + if (array == null) { + return; + } + int i = 0; + int j = array.length - 1; + long tmp; + while (j > i) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + j--; + i++; + } + } + + /** + *

Reverses the order of the given array.

+ *

+ *

This method does nothing for a null input array.

+ * + * @param array the array to reverse, may be null + */ + public static void reverse(int[] array) { + if (array == null) { + return; + } + int i = 0; + int j = array.length - 1; + int tmp; + while (j > i) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + j--; + i++; + } + } + + /** + *

Reverses the order of the given array.

+ *

+ *

This method does nothing for a null input array.

+ * + * @param array the array to reverse, may be null + */ + public static void reverse(short[] array) { + if (array == null) { + return; + } + int i = 0; + int j = array.length - 1; + short tmp; + while (j > i) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + j--; + i++; + } + } + + /** + *

Reverses the order of the given array.

+ *

+ *

This method does nothing for a null input array.

+ * + * @param array the array to reverse, may be null + */ + public static void reverse(char[] array) { + if (array == null) { + return; + } + int i = 0; + int j = array.length - 1; + char tmp; + while (j > i) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + j--; + i++; + } + } + + /** + *

Reverses the order of the given array.

+ *

+ *

This method does nothing for a null input array.

+ * + * @param array the array to reverse, may be null + */ + public static void reverse(byte[] array) { + if (array == null) { + return; + } + int i = 0; + int j = array.length - 1; + byte tmp; + while (j > i) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + j--; + i++; + } + } + + /** + *

Reverses the order of the given array.

+ *

+ *

This method does nothing for a null input array.

+ * + * @param array the array to reverse, may be null + */ + public static void reverse(double[] array) { + if (array == null) { + return; + } + int i = 0; + int j = array.length - 1; + double tmp; + while (j > i) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + j--; + i++; + } + } + + /** + *

Reverses the order of the given array.

+ *

+ *

This method does nothing for a null input array.

+ * + * @param array the array to reverse, may be null + */ + public static void reverse(float[] array) { + if (array == null) { + return; + } + int i = 0; + int j = array.length - 1; + float tmp; + while (j > i) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + j--; + i++; + } + } + + /** + *

Reverses the order of the given array.

+ *

+ *

This method does nothing for a null input array.

+ * + * @param array the array to reverse, may be null + */ + public static void reverse(boolean[] array) { + if (array == null) { + return; + } + int i = 0; + int j = array.length - 1; + boolean tmp; + while (j > i) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + j--; + i++; + } + } + + // IndexOf search + // ---------------------------------------------------------------------- + + // Object IndexOf + //----------------------------------------------------------------------- + + /** + *

Finds the index of the given object in the array.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ * + * @param array the array to search through for the object, may be null + * @param objectToFind the object to find, may be null + * @return the index of the object within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int indexOf(Object[] array, Object objectToFind) { + return indexOf(array, objectToFind, 0); + } + + /** + *

Finds the index of the given object in the array starting at the given index.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ *

+ *

A negative startIndex is treated as zero. A startIndex larger than the array + * length will return {@link #INDEX_NOT_FOUND} (-1).

+ * + * @param array the array to search through for the object, may be null + * @param objectToFind the object to find, may be null + * @param startIndex the index to start searching at + * @return the index of the object within the array starting at the index, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int indexOf(Object[] array, Object objectToFind, int startIndex) { + if (array == null) { + return INDEX_NOT_FOUND; + } + if (startIndex < 0) { + startIndex = 0; + } + if (objectToFind == null) { + for (int i = startIndex; i < array.length; i++) { + if (array[i] == null) { + return i; + } + } + } else { + for (int i = startIndex; i < array.length; i++) { + if (objectToFind.equals(array[i])) { + return i; + } + } + } + return INDEX_NOT_FOUND; + } + + /** + *

Finds the last index of the given object within the array.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ * + * @param array the array to travers backwords looking for the object, may be null + * @param objectToFind the object to find, may be null + * @return the last index of the object within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int lastIndexOf(Object[] array, Object objectToFind) { + return lastIndexOf(array, objectToFind, Integer.MAX_VALUE); + } + + /** + *

Finds the last index of the given object in the array starting at the given index.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ *

+ *

A negative startIndex will return {@link #INDEX_NOT_FOUND} (-1). A startIndex larger than + * the array length will search from the end of the array.

+ * + * @param array the array to traverse for looking for the object, may be null + * @param objectToFind the object to find, may be null + * @param startIndex the start index to travers backwards from + * @return the last index of the object within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int lastIndexOf(Object[] array, Object objectToFind, int startIndex) { + if (array == null) { + return INDEX_NOT_FOUND; + } + if (startIndex < 0) { + return INDEX_NOT_FOUND; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + if (objectToFind == null) { + for (int i = startIndex; i >= 0; i--) { + if (array[i] == null) { + return i; + } + } + } else { + for (int i = startIndex; i >= 0; i--) { + if (objectToFind.equals(array[i])) { + return i; + } + } + } + return INDEX_NOT_FOUND; + } + + /** + *

Checks if the object is in the given array.

+ *

+ *

The method returns false if a null array is passed in.

+ * + * @param array the array to search through + * @param objectToFind the object to find + * @return true if the array contains the object + */ + public static boolean contains(Object[] array, Object objectToFind) { + return indexOf(array, objectToFind) != INDEX_NOT_FOUND; + } + + // long IndexOf + //----------------------------------------------------------------------- + + /** + *

Finds the index of the given value in the array.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @return the index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int indexOf(long[] array, long valueToFind) { + return indexOf(array, valueToFind, 0); + } + + /** + *

Finds the index of the given value in the array starting at the given index.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ *

+ *

A negative startIndex is treated as zero. A startIndex larger than the array + * length will return {@link #INDEX_NOT_FOUND} (-1).

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @param startIndex the index to start searching at + * @return the index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int indexOf(long[] array, long valueToFind, int startIndex) { + if (array == null) { + return INDEX_NOT_FOUND; + } + if (startIndex < 0) { + startIndex = 0; + } + for (int i = startIndex; i < array.length; i++) { + if (valueToFind == array[i]) { + return i; + } + } + return INDEX_NOT_FOUND; + } + + /** + *

Finds the last index of the given value within the array.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ * + * @param array the array to travers backwords looking for the object, may be null + * @param valueToFind the object to find + * @return the last index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int lastIndexOf(long[] array, long valueToFind) { + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE); + } + + /** + *

Finds the last index of the given value in the array starting at the given index.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ *

+ *

A negative startIndex will return {@link #INDEX_NOT_FOUND} (-1). A startIndex larger than the + * array length will search from the end of the array.

+ * + * @param array the array to traverse for looking for the object, may be null + * @param valueToFind the value to find + * @param startIndex the start index to travers backwards from + * @return the last index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int lastIndexOf(long[] array, long valueToFind, int startIndex) { + if (array == null) { + return INDEX_NOT_FOUND; + } + if (startIndex < 0) { + return INDEX_NOT_FOUND; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + for (int i = startIndex; i >= 0; i--) { + if (valueToFind == array[i]) { + return i; + } + } + return INDEX_NOT_FOUND; + } + + /** + *

Checks if the value is in the given array.

+ *

+ *

The method returns false if a null array is passed in.

+ * + * @param array the array to search through + * @param valueToFind the value to find + * @return true if the array contains the object + */ + public static boolean contains(long[] array, long valueToFind) { + return indexOf(array, valueToFind) != INDEX_NOT_FOUND; + } + + // int IndexOf + //----------------------------------------------------------------------- + + /** + *

Finds the index of the given value in the array.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @return the index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int indexOf(int[] array, int valueToFind) { + return indexOf(array, valueToFind, 0); + } + + /** + *

Finds the index of the given value in the array starting at the given index.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ *

+ *

A negative startIndex is treated as zero. A startIndex larger than the array + * length will return {@link #INDEX_NOT_FOUND} (-1).

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @param startIndex the index to start searching at + * @return the index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int indexOf(int[] array, int valueToFind, int startIndex) { + if (array == null) { + return INDEX_NOT_FOUND; + } + if (startIndex < 0) { + startIndex = 0; + } + for (int i = startIndex; i < array.length; i++) { + if (valueToFind == array[i]) { + return i; + } + } + return INDEX_NOT_FOUND; + } + + /** + *

Finds the last index of the given value within the array.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ * + * @param array the array to travers backwords looking for the object, may be null + * @param valueToFind the object to find + * @return the last index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int lastIndexOf(int[] array, int valueToFind) { + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE); + } + + /** + *

Finds the last index of the given value in the array starting at the given index.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ *

+ *

A negative startIndex will return {@link #INDEX_NOT_FOUND} (-1). A startIndex larger than the + * array length will search from the end of the array.

+ * + * @param array the array to traverse for looking for the object, may be null + * @param valueToFind the value to find + * @param startIndex the start index to travers backwards from + * @return the last index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int lastIndexOf(int[] array, int valueToFind, int startIndex) { + if (array == null) { + return INDEX_NOT_FOUND; + } + if (startIndex < 0) { + return INDEX_NOT_FOUND; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + for (int i = startIndex; i >= 0; i--) { + if (valueToFind == array[i]) { + return i; + } + } + return INDEX_NOT_FOUND; + } + + /** + *

Checks if the value is in the given array.

+ *

+ *

The method returns false if a null array is passed in.

+ * + * @param array the array to search through + * @param valueToFind the value to find + * @return true if the array contains the object + */ + public static boolean contains(int[] array, int valueToFind) { + return indexOf(array, valueToFind) != INDEX_NOT_FOUND; + } + + // short IndexOf + //----------------------------------------------------------------------- + + /** + *

Finds the index of the given value in the array.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @return the index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int indexOf(short[] array, short valueToFind) { + return indexOf(array, valueToFind, 0); + } + + /** + *

Finds the index of the given value in the array starting at the given index.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ *

+ *

A negative startIndex is treated as zero. A startIndex larger than the array + * length will return {@link #INDEX_NOT_FOUND} (-1).

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @param startIndex the index to start searching at + * @return the index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int indexOf(short[] array, short valueToFind, int startIndex) { + if (array == null) { + return INDEX_NOT_FOUND; + } + if (startIndex < 0) { + startIndex = 0; + } + for (int i = startIndex; i < array.length; i++) { + if (valueToFind == array[i]) { + return i; + } + } + return INDEX_NOT_FOUND; + } + + /** + *

Finds the last index of the given value within the array.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ * + * @param array the array to travers backwords looking for the object, may be null + * @param valueToFind the object to find + * @return the last index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int lastIndexOf(short[] array, short valueToFind) { + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE); + } + + /** + *

Finds the last index of the given value in the array starting at the given index.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ *

+ *

A negative startIndex will return {@link #INDEX_NOT_FOUND} (-1). A startIndex larger than the + * array length will search from the end of the array.

+ * + * @param array the array to traverse for looking for the object, may be null + * @param valueToFind the value to find + * @param startIndex the start index to travers backwards from + * @return the last index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int lastIndexOf(short[] array, short valueToFind, int startIndex) { + if (array == null) { + return INDEX_NOT_FOUND; + } + if (startIndex < 0) { + return INDEX_NOT_FOUND; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + for (int i = startIndex; i >= 0; i--) { + if (valueToFind == array[i]) { + return i; + } + } + return INDEX_NOT_FOUND; + } + + /** + *

Checks if the value is in the given array.

+ *

+ *

The method returns false if a null array is passed in.

+ * + * @param array the array to search through + * @param valueToFind the value to find + * @return true if the array contains the object + */ + public static boolean contains(short[] array, short valueToFind) { + return indexOf(array, valueToFind) != INDEX_NOT_FOUND; + } + + // char IndexOf + //----------------------------------------------------------------------- + + /** + *

Finds the index of the given value in the array.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @return the index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + * @since 2.1 + */ + public static int indexOf(char[] array, char valueToFind) { + return indexOf(array, valueToFind, 0); + } + + /** + *

Finds the index of the given value in the array starting at the given index.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ *

+ *

A negative startIndex is treated as zero. A startIndex larger than the array + * length will return {@link #INDEX_NOT_FOUND} (-1).

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @param startIndex the index to start searching at + * @return the index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + * @since 2.1 + */ + public static int indexOf(char[] array, char valueToFind, int startIndex) { + if (array == null) { + return INDEX_NOT_FOUND; + } + if (startIndex < 0) { + startIndex = 0; + } + for (int i = startIndex; i < array.length; i++) { + if (valueToFind == array[i]) { + return i; + } + } + return INDEX_NOT_FOUND; + } + + /** + *

Finds the last index of the given value within the array.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ * + * @param array the array to travers backwords looking for the object, may be null + * @param valueToFind the object to find + * @return the last index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + * @since 2.1 + */ + public static int lastIndexOf(char[] array, char valueToFind) { + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE); + } + + /** + *

Finds the last index of the given value in the array starting at the given index.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ *

+ *

A negative startIndex will return {@link #INDEX_NOT_FOUND} (-1). A startIndex larger than the + * array length will search from the end of the array.

+ * + * @param array the array to traverse for looking for the object, may be null + * @param valueToFind the value to find + * @param startIndex the start index to travers backwards from + * @return the last index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + * @since 2.1 + */ + public static int lastIndexOf(char[] array, char valueToFind, int startIndex) { + if (array == null) { + return INDEX_NOT_FOUND; + } + if (startIndex < 0) { + return INDEX_NOT_FOUND; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + for (int i = startIndex; i >= 0; i--) { + if (valueToFind == array[i]) { + return i; + } + } + return INDEX_NOT_FOUND; + } + + /** + *

Checks if the value is in the given array.

+ *

+ *

The method returns false if a null array is passed in.

+ * + * @param array the array to search through + * @param valueToFind the value to find + * @return true if the array contains the object + * @since 2.1 + */ + public static boolean contains(char[] array, char valueToFind) { + return indexOf(array, valueToFind) != INDEX_NOT_FOUND; + } + + // byte IndexOf + //----------------------------------------------------------------------- + + /** + *

Finds the index of the given value in the array.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @return the index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int indexOf(byte[] array, byte valueToFind) { + return indexOf(array, valueToFind, 0); + } + + /** + *

Finds the index of the given value in the array starting at the given index.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ *

+ *

A negative startIndex is treated as zero. A startIndex larger than the array + * length will return {@link #INDEX_NOT_FOUND} (-1).

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @param startIndex the index to start searching at + * @return the index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int indexOf(byte[] array, byte valueToFind, int startIndex) { + if (array == null) { + return INDEX_NOT_FOUND; + } + if (startIndex < 0) { + startIndex = 0; + } + for (int i = startIndex; i < array.length; i++) { + if (valueToFind == array[i]) { + return i; + } + } + return INDEX_NOT_FOUND; + } + + /** + *

Finds the last index of the given value within the array.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ * + * @param array the array to travers backwords looking for the object, may be null + * @param valueToFind the object to find + * @return the last index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int lastIndexOf(byte[] array, byte valueToFind) { + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE); + } + + /** + *

Finds the last index of the given value in the array starting at the given index.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ *

+ *

A negative startIndex will return {@link #INDEX_NOT_FOUND} (-1). A startIndex larger than the + * array length will search from the end of the array.

+ * + * @param array the array to traverse for looking for the object, may be null + * @param valueToFind the value to find + * @param startIndex the start index to travers backwards from + * @return the last index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int lastIndexOf(byte[] array, byte valueToFind, int startIndex) { + if (array == null) { + return INDEX_NOT_FOUND; + } + if (startIndex < 0) { + return INDEX_NOT_FOUND; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + for (int i = startIndex; i >= 0; i--) { + if (valueToFind == array[i]) { + return i; + } + } + return INDEX_NOT_FOUND; + } + + /** + *

Checks if the value is in the given array.

+ *

+ *

The method returns false if a null array is passed in.

+ * + * @param array the array to search through + * @param valueToFind the value to find + * @return true if the array contains the object + */ + public static boolean contains(byte[] array, byte valueToFind) { + return indexOf(array, valueToFind) != INDEX_NOT_FOUND; + } + + // double IndexOf + //----------------------------------------------------------------------- + + /** + *

Finds the index of the given value in the array.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @return the index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int indexOf(double[] array, double valueToFind) { + return indexOf(array, valueToFind, 0); + } + + /** + *

Finds the index of the given value within a given tolerance in the array. + * This method will return the index of the first value which falls between the region + * defined by valueToFind - tolerance and valueToFind + tolerance.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @param tolerance tolerance of the search + * @return the index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int indexOf(double[] array, double valueToFind, double tolerance) { + return indexOf(array, valueToFind, 0, tolerance); + } + + /** + *

Finds the index of the given value in the array starting at the given index.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ *

+ *

A negative startIndex is treated as zero. A startIndex larger than the array + * length will return {@link #INDEX_NOT_FOUND} (-1).

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @param startIndex the index to start searching at + * @return the index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int indexOf(double[] array, double valueToFind, int startIndex) { + if (ArrayUtils.isEmpty(array)) { + return INDEX_NOT_FOUND; + } + if (startIndex < 0) { + startIndex = 0; + } + for (int i = startIndex; i < array.length; i++) { + if (valueToFind == array[i]) { + return i; + } + } + return INDEX_NOT_FOUND; + } + + /** + *

Finds the index of the given value in the array starting at the given index. + * This method will return the index of the first value which falls between the region + * defined by valueToFind - tolerance and valueToFind + tolerance.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ *

+ *

A negative startIndex is treated as zero. A startIndex larger than the array + * length will return {@link #INDEX_NOT_FOUND} (-1).

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @param startIndex the index to start searching at + * @param tolerance tolerance of the search + * @return the index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int indexOf(double[] array, double valueToFind, int startIndex, double tolerance) { + if (ArrayUtils.isEmpty(array)) { + return INDEX_NOT_FOUND; + } + if (startIndex < 0) { + startIndex = 0; + } + double min = valueToFind - tolerance; + double max = valueToFind + tolerance; + for (int i = startIndex; i < array.length; i++) { + if (array[i] >= min && array[i] <= max) { + return i; + } + } + return INDEX_NOT_FOUND; + } + + /** + *

Finds the last index of the given value within the array.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ * + * @param array the array to travers backwords looking for the object, may be null + * @param valueToFind the object to find + * @return the last index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int lastIndexOf(double[] array, double valueToFind) { + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE); + } + + /** + *

Finds the last index of the given value within a given tolerance in the array. + * This method will return the index of the last value which falls between the region + * defined by valueToFind - tolerance and valueToFind + tolerance.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @param tolerance tolerance of the search + * @return the index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int lastIndexOf(double[] array, double valueToFind, double tolerance) { + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE, tolerance); + } + + /** + *

Finds the last index of the given value in the array starting at the given index.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ *

+ *

A negative startIndex will return {@link #INDEX_NOT_FOUND} (-1). A startIndex larger than the + * array length will search from the end of the array.

+ * + * @param array the array to traverse for looking for the object, may be null + * @param valueToFind the value to find + * @param startIndex the start index to travers backwards from + * @return the last index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int lastIndexOf(double[] array, double valueToFind, int startIndex) { + if (ArrayUtils.isEmpty(array)) { + return INDEX_NOT_FOUND; + } + if (startIndex < 0) { + return INDEX_NOT_FOUND; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + for (int i = startIndex; i >= 0; i--) { + if (valueToFind == array[i]) { + return i; + } + } + return INDEX_NOT_FOUND; + } + + /** + *

Finds the last index of the given value in the array starting at the given index. + * This method will return the index of the last value which falls between the region + * defined by valueToFind - tolerance and valueToFind + tolerance.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ *

+ *

A negative startIndex will return {@link #INDEX_NOT_FOUND} (-1). A startIndex larger than the + * array length will search from the end of the array.

+ * + * @param array the array to traverse for looking for the object, may be null + * @param valueToFind the value to find + * @param startIndex the start index to travers backwards from + * @param tolerance search for value within plus/minus this amount + * @return the last index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int lastIndexOf(double[] array, double valueToFind, int startIndex, double tolerance) { + if (ArrayUtils.isEmpty(array)) { + return INDEX_NOT_FOUND; + } + if (startIndex < 0) { + return INDEX_NOT_FOUND; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + double min = valueToFind - tolerance; + double max = valueToFind + tolerance; + for (int i = startIndex; i >= 0; i--) { + if (array[i] >= min && array[i] <= max) { + return i; + } + } + return INDEX_NOT_FOUND; + } + + /** + *

Checks if the value is in the given array.

+ *

+ *

The method returns false if a null array is passed in.

+ * + * @param array the array to search through + * @param valueToFind the value to find + * @return true if the array contains the object + */ + public static boolean contains(double[] array, double valueToFind) { + return indexOf(array, valueToFind) != INDEX_NOT_FOUND; + } + + /** + *

Checks if a value falling within the given tolerance is in the + * given array. If the array contains a value within the inclusive range + * defined by (value - tolerance) to (value + tolerance).

+ *

+ *

The method returns false if a null array + * is passed in.

+ * + * @param array the array to search + * @param valueToFind the value to find + * @param tolerance the array contains the tolerance of the search + * @return true if value falling within tolerance is in array + */ + public static boolean contains(double[] array, double valueToFind, double tolerance) { + return indexOf(array, valueToFind, 0, tolerance) != INDEX_NOT_FOUND; + } + + // float IndexOf + //----------------------------------------------------------------------- + + /** + *

Finds the index of the given value in the array.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @return the index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int indexOf(float[] array, float valueToFind) { + return indexOf(array, valueToFind, 0); + } + + /** + *

Finds the index of the given value in the array starting at the given index.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ *

+ *

A negative startIndex is treated as zero. A startIndex larger than the array + * length will return {@link #INDEX_NOT_FOUND} (-1).

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @param startIndex the index to start searching at + * @return the index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int indexOf(float[] array, float valueToFind, int startIndex) { + if (ArrayUtils.isEmpty(array)) { + return INDEX_NOT_FOUND; + } + if (startIndex < 0) { + startIndex = 0; + } + for (int i = startIndex; i < array.length; i++) { + if (valueToFind == array[i]) { + return i; + } + } + return INDEX_NOT_FOUND; + } + + /** + *

Finds the last index of the given value within the array.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ * + * @param array the array to travers backwords looking for the object, may be null + * @param valueToFind the object to find + * @return the last index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int lastIndexOf(float[] array, float valueToFind) { + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE); + } + + /** + *

Finds the last index of the given value in the array starting at the given index.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ *

+ *

A negative startIndex will return {@link #INDEX_NOT_FOUND} (-1). A startIndex larger than the + * array length will search from the end of the array.

+ * + * @param array the array to traverse for looking for the object, may be null + * @param valueToFind the value to find + * @param startIndex the start index to travers backwards from + * @return the last index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int lastIndexOf(float[] array, float valueToFind, int startIndex) { + if (ArrayUtils.isEmpty(array)) { + return INDEX_NOT_FOUND; + } + if (startIndex < 0) { + return INDEX_NOT_FOUND; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + for (int i = startIndex; i >= 0; i--) { + if (valueToFind == array[i]) { + return i; + } + } + return INDEX_NOT_FOUND; + } + + /** + *

Checks if the value is in the given array.

+ *

+ *

The method returns false if a null array is passed in.

+ * + * @param array the array to search through + * @param valueToFind the value to find + * @return true if the array contains the object + */ + public static boolean contains(float[] array, float valueToFind) { + return indexOf(array, valueToFind) != INDEX_NOT_FOUND; + } + + // boolean IndexOf + //----------------------------------------------------------------------- + + /** + *

Finds the index of the given value in the array.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @return the index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int indexOf(boolean[] array, boolean valueToFind) { + return indexOf(array, valueToFind, 0); + } + + /** + *

Finds the index of the given value in the array starting at the given index.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ *

+ *

A negative startIndex is treated as zero. A startIndex larger than the array + * length will return {@link #INDEX_NOT_FOUND} (-1).

+ * + * @param array the array to search through for the object, may be null + * @param valueToFind the value to find + * @param startIndex the index to start searching at + * @return the index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null + * array input + */ + public static int indexOf(boolean[] array, boolean valueToFind, int startIndex) { + if (ArrayUtils.isEmpty(array)) { + return INDEX_NOT_FOUND; + } + if (startIndex < 0) { + startIndex = 0; + } + for (int i = startIndex; i < array.length; i++) { + if (valueToFind == array[i]) { + return i; + } + } + return INDEX_NOT_FOUND; + } + + /** + *

Finds the last index of the given value within the array.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) if + * null array input.

+ * + * @param array the array to travers backwords looking for the object, may be null + * @param valueToFind the object to find + * @return the last index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int lastIndexOf(boolean[] array, boolean valueToFind) { + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE); + } + + /** + *

Finds the last index of the given value in the array starting at the given index.

+ *

+ *

This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

+ *

+ *

A negative startIndex will return {@link #INDEX_NOT_FOUND} (-1). A startIndex larger than + * the array length will search from the end of the array.

+ * + * @param array the array to traverse for looking for the object, may be null + * @param valueToFind the value to find + * @param startIndex the start index to travers backwards from + * @return the last index of the value within the array, + * {@link #INDEX_NOT_FOUND} (-1) if not found or null array input + */ + public static int lastIndexOf(boolean[] array, boolean valueToFind, int startIndex) { + if (ArrayUtils.isEmpty(array)) { + return INDEX_NOT_FOUND; + } + if (startIndex < 0) { + return INDEX_NOT_FOUND; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + for (int i = startIndex; i >= 0; i--) { + if (valueToFind == array[i]) { + return i; + } + } + return INDEX_NOT_FOUND; + } + + /** + *

Checks if the value is in the given array.

+ *

+ *

The method returns false if a null array is passed in.

+ * + * @param array the array to search through + * @param valueToFind the value to find + * @return true if the array contains the object + */ + public static boolean contains(boolean[] array, boolean valueToFind) { + return indexOf(array, valueToFind) != INDEX_NOT_FOUND; + } + + // Primitive/Object array converters + // ---------------------------------------------------------------------- + + // Character array converters + // ---------------------------------------------------------------------- + + /** + *

Converts an array of object Characters to primitives.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a Character array, may be null + * @return a char array, null if null array input + * @throws NullPointerException if array content is null + */ + public static char[] toPrimitive(Character[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_CHAR_ARRAY; + } + final char[] result = new char[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = array[i].charValue(); + } + return result; + } + + /** + *

Converts an array of object Character to primitives handling null.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a Character array, may be null + * @param valueForNull the value to insert if null found + * @return a char array, null if null array input + */ + public static char[] toPrimitive(Character[] array, char valueForNull) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_CHAR_ARRAY; + } + final char[] result = new char[array.length]; + for (int i = 0; i < array.length; i++) { + Character b = array[i]; + result[i] = (b == null ? valueForNull : b.charValue()); + } + return result; + } + + /** + *

Converts an array of primitive chars to objects.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a char array + * @return a Character array, null if null array input + */ + public static Character[] toObject(char[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_CHARACTER_OBJECT_ARRAY; + } + final Character[] result = new Character[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = new Character(array[i]); + } + return result; + } + + // Long array converters + // ---------------------------------------------------------------------- + + /** + *

Converts an array of object Longs to primitives.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a Long array, may be null + * @return a long array, null if null array input + * @throws NullPointerException if array content is null + */ + public static long[] toPrimitive(Long[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_LONG_ARRAY; + } + final long[] result = new long[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = array[i].longValue(); + } + return result; + } + + /** + *

Converts an array of object Long to primitives handling null.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a Long array, may be null + * @param valueForNull the value to insert if null found + * @return a long array, null if null array input + */ + public static long[] toPrimitive(Long[] array, long valueForNull) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_LONG_ARRAY; + } + final long[] result = new long[array.length]; + for (int i = 0; i < array.length; i++) { + Long b = array[i]; + result[i] = (b == null ? valueForNull : b.longValue()); + } + return result; + } + + /** + *

Converts an array of primitive longs to objects.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a long array + * @return a Long array, null if null array input + */ + public static Long[] toObject(long[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_LONG_OBJECT_ARRAY; + } + final Long[] result = new Long[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = new Long(array[i]); + } + return result; + } + + // Int array converters + // ---------------------------------------------------------------------- + + /** + *

Converts an array of object Integers to primitives.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a Integer array, may be null + * @return an int array, null if null array input + * @throws NullPointerException if array content is null + */ + public static int[] toPrimitive(Integer[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_INT_ARRAY; + } + final int[] result = new int[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = array[i].intValue(); + } + return result; + } + + /** + *

Converts an array of object Integer to primitives handling null.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a Integer array, may be null + * @param valueForNull the value to insert if null found + * @return an int array, null if null array input + */ + public static int[] toPrimitive(Integer[] array, int valueForNull) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_INT_ARRAY; + } + final int[] result = new int[array.length]; + for (int i = 0; i < array.length; i++) { + Integer b = array[i]; + result[i] = (b == null ? valueForNull : b.intValue()); + } + return result; + } + + /** + *

Converts an array of primitive ints to objects.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array an int array + * @return an Integer array, null if null array input + */ + public static Integer[] toObject(int[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_INTEGER_OBJECT_ARRAY; + } + final Integer[] result = new Integer[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = new Integer(array[i]); + } + return result; + } + + // Short array converters + // ---------------------------------------------------------------------- + + /** + *

Converts an array of object Shorts to primitives.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a Short array, may be null + * @return a byte array, null if null array input + * @throws NullPointerException if array content is null + */ + public static short[] toPrimitive(Short[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_SHORT_ARRAY; + } + final short[] result = new short[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = array[i].shortValue(); + } + return result; + } + + /** + *

Converts an array of object Short to primitives handling null.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a Short array, may be null + * @param valueForNull the value to insert if null found + * @return a byte array, null if null array input + */ + public static short[] toPrimitive(Short[] array, short valueForNull) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_SHORT_ARRAY; + } + final short[] result = new short[array.length]; + for (int i = 0; i < array.length; i++) { + Short b = array[i]; + result[i] = (b == null ? valueForNull : b.shortValue()); + } + return result; + } + + /** + *

Converts an array of primitive shorts to objects.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a short array + * @return a Short array, null if null array input + */ + public static Short[] toObject(short[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_SHORT_OBJECT_ARRAY; + } + final Short[] result = new Short[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = new Short(array[i]); + } + return result; + } + + // Byte array converters + // ---------------------------------------------------------------------- + + /** + *

Converts an array of object Bytes to primitives.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a Byte array, may be null + * @return a byte array, null if null array input + * @throws NullPointerException if array content is null + */ + public static byte[] toPrimitive(Byte[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_BYTE_ARRAY; + } + final byte[] result = new byte[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = array[i].byteValue(); + } + return result; + } + + /** + *

Converts an array of object Bytes to primitives handling null.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a Byte array, may be null + * @param valueForNull the value to insert if null found + * @return a byte array, null if null array input + */ + public static byte[] toPrimitive(Byte[] array, byte valueForNull) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_BYTE_ARRAY; + } + final byte[] result = new byte[array.length]; + for (int i = 0; i < array.length; i++) { + Byte b = array[i]; + result[i] = (b == null ? valueForNull : b.byteValue()); + } + return result; + } + + /** + *

Converts an array of primitive bytes to objects.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a byte array + * @return a Byte array, null if null array input + */ + public static Byte[] toObject(byte[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_BYTE_OBJECT_ARRAY; + } + final Byte[] result = new Byte[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = new Byte(array[i]); + } + return result; + } + + // Double array converters + // ---------------------------------------------------------------------- + + /** + *

Converts an array of object Doubles to primitives.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a Double array, may be null + * @return a double array, null if null array input + * @throws NullPointerException if array content is null + */ + public static double[] toPrimitive(Double[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_DOUBLE_ARRAY; + } + final double[] result = new double[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = array[i].doubleValue(); + } + return result; + } + + /** + *

Converts an array of object Doubles to primitives handling null.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a Double array, may be null + * @param valueForNull the value to insert if null found + * @return a double array, null if null array input + */ + public static double[] toPrimitive(Double[] array, double valueForNull) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_DOUBLE_ARRAY; + } + final double[] result = new double[array.length]; + for (int i = 0; i < array.length; i++) { + Double b = array[i]; + result[i] = (b == null ? valueForNull : b.doubleValue()); + } + return result; + } + + /** + *

Converts an array of primitive doubles to objects.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a double array + * @return a Double array, null if null array input + */ + public static Double[] toObject(double[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_DOUBLE_OBJECT_ARRAY; + } + final Double[] result = new Double[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = new Double(array[i]); + } + return result; + } + + // Float array converters + // ---------------------------------------------------------------------- + + /** + *

Converts an array of object Floats to primitives.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a Float array, may be null + * @return a float array, null if null array input + * @throws NullPointerException if array content is null + */ + public static float[] toPrimitive(Float[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_FLOAT_ARRAY; + } + final float[] result = new float[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = array[i].floatValue(); + } + return result; + } + + /** + *

Converts an array of object Floats to primitives handling null.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a Float array, may be null + * @param valueForNull the value to insert if null found + * @return a float array, null if null array input + */ + public static float[] toPrimitive(Float[] array, float valueForNull) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_FLOAT_ARRAY; + } + final float[] result = new float[array.length]; + for (int i = 0; i < array.length; i++) { + Float b = array[i]; + result[i] = (b == null ? valueForNull : b.floatValue()); + } + return result; + } + + /** + *

Converts an array of primitive floats to objects.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a float array + * @return a Float array, null if null array input + */ + public static Float[] toObject(float[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_FLOAT_OBJECT_ARRAY; + } + final Float[] result = new Float[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = new Float(array[i]); + } + return result; + } + + // Boolean array converters + // ---------------------------------------------------------------------- + + /** + *

Converts an array of object Booleans to primitives.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a Boolean array, may be null + * @return a boolean array, null if null array input + * @throws NullPointerException if array content is null + */ + public static boolean[] toPrimitive(Boolean[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_BOOLEAN_ARRAY; + } + final boolean[] result = new boolean[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = array[i].booleanValue(); + } + return result; + } + + /** + *

Converts an array of object Booleans to primitives handling null.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a Boolean array, may be null + * @param valueForNull the value to insert if null found + * @return a boolean array, null if null array input + */ + public static boolean[] toPrimitive(Boolean[] array, boolean valueForNull) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_BOOLEAN_ARRAY; + } + final boolean[] result = new boolean[array.length]; + for (int i = 0; i < array.length; i++) { + Boolean b = array[i]; + result[i] = (b == null ? valueForNull : b.booleanValue()); + } + return result; + } + + /** + *

Converts an array of primitive booleans to objects.

+ *

+ *

This method returns null for a null input array.

+ * + * @param array a boolean array + * @return a Boolean array, null if null array input + */ + public static Boolean[] toObject(boolean[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_BOOLEAN_OBJECT_ARRAY; + } + final Boolean[] result = new Boolean[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = (array[i] ? Boolean.TRUE : Boolean.FALSE); + } + return result; + } + + // ---------------------------------------------------------------------- + + /** + *

Checks if an array of Objects is empty or null.

+ * + * @param array the array to test + * @return true if the array is empty or null + * @since 2.1 + */ + public static boolean isEmpty(Object[] array) { + if (array == null || array.length == 0) { + return true; + } + return false; + } + + /** + *

Checks if an array of Objects is not empty or not null.

+ * + * @param array the array to test + * @return true if the array is not empty or not null + * @since 2.1 + */ + public static boolean isNotEmpty(Object[] array) { + return !isEmpty(array); + } + + public static boolean isEmpty(Object[][] array) { + if (array == null) { + return true; + } + + boolean empty = true; + for (int i = 0, len = array.length; i < len; i++) { + if (!isEmpty(array[i])) { + empty = false; + break; + } + } + return empty; + } + + /** + *

Checks if an array of primitive longs is empty or null.

+ * + * @param array the array to test + * @return true if the array is empty or null + * @since 2.1 + */ + public static boolean isEmpty(long[] array) { + if (array == null || array.length == 0) { + return true; + } + return false; + } + + /** + *

Checks if an array of primitive ints is empty or null.

+ * + * @param array the array to test + * @return true if the array is empty or null + * @since 2.1 + */ + public static boolean isEmpty(int[] array) { + if (array == null || array.length == 0) { + return true; + } + return false; + } + + /** + *

Checks if an array of primitive shorts is empty or null.

+ * + * @param array the array to test + * @return true if the array is empty or null + * @since 2.1 + */ + public static boolean isEmpty(short[] array) { + if (array == null || array.length == 0) { + return true; + } + return false; + } + + /** + *

Checks if an array of primitive chars is empty or null.

+ * + * @param array the array to test + * @return true if the array is empty or null + * @since 2.1 + */ + public static boolean isEmpty(char[] array) { + if (array == null || array.length == 0) { + return true; + } + return false; + } + + /** + *

Checks if an array of primitive bytes is empty or null.

+ * + * @param array the array to test + * @return true if the array is empty or null + * @since 2.1 + */ + public static boolean isEmpty(byte[] array) { + if (array == null || array.length == 0) { + return true; + } + return false; + } + + /** + *

Checks if an array of primitive doubles is empty or null.

+ * + * @param array the array to test + * @return true if the array is empty or null + * @since 2.1 + */ + public static boolean isEmpty(double[] array) { + if (array == null || array.length == 0) { + return true; + } + return false; + } + + /** + *

Checks if an array of primitive floats is empty or null.

+ * + * @param array the array to test + * @return true if the array is empty or null + * @since 2.1 + */ + public static boolean isEmpty(float[] array) { + if (array == null || array.length == 0) { + return true; + } + return false; + } + + /** + *

Checks if an array of primitive booleans is empty or null.

+ * + * @param array the array to test + * @return true if the array is empty or null + * @since 2.1 + */ + public static boolean isEmpty(boolean[] array) { + if (array == null || array.length == 0) { + return true; + } + return false; + } + + /** + *

Adds all the elements of the given arrays into a new array.

+ *

The new array contains all of the element of array1 followed + * by all of the elements array2. When an array is returned, it is always + * a new array.

+ *

+ *

+     * helper.ArrayUtils.addAll(null, null)     = null
+     * helper.ArrayUtils.addAll(array1, null)   = cloned copy of array1
+     * helper.ArrayUtils.addAll(null, array2)   = cloned copy of array2
+     * helper.ArrayUtils.addAll([], [])         = []
+     * helper.ArrayUtils.addAll([null], [null]) = [null, null]
+     * helper.ArrayUtils.addAll(["a", "b", "c"], ["1", "2", "3"]) = ["a", "b", "c", "1", "2", "3"]
+     * 
+ * + * @param array1 the first array whose elements are added to the new array, may be null + * @param array2 the second array whose elements are added to the new array, may be null + * @return The new array, null if null array inputs. + * The type of the new array is the type of the first array. + * @since 2.1 + */ + public static T[] addAll(T[] array1, T[] array2) { + if (array1 == null) { + return clone(array2); + } else if (array2 == null) { + return clone(array1); + } + + T[] joinedArray = (T[]) Array.newInstance(array1.getClass().getComponentType(), + array1.length + array2.length); + System.arraycopy(array1, 0, joinedArray, 0, array1.length); + System.arraycopy(array2, 0, joinedArray, array1.length, array2.length); + return joinedArray; + } + + /** + *

Adds all the elements of the given arrays into a new array.

+ *

The new array contains all of the element of array1 followed + * by all of the elements array2. When an array is returned, it is always + * a new array.

+ *

+ *

+     * helper.ArrayUtils.addAll(array1, null)   = cloned copy of array1
+     * helper.ArrayUtils.addAll(null, array2)   = cloned copy of array2
+     * helper.ArrayUtils.addAll([], [])         = []
+     * 
+ * + * @param array1 the first array whose elements are added to the new array. + * @param array2 the second array whose elements are added to the new array. + * @return The new boolean[] array. + * @since 2.1 + */ + public static boolean[] addAll(boolean[] array1, boolean[] array2) { + if (array1 == null) { + return clone(array2); + } else if (array2 == null) { + return clone(array1); + } + boolean[] joinedArray = new boolean[array1.length + array2.length]; + System.arraycopy(array1, 0, joinedArray, 0, array1.length); + System.arraycopy(array2, 0, joinedArray, array1.length, array2.length); + return joinedArray; + } + + /** + *

Adds all the elements of the given arrays into a new array.

+ *

The new array contains all of the element of array1 followed + * by all of the elements array2. When an array is returned, it is always + * a new array.

+ *

+ *

+     * helper.ArrayUtils.addAll(array1, null)   = cloned copy of array1
+     * helper.ArrayUtils.addAll(null, array2)   = cloned copy of array2
+     * helper.ArrayUtils.addAll([], [])         = []
+     * 
+ * + * @param array1 the first array whose elements are added to the new array. + * @param array2 the second array whose elements are added to the new array. + * @return The new char[] array. + * @since 2.1 + */ + public static char[] addAll(char[] array1, char[] array2) { + if (array1 == null) { + return clone(array2); + } else if (array2 == null) { + return clone(array1); + } + char[] joinedArray = new char[array1.length + array2.length]; + System.arraycopy(array1, 0, joinedArray, 0, array1.length); + System.arraycopy(array2, 0, joinedArray, array1.length, array2.length); + return joinedArray; + } + + /** + *

Adds all the elements of the given arrays into a new array.

+ *

The new array contains all of the element of array1 followed + * by all of the elements array2. When an array is returned, it is always + * a new array.

+ *

+ *

+     * helper.ArrayUtils.addAll(array1, null)   = cloned copy of array1
+     * helper.ArrayUtils.addAll(null, array2)   = cloned copy of array2
+     * helper.ArrayUtils.addAll([], [])         = []
+     * 
+ * + * @param array1 the first array whose elements are added to the new array. + * @param array2 the second array whose elements are added to the new array. + * @return The new byte[] array. + * @since 2.1 + */ + public static byte[] addAll(byte[] array1, byte[] array2) { + if (array1 == null) { + return clone(array2); + } else if (array2 == null) { + return clone(array1); + } + byte[] joinedArray = new byte[array1.length + array2.length]; + System.arraycopy(array1, 0, joinedArray, 0, array1.length); + System.arraycopy(array2, 0, joinedArray, array1.length, array2.length); + return joinedArray; + } + + /** + *

Adds all the elements of the given arrays into a new array.

+ *

The new array contains all of the element of array1 followed + * by all of the elements array2. When an array is returned, it is always + * a new array.

+ *

+ *

+     * helper.ArrayUtils.addAll(array1, null)   = cloned copy of array1
+     * helper.ArrayUtils.addAll(null, array2)   = cloned copy of array2
+     * helper.ArrayUtils.addAll([], [])         = []
+     * 
+ * + * @param array1 the first array whose elements are added to the new array. + * @param array2 the second array whose elements are added to the new array. + * @return The new short[] array. + * @since 2.1 + */ + public static short[] addAll(short[] array1, short[] array2) { + if (array1 == null) { + return clone(array2); + } else if (array2 == null) { + return clone(array1); + } + short[] joinedArray = new short[array1.length + array2.length]; + System.arraycopy(array1, 0, joinedArray, 0, array1.length); + System.arraycopy(array2, 0, joinedArray, array1.length, array2.length); + return joinedArray; + } + + /** + *

Adds all the elements of the given arrays into a new array.

+ *

The new array contains all of the element of array1 followed + * by all of the elements array2. When an array is returned, it is always + * a new array.

+ *

+ *

+     * helper.ArrayUtils.addAll(array1, null)   = cloned copy of array1
+     * helper.ArrayUtils.addAll(null, array2)   = cloned copy of array2
+     * helper.ArrayUtils.addAll([], [])         = []
+     * 
+ * + * @param array1 the first array whose elements are added to the new array. + * @param array2 the second array whose elements are added to the new array. + * @return The new int[] array. + * @since 2.1 + */ + public static int[] addAll(int[] array1, int[] array2) { + if (array1 == null) { + return clone(array2); + } else if (array2 == null) { + return clone(array1); + } + int[] joinedArray = new int[array1.length + array2.length]; + System.arraycopy(array1, 0, joinedArray, 0, array1.length); + System.arraycopy(array2, 0, joinedArray, array1.length, array2.length); + return joinedArray; + } + + /** + *

Adds all the elements of the given arrays into a new array.

+ *

The new array contains all of the element of array1 followed + * by all of the elements array2. When an array is returned, it is always + * a new array.

+ *

+ *

+     * helper.ArrayUtils.addAll(array1, null)   = cloned copy of array1
+     * helper.ArrayUtils.addAll(null, array2)   = cloned copy of array2
+     * helper.ArrayUtils.addAll([], [])         = []
+     * 
+ * + * @param array1 the first array whose elements are added to the new array. + * @param array2 the second array whose elements are added to the new array. + * @return The new long[] array. + * @since 2.1 + */ + public static long[] addAll(long[] array1, long[] array2) { + if (array1 == null) { + return clone(array2); + } else if (array2 == null) { + return clone(array1); + } + long[] joinedArray = new long[array1.length + array2.length]; + System.arraycopy(array1, 0, joinedArray, 0, array1.length); + System.arraycopy(array2, 0, joinedArray, array1.length, array2.length); + return joinedArray; + } + + /** + *

Adds all the elements of the given arrays into a new array.

+ *

The new array contains all of the element of array1 followed + * by all of the elements array2. When an array is returned, it is always + * a new array.

+ *

+ *

+     * helper.ArrayUtils.addAll(array1, null)   = cloned copy of array1
+     * helper.ArrayUtils.addAll(null, array2)   = cloned copy of array2
+     * helper.ArrayUtils.addAll([], [])         = []
+     * 
+ * + * @param array1 the first array whose elements are added to the new array. + * @param array2 the second array whose elements are added to the new array. + * @return The new float[] array. + * @since 2.1 + */ + public static float[] addAll(float[] array1, float[] array2) { + if (array1 == null) { + return clone(array2); + } else if (array2 == null) { + return clone(array1); + } + float[] joinedArray = new float[array1.length + array2.length]; + System.arraycopy(array1, 0, joinedArray, 0, array1.length); + System.arraycopy(array2, 0, joinedArray, array1.length, array2.length); + return joinedArray; + } + + /** + *

Adds all the elements of the given arrays into a new array.

+ *

The new array contains all of the element of array1 followed + * by all of the elements array2. When an array is returned, it is always + * a new array.

+ *

+ *

+     * helper.ArrayUtils.addAll(array1, null)   = cloned copy of array1
+     * helper.ArrayUtils.addAll(null, array2)   = cloned copy of array2
+     * helper.ArrayUtils.addAll([], [])         = []
+     * 
+ * + * @param array1 the first array whose elements are added to the new array. + * @param array2 the second array whose elements are added to the new array. + * @return The new double[] array. + * @since 2.1 + */ + public static double[] addAll(double[] array1, double[] array2) { + if (array1 == null) { + return clone(array2); + } else if (array2 == null) { + return clone(array1); + } + double[] joinedArray = new double[array1.length + array2.length]; + System.arraycopy(array1, 0, joinedArray, 0, array1.length); + System.arraycopy(array2, 0, joinedArray, array1.length, array2.length); + return joinedArray; + } + + + /** + *

Copies the given array and adds the given element at the end of the new array.

+ *

+ *

The new array contains the same elements of the input + * array plus the given element in the last position. The component type of + * the new array is the same as that of the input array.

+ *

+ *

If the input array is null, a new one element array is returned + * whose component type is the same as the element.

+ *

+ *

+     * helper.ArrayUtils.add(null, null)      = [null]
+     * helper.ArrayUtils.add(null, "a")       = ["a"]
+     * helper.ArrayUtils.add(["a"], null)     = ["a", null]
+     * helper.ArrayUtils.add(["a"], "b")      = ["a", "b"]
+     * helper.ArrayUtils.add(["a", "b"], "c") = ["a", "b", "c"]
+     * 
+ * + * @param array the array to "add" the element to, may be null + * @param element the object to add + * @return A new array containing the existing elements plus the new element + * @since 2.1 + */ + public static T[] add(T[] array, T element) { + Class type = array != null ? array.getClass() : (element != null ? element.getClass() : Object.class); + T[] newArray = (T[]) copyArrayGrow1(array, type); + newArray[newArray.length - 1] = element; + return newArray; + } + + /** + *

Copies the given array and adds the given element at the end of the new array.

+ *

+ *

The new array contains the same elements of the input + * array plus the given element in the last position. The component type of + * the new array is the same as that of the input array.

+ *

+ *

If the input array is null, a new one element array is returned + * whose component type is the same as the element.

+ *

+ *

+     * helper.ArrayUtils.add(null, true)          = [true]
+     * helper.ArrayUtils.add([true], false)       = [true, false]
+     * helper.ArrayUtils.add([true, false], true) = [true, false, true]
+     * 
+ * + * @param array the array to copy and add the element to, may be null + * @param element the object to add at the last index of the new array + * @return A new array containing the existing elements plus the new element + * @since 2.1 + */ + public static boolean[] add(boolean[] array, boolean element) { + boolean[] newArray = (boolean[]) copyArrayGrow1(array, Boolean.TYPE); + newArray[newArray.length - 1] = element; + return newArray; + } + + /** + *

Copies the given array and adds the given element at the end of the new array.

+ *

+ *

The new array contains the same elements of the input + * array plus the given element in the last position. The component type of + * the new array is the same as that of the input array.

+ *

+ *

If the input array is null, a new one element array is returned + * whose component type is the same as the element.

+ *

+ *

+     * helper.ArrayUtils.add(null, 0)   = [0]
+     * helper.ArrayUtils.add([1], 0)    = [1, 0]
+     * helper.ArrayUtils.add([1, 0], 1) = [1, 0, 1]
+     * 
+ * + * @param array the array to copy and add the element to, may be null + * @param element the object to add at the last index of the new array + * @return A new array containing the existing elements plus the new element + * @since 2.1 + */ + public static byte[] add(byte[] array, byte element) { + byte[] newArray = (byte[]) copyArrayGrow1(array, Byte.TYPE); + newArray[newArray.length - 1] = element; + return newArray; + } + + /** + *

Copies the given array and adds the given element at the end of the new array.

+ *

+ *

The new array contains the same elements of the input + * array plus the given element in the last position. The component type of + * the new array is the same as that of the input array.

+ *

+ *

If the input array is null, a new one element array is returned + * whose component type is the same as the element.

+ *

+ *

+     * helper.ArrayUtils.add(null, '0')       = ['0']
+     * helper.ArrayUtils.add(['1'], '0')      = ['1', '0']
+     * helper.ArrayUtils.add(['1', '0'], '1') = ['1', '0', '1']
+     * 
+ * + * @param array the array to copy and add the element to, may be null + * @param element the object to add at the last index of the new array + * @return A new array containing the existing elements plus the new element + * @since 2.1 + */ + public static char[] add(char[] array, char element) { + char[] newArray = (char[]) copyArrayGrow1(array, Character.TYPE); + newArray[newArray.length - 1] = element; + return newArray; + } + + /** + *

Copies the given array and adds the given element at the end of the new array.

+ *

+ *

The new array contains the same elements of the input + * array plus the given element in the last position. The component type of + * the new array is the same as that of the input array.

+ *

+ *

If the input array is null, a new one element array is returned + * whose component type is the same as the element.

+ *

+ *

+     * helper.ArrayUtils.add(null, 0)   = [0]
+     * helper.ArrayUtils.add([1], 0)    = [1, 0]
+     * helper.ArrayUtils.add([1, 0], 1) = [1, 0, 1]
+     * 
+ * + * @param array the array to copy and add the element to, may be null + * @param element the object to add at the last index of the new array + * @return A new array containing the existing elements plus the new element + * @since 2.1 + */ + public static double[] add(double[] array, double element) { + double[] newArray = (double[]) copyArrayGrow1(array, Double.TYPE); + newArray[newArray.length - 1] = element; + return newArray; + } + + /** + *

Copies the given array and adds the given element at the end of the new array.

+ *

+ *

The new array contains the same elements of the input + * array plus the given element in the last position. The component type of + * the new array is the same as that of the input array.

+ *

+ *

If the input array is null, a new one element array is returned + * whose component type is the same as the element.

+ *

+ *

+     * helper.ArrayUtils.add(null, 0)   = [0]
+     * helper.ArrayUtils.add([1], 0)    = [1, 0]
+     * helper.ArrayUtils.add([1, 0], 1) = [1, 0, 1]
+     * 
+ * + * @param array the array to copy and add the element to, may be null + * @param element the object to add at the last index of the new array + * @return A new array containing the existing elements plus the new element + * @since 2.1 + */ + public static float[] add(float[] array, float element) { + float[] newArray = (float[]) copyArrayGrow1(array, Float.TYPE); + newArray[newArray.length - 1] = element; + return newArray; + } + + /** + *

Copies the given array and adds the given element at the end of the new array.

+ *

+ *

The new array contains the same elements of the input + * array plus the given element in the last position. The component type of + * the new array is the same as that of the input array.

+ *

+ *

If the input array is null, a new one element array is returned + * whose component type is the same as the element.

+ *

+ *

+     * helper.ArrayUtils.add(null, 0)   = [0]
+     * helper.ArrayUtils.add([1], 0)    = [1, 0]
+     * helper.ArrayUtils.add([1, 0], 1) = [1, 0, 1]
+     * 
+ * + * @param array the array to copy and add the element to, may be null + * @param element the object to add at the last index of the new array + * @return A new array containing the existing elements plus the new element + * @since 2.1 + */ + public static int[] add(int[] array, int element) { + int[] newArray = (int[]) copyArrayGrow1(array, Integer.TYPE); + newArray[newArray.length - 1] = element; + return newArray; + } + + /** + *

Copies the given array and adds the given element at the end of the new array.

+ *

+ *

The new array contains the same elements of the input + * array plus the given element in the last position. The component type of + * the new array is the same as that of the input array.

+ *

+ *

If the input array is null, a new one element array is returned + * whose component type is the same as the element.

+ *

+ *

+     * helper.ArrayUtils.add(null, 0)   = [0]
+     * helper.ArrayUtils.add([1], 0)    = [1, 0]
+     * helper.ArrayUtils.add([1, 0], 1) = [1, 0, 1]
+     * 
+ * + * @param array the array to copy and add the element to, may be null + * @param element the object to add at the last index of the new array + * @return A new array containing the existing elements plus the new element + * @since 2.1 + */ + public static long[] add(long[] array, long element) { + long[] newArray = (long[]) copyArrayGrow1(array, Long.TYPE); + newArray[newArray.length - 1] = element; + return newArray; + } + + /** + *

Copies the given array and adds the given element at the end of the new array.

+ *

+ *

The new array contains the same elements of the input + * array plus the given element in the last position. The component type of + * the new array is the same as that of the input array.

+ *

+ *

If the input array is null, a new one element array is returned + * whose component type is the same as the element.

+ *

+ *

+     * helper.ArrayUtils.add(null, 0)   = [0]
+     * helper.ArrayUtils.add([1], 0)    = [1, 0]
+     * helper.ArrayUtils.add([1, 0], 1) = [1, 0, 1]
+     * 
+ * + * @param array the array to copy and add the element to, may be null + * @param element the object to add at the last index of the new array + * @return A new array containing the existing elements plus the new element + * @since 2.1 + */ + public static short[] add(short[] array, short element) { + short[] newArray = (short[]) copyArrayGrow1(array, Short.TYPE); + newArray[newArray.length - 1] = element; + return newArray; + } + + /** + * Returns a copy of the given array of size 1 greater than the argument. + * The last value of the array is left to the default value. + * + * @param array The array to copy, must not be null. + * @param newArrayComponentType If array is null, create a + * size 1 array of this type. + * @return A new copy of the array of size 1 greater than the input. + */ + private static Object copyArrayGrow1(Object array, Class newArrayComponentType) { + if (array != null) { + int arrayLength = Array.getLength(array); + Object newArray = Array.newInstance(array.getClass().getComponentType(), arrayLength + 1); + System.arraycopy(array, 0, newArray, 0, arrayLength); + return newArray; + } + return Array.newInstance(newArrayComponentType, 1); + } + + /** + *

Inserts the specified element at the specified position in the array. + * Shifts the element currently at that position (if any) and any subsequent + * elements to the right (adds one to their indices).

+ *

+ *

This method returns a new array with the same elements of the input + * array plus the given element on the specified position. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

If the input array is null, a new one element array is returned + * whose component type is the same as the element.

+ *

+ *

+     * helper.ArrayUtils.add(null, 0, null)      = [null]
+     * helper.ArrayUtils.add(null, 0, "a")       = ["a"]
+     * helper.ArrayUtils.add(["a"], 1, null)     = ["a", null]
+     * helper.ArrayUtils.add(["a"], 1, "b")      = ["a", "b"]
+     * helper.ArrayUtils.add(["a", "b"], 3, "c") = ["a", "b", "c"]
+     * 
+ * + * @param array the array to add the element to, may be null + * @param index the position of the new object + * @param element the object to add + * @return A new array containing the existing elements and the new element + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index > array.length). + */ + public static Object[] add(Object[] array, int index, Object element) { + Class clss = null; + if (array != null) { + clss = array.getClass().getComponentType(); + } else if (element != null) { + clss = element.getClass(); + } else { + return new Object[]{null}; + } + return (Object[]) add(array, index, element, clss); + } + + /** + *

Inserts the specified element at the specified position in the array. + * Shifts the element currently at that position (if any) and any subsequent + * elements to the right (adds one to their indices).

+ *

+ *

This method returns a new array with the same elements of the input + * array plus the given element on the specified position. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

If the input array is null, a new one element array is returned + * whose component type is the same as the element.

+ *

+ *

+     * helper.ArrayUtils.add(null, 0, true)          = [true]
+     * helper.ArrayUtils.add([true], 0, false)       = [false, true]
+     * helper.ArrayUtils.add([false], 1, true)       = [false, true]
+     * helper.ArrayUtils.add([true, false], 1, true) = [true, true, false]
+     * 
+ * + * @param array the array to add the element to, may be null + * @param index the position of the new object + * @param element the object to add + * @return A new array containing the existing elements and the new element + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index > array.length). + */ + public static boolean[] add(boolean[] array, int index, boolean element) { + return (boolean[]) add(array, index, element, Boolean.TYPE); + } + + /** + *

Inserts the specified element at the specified position in the array. + * Shifts the element currently at that position (if any) and any subsequent + * elements to the right (adds one to their indices).

+ *

+ *

This method returns a new array with the same elements of the input + * array plus the given element on the specified position. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

If the input array is null, a new one element array is returned + * whose component type is the same as the element.

+ *

+ *

+     * helper.ArrayUtils.add(null, 0, 'a')            = ['a']
+     * helper.ArrayUtils.add(['a'], 0, 'b')           = ['b', 'a']
+     * helper.ArrayUtils.add(['a', 'b'], 0, 'c')      = ['c', 'a', 'b']
+     * helper.ArrayUtils.add(['a', 'b'], 1, 'k')      = ['a', 'k', 'b']
+     * helper.ArrayUtils.add(['a', 'b', 'c'], 1, 't') = ['a', 't', 'b', 'c']
+     * 
+ * + * @param array the array to add the element to, may be null + * @param index the position of the new object + * @param element the object to add + * @return A new array containing the existing elements and the new element + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index > array.length). + */ + public static char[] add(char[] array, int index, char element) { + return (char[]) add(array, index, new Character(element), Character.TYPE); + } + + /** + *

Inserts the specified element at the specified position in the array. + * Shifts the element currently at that position (if any) and any subsequent + * elements to the right (adds one to their indices).

+ *

+ *

This method returns a new array with the same elements of the input + * array plus the given element on the specified position. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

If the input array is null, a new one element array is returned + * whose component type is the same as the element.

+ *

+ *

+     * helper.ArrayUtils.add([1], 0, 2)         = [2, 1]
+     * helper.ArrayUtils.add([2, 6], 2, 3)      = [2, 6, 3]
+     * helper.ArrayUtils.add([2, 6], 0, 1)      = [1, 2, 6]
+     * helper.ArrayUtils.add([2, 6, 3], 2, 1)   = [2, 6, 1, 3]
+     * 
+ * + * @param array the array to add the element to, may be null + * @param index the position of the new object + * @param element the object to add + * @return A new array containing the existing elements and the new element + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index > array.length). + */ + public static byte[] add(byte[] array, int index, byte element) { + return (byte[]) add(array, index, new Byte(element), Byte.TYPE); + } + + /** + *

Inserts the specified element at the specified position in the array. + * Shifts the element currently at that position (if any) and any subsequent + * elements to the right (adds one to their indices).

+ *

+ *

This method returns a new array with the same elements of the input + * array plus the given element on the specified position. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

If the input array is null, a new one element array is returned + * whose component type is the same as the element.

+ *

+ *

+     * helper.ArrayUtils.add([1], 0, 2)         = [2, 1]
+     * helper.ArrayUtils.add([2, 6], 2, 10)     = [2, 6, 10]
+     * helper.ArrayUtils.add([2, 6], 0, -4)     = [-4, 2, 6]
+     * helper.ArrayUtils.add([2, 6, 3], 2, 1)   = [2, 6, 1, 3]
+     * 
+ * + * @param array the array to add the element to, may be null + * @param index the position of the new object + * @param element the object to add + * @return A new array containing the existing elements and the new element + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index > array.length). + */ + public static short[] add(short[] array, int index, short element) { + return (short[]) add(array, index, new Short(element), Short.TYPE); + } + + /** + *

Inserts the specified element at the specified position in the array. + * Shifts the element currently at that position (if any) and any subsequent + * elements to the right (adds one to their indices).

+ *

+ *

This method returns a new array with the same elements of the input + * array plus the given element on the specified position. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

If the input array is null, a new one element array is returned + * whose component type is the same as the element.

+ *

+ *

+     * helper.ArrayUtils.add([1], 0, 2)         = [2, 1]
+     * helper.ArrayUtils.add([2, 6], 2, 10)     = [2, 6, 10]
+     * helper.ArrayUtils.add([2, 6], 0, -4)     = [-4, 2, 6]
+     * helper.ArrayUtils.add([2, 6, 3], 2, 1)   = [2, 6, 1, 3]
+     * 
+ * + * @param array the array to add the element to, may be null + * @param index the position of the new object + * @param element the object to add + * @return A new array containing the existing elements and the new element + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index > array.length). + */ + public static int[] add(int[] array, int index, int element) { + return (int[]) add(array, index, new Integer(element), Integer.TYPE); + } + + /** + *

Inserts the specified element at the specified position in the array. + * Shifts the element currently at that position (if any) and any subsequent + * elements to the right (adds one to their indices).

+ *

+ *

This method returns a new array with the same elements of the input + * array plus the given element on the specified position. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

If the input array is null, a new one element array is returned + * whose component type is the same as the element.

+ *

+ *

+     * helper.ArrayUtils.add([1L], 0, 2L)           = [2L, 1L]
+     * helper.ArrayUtils.add([2L, 6L], 2, 10L)      = [2L, 6L, 10L]
+     * helper.ArrayUtils.add([2L, 6L], 0, -4L)      = [-4L, 2L, 6L]
+     * helper.ArrayUtils.add([2L, 6L, 3L], 2, 1L)   = [2L, 6L, 1L, 3L]
+     * 
+ * + * @param array the array to add the element to, may be null + * @param index the position of the new object + * @param element the object to add + * @return A new array containing the existing elements and the new element + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index > array.length). + */ + public static long[] add(long[] array, int index, long element) { + return (long[]) add(array, index, new Long(element), Long.TYPE); + } + + /** + *

Inserts the specified element at the specified position in the array. + * Shifts the element currently at that position (if any) and any subsequent + * elements to the right (adds one to their indices).

+ *

+ *

This method returns a new array with the same elements of the input + * array plus the given element on the specified position. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

If the input array is null, a new one element array is returned + * whose component type is the same as the element.

+ *

+ *

+     * helper.ArrayUtils.add([1.1f], 0, 2.2f)               = [2.2f, 1.1f]
+     * helper.ArrayUtils.add([2.3f, 6.4f], 2, 10.5f)        = [2.3f, 6.4f, 10.5f]
+     * helper.ArrayUtils.add([2.6f, 6.7f], 0, -4.8f)        = [-4.8f, 2.6f, 6.7f]
+     * helper.ArrayUtils.add([2.9f, 6.0f, 0.3f], 2, 1.0f)   = [2.9f, 6.0f, 1.0f, 0.3f]
+     * 
+ * + * @param array the array to add the element to, may be null + * @param index the position of the new object + * @param element the object to add + * @return A new array containing the existing elements and the new element + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index > array.length). + */ + public static float[] add(float[] array, int index, float element) { + return (float[]) add(array, index, new Float(element), Float.TYPE); + } + + /** + *

Inserts the specified element at the specified position in the array. + * Shifts the element currently at that position (if any) and any subsequent + * elements to the right (adds one to their indices).

+ *

+ *

This method returns a new array with the same elements of the input + * array plus the given element on the specified position. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

If the input array is null, a new one element array is returned + * whose component type is the same as the element.

+ *

+ *

+     * helper.ArrayUtils.add([1.1], 0, 2.2)              = [2.2, 1.1]
+     * helper.ArrayUtils.add([2.3, 6.4], 2, 10.5)        = [2.3, 6.4, 10.5]
+     * helper.ArrayUtils.add([2.6, 6.7], 0, -4.8)        = [-4.8, 2.6, 6.7]
+     * helper.ArrayUtils.add([2.9, 6.0, 0.3], 2, 1.0)    = [2.9, 6.0, 1.0, 0.3]
+     * 
+ * + * @param array the array to add the element to, may be null + * @param index the position of the new object + * @param element the object to add + * @return A new array containing the existing elements and the new element + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index > array.length). + */ + public static double[] add(double[] array, int index, double element) { + return (double[]) add(array, index, element, Double.TYPE); + } + + /** + * Underlying implementation of add(array, index, element) methods. + * The last parameter is the class, which may not equal element.getClass + * for primitives. + * + * @param array the array to add the element to, may be null + * @param index the position of the new object + * @param element the object to add + * @param clss the type of the element being added + * @return A new array containing the existing elements and the new element + */ + private static Object add(Object array, int index, Object element, Class clss) { + if (array == null) { + if (index != 0) { + throw new IndexOutOfBoundsException("Index: " + index + ", Length: 0"); + } + Object joinedArray = Array.newInstance(clss, 1); + Array.set(joinedArray, 0, element); + return joinedArray; + } + int length = Array.getLength(array); + if (index > length || index < 0) { + throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length); + } + Object result = Array.newInstance(clss, length + 1); + System.arraycopy(array, 0, result, 0, index); + Array.set(result, index, element); + if (index < length) { + System.arraycopy(array, index, result, index + 1, length - index); + } + return result; + } + + /** + *

Removes the element at the specified position from the specified array. + * All subsequent elements are shifted to the left (substracts one from + * their indices).

+ *

+ *

This method returns a new array with the same elements of the input + * array except the element on the specified position. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

If the input array is null, an IndexOutOfBoundsException + * will be thrown, because in that case no valid index can be specified.

+ *

+ *

+     * helper.ArrayUtils.remove(["a"], 0)           = []
+     * helper.ArrayUtils.remove(["a", "b"], 0)      = ["b"]
+     * helper.ArrayUtils.remove(["a", "b"], 1)      = ["a"]
+     * helper.ArrayUtils.remove(["a", "b", "c"], 1) = ["a", "c"]
+     * 
+ * + * @param array the array to remove the element from, may not be null + * @param index the position of the element to be removed + * @return A new array containing the existing elements except the element + * at the specified position. + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index >= array.length), or if the array is null. + * @since 2.1 + */ + public static Object[] remove(Object[] array, int index) { + return (Object[]) remove((Object) array, index); + } + + /** + *

Removes the first occurrence of the specified element from the + * specified array. All subsequent elements are shifted to the left + * (substracts one from their indices). If the array doesn't contains + * such an element, no elements are removed from the array.

+ *

+ *

This method returns a new array with the same elements of the input + * array except the first occurrence of the specified element. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

+     * helper.ArrayUtils.removeElement(null, "a")            = null
+     * helper.ArrayUtils.removeElement([], "a")              = []
+     * helper.ArrayUtils.removeElement(["a"], "b")           = ["a"]
+     * helper.ArrayUtils.removeElement(["a", "b"], "a")      = ["b"]
+     * helper.ArrayUtils.removeElement(["a", "b", "a"], "a") = ["b", "a"]
+     * 
+ * + * @param array the array to remove the element from, may be null + * @param element the element to be removed + * @return A new array containing the existing elements except the first + * occurrence of the specified element. + * @since 2.1 + */ + public static Object[] removeElement(Object[] array, Object element) { + int index = indexOf(array, element); + if (index == INDEX_NOT_FOUND) { + return clone(array); + } + return remove(array, index); + } + + /** + *

Removes the element at the specified position from the specified array. + * All subsequent elements are shifted to the left (substracts one from + * their indices).

+ *

+ *

This method returns a new array with the same elements of the input + * array except the element on the specified position. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

If the input array is null, an IndexOutOfBoundsException + * will be thrown, because in that case no valid index can be specified.

+ *

+ *

+     * helper.ArrayUtils.remove([true], 0)              = []
+     * helper.ArrayUtils.remove([true, false], 0)       = [false]
+     * helper.ArrayUtils.remove([true, false], 1)       = [true]
+     * helper.ArrayUtils.remove([true, true, false], 1) = [true, false]
+     * 
+ * + * @param array the array to remove the element from, may not be null + * @param index the position of the element to be removed + * @return A new array containing the existing elements except the element + * at the specified position. + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index >= array.length), or if the array is null. + * @since 2.1 + */ + public static boolean[] remove(boolean[] array, int index) { + return (boolean[]) remove((Object) array, index); + } + + /** + *

Removes the first occurrence of the specified element from the + * specified array. All subsequent elements are shifted to the left + * (substracts one from their indices). If the array doesn't contains + * such an element, no elements are removed from the array.

+ *

+ *

This method returns a new array with the same elements of the input + * array except the first occurrence of the specified element. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

+     * helper.ArrayUtils.removeElement(null, true)                = null
+     * helper.ArrayUtils.removeElement([], true)                  = []
+     * helper.ArrayUtils.removeElement([true], false)             = [true]
+     * helper.ArrayUtils.removeElement([true, false], false)      = [true]
+     * helper.ArrayUtils.removeElement([true, false, true], true) = [false, true]
+     * 
+ * + * @param array the array to remove the element from, may be null + * @param element the element to be removed + * @return A new array containing the existing elements except the first + * occurrence of the specified element. + * @since 2.1 + */ + public static boolean[] removeElement(boolean[] array, boolean element) { + int index = indexOf(array, element); + if (index == INDEX_NOT_FOUND) { + return clone(array); + } + return remove(array, index); + } + + /** + *

Removes the element at the specified position from the specified array. + * All subsequent elements are shifted to the left (substracts one from + * their indices).

+ *

+ *

This method returns a new array with the same elements of the input + * array except the element on the specified position. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

If the input array is null, an IndexOutOfBoundsException + * will be thrown, because in that case no valid index can be specified.

+ *

+ *

+     * helper.ArrayUtils.remove([1], 0)          = []
+     * helper.ArrayUtils.remove([1, 0], 0)       = [0]
+     * helper.ArrayUtils.remove([1, 0], 1)       = [1]
+     * helper.ArrayUtils.remove([1, 0, 1], 1)    = [1, 1]
+     * 
+ * + * @param array the array to remove the element from, may not be null + * @param index the position of the element to be removed + * @return A new array containing the existing elements except the element + * at the specified position. + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index >= array.length), or if the array is null. + * @since 2.1 + */ + public static byte[] remove(byte[] array, int index) { + return (byte[]) remove((Object) array, index); + } + + /** + *

Removes the first occurrence of the specified element from the + * specified array. All subsequent elements are shifted to the left + * (substracts one from their indices). If the array doesn't contains + * such an element, no elements are removed from the array.

+ *

+ *

This method returns a new array with the same elements of the input + * array except the first occurrence of the specified element. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

+     * helper.ArrayUtils.removeElement(null, 1)        = null
+     * helper.ArrayUtils.removeElement([], 1)          = []
+     * helper.ArrayUtils.removeElement([1], 0)         = [1]
+     * helper.ArrayUtils.removeElement([1, 0], 0)      = [1]
+     * helper.ArrayUtils.removeElement([1, 0, 1], 1)   = [0, 1]
+     * 
+ * + * @param array the array to remove the element from, may be null + * @param element the element to be removed + * @return A new array containing the existing elements except the first + * occurrence of the specified element. + * @since 2.1 + */ + public static byte[] removeElement(byte[] array, byte element) { + int index = indexOf(array, element); + if (index == INDEX_NOT_FOUND) { + return clone(array); + } + return remove(array, index); + } + + /** + *

Removes the element at the specified position from the specified array. + * All subsequent elements are shifted to the left (substracts one from + * their indices).

+ *

+ *

This method returns a new array with the same elements of the input + * array except the element on the specified position. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

If the input array is null, an IndexOutOfBoundsException + * will be thrown, because in that case no valid index can be specified.

+ *

+ *

+     * helper.ArrayUtils.remove(['a'], 0)           = []
+     * helper.ArrayUtils.remove(['a', 'b'], 0)      = ['b']
+     * helper.ArrayUtils.remove(['a', 'b'], 1)      = ['a']
+     * helper.ArrayUtils.remove(['a', 'b', 'c'], 1) = ['a', 'c']
+     * 
+ * + * @param array the array to remove the element from, may not be null + * @param index the position of the element to be removed + * @return A new array containing the existing elements except the element + * at the specified position. + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index >= array.length), or if the array is null. + * @since 2.1 + */ + public static char[] remove(char[] array, int index) { + return (char[]) remove((Object) array, index); + } + + /** + *

Removes the first occurrence of the specified element from the + * specified array. All subsequent elements are shifted to the left + * (substracts one from their indices). If the array doesn't contains + * such an element, no elements are removed from the array.

+ *

+ *

This method returns a new array with the same elements of the input + * array except the first occurrence of the specified element. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

+     * helper.ArrayUtils.removeElement(null, 'a')            = null
+     * helper.ArrayUtils.removeElement([], 'a')              = []
+     * helper.ArrayUtils.removeElement(['a'], 'b')           = ['a']
+     * helper.ArrayUtils.removeElement(['a', 'b'], 'a')      = ['b']
+     * helper.ArrayUtils.removeElement(['a', 'b', 'a'], 'a') = ['b', 'a']
+     * 
+ * + * @param array the array to remove the element from, may be null + * @param element the element to be removed + * @return A new array containing the existing elements except the first + * occurrence of the specified element. + * @since 2.1 + */ + public static char[] removeElement(char[] array, char element) { + int index = indexOf(array, element); + if (index == INDEX_NOT_FOUND) { + return clone(array); + } + return remove(array, index); + } + + /** + *

Removes the element at the specified position from the specified array. + * All subsequent elements are shifted to the left (substracts one from + * their indices).

+ *

+ *

This method returns a new array with the same elements of the input + * array except the element on the specified position. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

If the input array is null, an IndexOutOfBoundsException + * will be thrown, because in that case no valid index can be specified.

+ *

+ *

+     * helper.ArrayUtils.remove([1.1], 0)           = []
+     * helper.ArrayUtils.remove([2.5, 6.0], 0)      = [6.0]
+     * helper.ArrayUtils.remove([2.5, 6.0], 1)      = [2.5]
+     * helper.ArrayUtils.remove([2.5, 6.0, 3.8], 1) = [2.5, 3.8]
+     * 
+ * + * @param array the array to remove the element from, may not be null + * @param index the position of the element to be removed + * @return A new array containing the existing elements except the element + * at the specified position. + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index >= array.length), or if the array is null. + * @since 2.1 + */ + public static double[] remove(double[] array, int index) { + return (double[]) remove((Object) array, index); + } + + /** + *

Removes the first occurrence of the specified element from the + * specified array. All subsequent elements are shifted to the left + * (substracts one from their indices). If the array doesn't contains + * such an element, no elements are removed from the array.

+ *

+ *

This method returns a new array with the same elements of the input + * array except the first occurrence of the specified element. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

+     * helper.ArrayUtils.removeElement(null, 1.1)            = null
+     * helper.ArrayUtils.removeElement([], 1.1)              = []
+     * helper.ArrayUtils.removeElement([1.1], 1.2)           = [1.1]
+     * helper.ArrayUtils.removeElement([1.1, 2.3], 1.1)      = [2.3]
+     * helper.ArrayUtils.removeElement([1.1, 2.3, 1.1], 1.1) = [2.3, 1.1]
+     * 
+ * + * @param array the array to remove the element from, may be null + * @param element the element to be removed + * @return A new array containing the existing elements except the first + * occurrence of the specified element. + * @since 2.1 + */ + public static double[] removeElement(double[] array, double element) { + int index = indexOf(array, element); + if (index == INDEX_NOT_FOUND) { + return clone(array); + } + return remove(array, index); + } + + /** + *

Removes the element at the specified position from the specified array. + * All subsequent elements are shifted to the left (substracts one from + * their indices).

+ *

+ *

This method returns a new array with the same elements of the input + * array except the element on the specified position. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

If the input array is null, an IndexOutOfBoundsException + * will be thrown, because in that case no valid index can be specified.

+ *

+ *

+     * helper.ArrayUtils.remove([1.1], 0)           = []
+     * helper.ArrayUtils.remove([2.5, 6.0], 0)      = [6.0]
+     * helper.ArrayUtils.remove([2.5, 6.0], 1)      = [2.5]
+     * helper.ArrayUtils.remove([2.5, 6.0, 3.8], 1) = [2.5, 3.8]
+     * 
+ * + * @param array the array to remove the element from, may not be null + * @param index the position of the element to be removed + * @return A new array containing the existing elements except the element + * at the specified position. + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index >= array.length), or if the array is null. + * @since 2.1 + */ + public static float[] remove(float[] array, int index) { + return (float[]) remove((Object) array, index); + } + + /** + *

Removes the first occurrence of the specified element from the + * specified array. All subsequent elements are shifted to the left + * (substracts one from their indices). If the array doesn't contains + * such an element, no elements are removed from the array.

+ *

+ *

This method returns a new array with the same elements of the input + * array except the first occurrence of the specified element. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

+     * helper.ArrayUtils.removeElement(null, 1.1)            = null
+     * helper.ArrayUtils.removeElement([], 1.1)              = []
+     * helper.ArrayUtils.removeElement([1.1], 1.2)           = [1.1]
+     * helper.ArrayUtils.removeElement([1.1, 2.3], 1.1)      = [2.3]
+     * helper.ArrayUtils.removeElement([1.1, 2.3, 1.1], 1.1) = [2.3, 1.1]
+     * 
+ * + * @param array the array to remove the element from, may be null + * @param element the element to be removed + * @return A new array containing the existing elements except the first + * occurrence of the specified element. + * @since 2.1 + */ + public static float[] removeElement(float[] array, float element) { + int index = indexOf(array, element); + if (index == INDEX_NOT_FOUND) { + return clone(array); + } + return remove(array, index); + } + + /** + *

Removes the element at the specified position from the specified array. + * All subsequent elements are shifted to the left (substracts one from + * their indices).

+ *

+ *

This method returns a new array with the same elements of the input + * array except the element on the specified position. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

If the input array is null, an IndexOutOfBoundsException + * will be thrown, because in that case no valid index can be specified.

+ *

+ *

+     * helper.ArrayUtils.remove([1], 0)         = []
+     * helper.ArrayUtils.remove([2, 6], 0)      = [6]
+     * helper.ArrayUtils.remove([2, 6], 1)      = [2]
+     * helper.ArrayUtils.remove([2, 6, 3], 1)   = [2, 3]
+     * 
+ * + * @param array the array to remove the element from, may not be null + * @param index the position of the element to be removed + * @return A new array containing the existing elements except the element + * at the specified position. + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index >= array.length), or if the array is null. + * @since 2.1 + */ + public static int[] remove(int[] array, int index) { + return (int[]) remove((Object) array, index); + } + + /** + *

Removes the first occurrence of the specified element from the + * specified array. All subsequent elements are shifted to the left + * (substracts one from their indices). If the array doesn't contains + * such an element, no elements are removed from the array.

+ *

+ *

This method returns a new array with the same elements of the input + * array except the first occurrence of the specified element. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

+     * helper.ArrayUtils.removeElement(null, 1)      = null
+     * helper.ArrayUtils.removeElement([], 1)        = []
+     * helper.ArrayUtils.removeElement([1], 2)       = [1]
+     * helper.ArrayUtils.removeElement([1, 3], 1)    = [3]
+     * helper.ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
+     * 
+ * + * @param array the array to remove the element from, may be null + * @param element the element to be removed + * @return A new array containing the existing elements except the first + * occurrence of the specified element. + * @since 2.1 + */ + public static int[] removeElement(int[] array, int element) { + int index = indexOf(array, element); + if (index == INDEX_NOT_FOUND) { + return clone(array); + } + return remove(array, index); + } + + /** + *

Removes the element at the specified position from the specified array. + * All subsequent elements are shifted to the left (substracts one from + * their indices).

+ *

+ *

This method returns a new array with the same elements of the input + * array except the element on the specified position. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

If the input array is null, an IndexOutOfBoundsException + * will be thrown, because in that case no valid index can be specified.

+ *

+ *

+     * helper.ArrayUtils.remove([1], 0)         = []
+     * helper.ArrayUtils.remove([2, 6], 0)      = [6]
+     * helper.ArrayUtils.remove([2, 6], 1)      = [2]
+     * helper.ArrayUtils.remove([2, 6, 3], 1)   = [2, 3]
+     * 
+ * + * @param array the array to remove the element from, may not be null + * @param index the position of the element to be removed + * @return A new array containing the existing elements except the element + * at the specified position. + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index >= array.length), or if the array is null. + * @since 2.1 + */ + public static long[] remove(long[] array, int index) { + return (long[]) remove((Object) array, index); + } + + /** + *

Removes the first occurrence of the specified element from the + * specified array. All subsequent elements are shifted to the left + * (substracts one from their indices). If the array doesn't contains + * such an element, no elements are removed from the array.

+ *

+ *

This method returns a new array with the same elements of the input + * array except the first occurrence of the specified element. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

+     * helper.ArrayUtils.removeElement(null, 1)      = null
+     * helper.ArrayUtils.removeElement([], 1)        = []
+     * helper.ArrayUtils.removeElement([1], 2)       = [1]
+     * helper.ArrayUtils.removeElement([1, 3], 1)    = [3]
+     * helper.ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
+     * 
+ * + * @param array the array to remove the element from, may be null + * @param element the element to be removed + * @return A new array containing the existing elements except the first + * occurrence of the specified element. + * @since 2.1 + */ + public static long[] removeElement(long[] array, long element) { + int index = indexOf(array, element); + if (index == INDEX_NOT_FOUND) { + return clone(array); + } + return remove(array, index); + } + + /** + *

Removes the element at the specified position from the specified array. + * All subsequent elements are shifted to the left (substracts one from + * their indices).

+ *

+ *

This method returns a new array with the same elements of the input + * array except the element on the specified position. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

If the input array is null, an IndexOutOfBoundsException + * will be thrown, because in that case no valid index can be specified.

+ *

+ *

+     * helper.ArrayUtils.remove([1], 0)         = []
+     * helper.ArrayUtils.remove([2, 6], 0)      = [6]
+     * helper.ArrayUtils.remove([2, 6], 1)      = [2]
+     * helper.ArrayUtils.remove([2, 6, 3], 1)   = [2, 3]
+     * 
+ * + * @param array the array to remove the element from, may not be null + * @param index the position of the element to be removed + * @return A new array containing the existing elements except the element + * at the specified position. + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index >= array.length), or if the array is null. + * @since 2.1 + */ + public static short[] remove(short[] array, int index) { + return (short[]) remove((Object) array, index); + } + + /** + *

Removes the first occurrence of the specified element from the + * specified array. All subsequent elements are shifted to the left + * (substracts one from their indices). If the array doesn't contains + * such an element, no elements are removed from the array.

+ *

+ *

This method returns a new array with the same elements of the input + * array except the first occurrence of the specified element. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

+     * helper.ArrayUtils.removeElement(null, 1)      = null
+     * helper.ArrayUtils.removeElement([], 1)        = []
+     * helper.ArrayUtils.removeElement([1], 2)       = [1]
+     * helper.ArrayUtils.removeElement([1, 3], 1)    = [3]
+     * helper.ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
+     * 
+ * + * @param array the array to remove the element from, may be null + * @param element the element to be removed + * @return A new array containing the existing elements except the first + * occurrence of the specified element. + * @since 2.1 + */ + public static short[] removeElement(short[] array, short element) { + int index = indexOf(array, element); + if (index == INDEX_NOT_FOUND) { + return clone(array); + } + return remove(array, index); + } + + /** + *

Removes the element at the specified position from the specified array. + * All subsequent elements are shifted to the left (substracts one from + * their indices).

+ *

+ *

This method returns a new array with the same elements of the input + * array except the element on the specified position. The component + * type of the returned array is always the same as that of the input + * array.

+ *

+ *

If the input array is null, an IndexOutOfBoundsException + * will be thrown, because in that case no valid index can be specified.

+ * + * @param array the array to remove the element from, may not be null + * @param index the position of the element to be removed + * @return A new array containing the existing elements except the element + * at the specified position. + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index >= array.length), or if the array is null. + * @since 2.1 + */ + private static Object remove(Object array, int index) { + int length = getLength(array); + if (index < 0 || index >= length) { + throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length); + } + + Object result = Array.newInstance(array.getClass().getComponentType(), length - 1); + System.arraycopy(array, 0, result, 0, index); + if (index < length - 1) { + System.arraycopy(array, index + 1, result, index, length - index - 1); + } + + return result; + } + + /** + * java.util.Arrays.toList 方法返回的是不可变的list,而且List类型是一个内部私有的类 + * 此方法返回一个 ArrayList + * @param array + * @param + * @return + */ + public static List toList(T[] array) { + List list = new ArrayList(); + if (array == null || array.length == 0) { + return list; + } + Collections.addAll(list, array); + return list; + } +} \ No newline at end of file diff --git a/src/helper/EncodeConstants.java b/src/helper/EncodeConstants.java new file mode 100644 index 0000000..1b90e0e --- /dev/null +++ b/src/helper/EncodeConstants.java @@ -0,0 +1,11 @@ +package helper; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2018-12-03 + */ +public class EncodeConstants { + + public static final String ENCODING_UTF_8 = "UTF-8"; +} diff --git a/src/helper/KeyReader.java b/src/helper/KeyReader.java new file mode 100644 index 0000000..c7dd50d --- /dev/null +++ b/src/helper/KeyReader.java @@ -0,0 +1,89 @@ +package helper; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2018-12-03 + */ +public class KeyReader { + + private static final int TW_MB = 32 * 1024; + + private static final Pattern PUBLIC_PATTERN = Pattern.compile("-----BEGIN PUBLIC KEY-----([\\s\\S]*?)-----END PUBLIC KEY-----"); + private static final Pattern PRIVATE_PATTERN = Pattern.compile("-----BEGIN PRIVATE KEY-----([\\s\\S]*?)-----END PRIVATE KEY-----"); + + private static PrivateKey privateKey = null; + private static PublicKey publicKey = null; + + static { + try { + String text = readFileContext(); + privateKey = RSAUtils.string2PrivateKey(getMatchedText(text, PRIVATE_PATTERN)); + publicKey = RSAUtils.string2PublicKey(getMatchedText(text, PUBLIC_PATTERN)); + } catch (Exception e) { + LoggerFactory.getLogger().error(e.getMessage(), e); + } + } + + public static PrivateKey getPrivateKey() { + return privateKey; + } + + public static PublicKey getPublicKey() { + return publicKey; + } + + private static String readFileContext() { + InputStream in = KeyReader.class.getResourceAsStream("/key.txt"); + byte[] bytes = inputStream2Bytes(in); + return new String(bytes, StandardCharsets.UTF_8); + } + + private static String getMatchedText(String text, Pattern pattern){ + Matcher m = pattern.matcher(text); + if (m.find()){ + return m.group(1).trim(); + } + return ""; + } + + private static byte[] inputStream2Bytes(InputStream in) { + if (in == null) { + return new byte[0]; + } + byte[] temp = new byte[TW_MB]; + ByteArrayOutputStream bi = new ByteArrayOutputStream(); + try { + int count; + while ((count = in.read(temp)) > 0) { + byte[] b4Add; + if (temp.length == count) { + b4Add = temp; + } else { + b4Add = ArrayUtils.subarray(temp, 0, count); + } + bi.write(b4Add); + } + } catch (IOException e) { + LoggerFactory.getLogger().error(e.getMessage(), e); + } finally { + try { + in.close(); + } catch (IOException e) { + LoggerFactory.getLogger().error(e.getMessage(), e); + } + } + + return bi.toByteArray(); + } + +} diff --git a/src/helper/Logger.java b/src/helper/Logger.java new file mode 100644 index 0000000..c41498f --- /dev/null +++ b/src/helper/Logger.java @@ -0,0 +1,16 @@ +package helper; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2018-12-03 + */ +public class Logger { + + public void error(String message, Throwable t) { + System.out.println("error:" + message); + if (t != null) { + t.printStackTrace(); + } + } +} diff --git a/src/helper/LoggerFactory.java b/src/helper/LoggerFactory.java new file mode 100644 index 0000000..70c2f1a --- /dev/null +++ b/src/helper/LoggerFactory.java @@ -0,0 +1,15 @@ +package helper; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2018-12-03 + */ +public class LoggerFactory { + + private static Logger logger = new Logger(); + + public static Logger getLogger() { + return logger; + } +} diff --git a/src/helper/RSAUtils.java b/src/helper/RSAUtils.java new file mode 100644 index 0000000..8a26ee3 --- /dev/null +++ b/src/helper/RSAUtils.java @@ -0,0 +1,265 @@ +package helper; + +import sun.misc.BASE64Decoder; +import sun.misc.BASE64Encoder; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.MessageDigest; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + + +public class RSAUtils { + + private static final int FRAGMENT_LENGTH = 245; + private static final int FRAGMENT_LENGTH_DECRYPT = 256; + + + /** + * RSA加密 + * + * @param plainText 要加密的文本内容 + * @param publicKey 用于加密的公钥 + * @return 加密后的内容 + */ + public static String encrypt(String plainText, Key publicKey) { + if (StringUtils.isEmpty(plainText)) { + return plainText; + } + try { + byte[] publicEncrypt = encrypt(plainText.getBytes(EncodeConstants.ENCODING_UTF_8), publicKey); + return RSAUtils.byte2Base64(publicEncrypt); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + + /** + * RSA解密 + * + * @param cipherText 密文数据 + * @return 解密后的内容 + */ + public static String decrypt(String cipherText, Key privateKey) { + + if (StringUtils.isEmpty(cipherText)) { + return cipherText; + } + byte[] bytes = null; + try { + bytes = decrypt(base642Byte(cipherText), privateKey); + } catch (Exception e) { + LoggerFactory.getLogger().error(e.getMessage(), e); + } + if (bytes == null) { + return null; + } + try { + return new String(bytes, EncodeConstants.ENCODING_UTF_8); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + + + /** + * RSA加密 + * + * @param plainTextData 要加密的内容 + * @param publicKey 用于加密的公钥 + * @return 加密后的内容 + */ + public static byte[] encrypt(byte[] plainTextData, Key publicKey) { + + if (ArrayUtils.isEmpty(plainTextData)) { + return plainTextData; + } + try { + Cipher c1 = Cipher.getInstance("RSA"); + c1.init(Cipher.ENCRYPT_MODE, publicKey); + return dealEncryptFragment(plainTextData, c1); + } catch (Exception e) { + LoggerFactory.getLogger().error(e.getMessage(), e); + } + return null; + } + + private static byte[] dealEncryptFragment(byte[] data, Cipher cipher) throws IllegalBlockSizeException, BadPaddingException { + + byte[] result = new byte[]{}; + int i; + for (i = 0; i < data.length; i += FRAGMENT_LENGTH) { + byte[] fragment = ArrayUtils.subarray(data, i, i + FRAGMENT_LENGTH); + byte[] update = cipher.doFinal(fragment); + result = ArrayUtils.addAll(result, update); + } + return result; + } + + + /** + * RSA解密 + * + * @param cipherData 密文数据 + * @param privateKey 用于解密的私钥 + * @return 解密后的内容 + */ + public static byte[] decrypt(byte[] cipherData, Key privateKey) { + try { + Cipher c1 = Cipher.getInstance("RSA"); + c1.init(Cipher.DECRYPT_MODE, privateKey); + return dealDecryptFragment(cipherData, c1); + } catch (Exception e) { + LoggerFactory.getLogger().error(e.getMessage(), e); + } + return null; + } + + + private static byte[] dealDecryptFragment(byte[] data, Cipher cipher) throws IllegalBlockSizeException, BadPaddingException { + + byte[] result = new byte[]{}; + int i; + for (i = 0; i < data.length; i += FRAGMENT_LENGTH_DECRYPT) { + byte[] fragment = ArrayUtils.subarray(data, i, i + FRAGMENT_LENGTH_DECRYPT); + byte[] update = cipher.doFinal(fragment); + result = ArrayUtils.addAll(result, update); + } + return result; + } + + + + public static String sha256(String plainTextData) { + if (StringUtils.isEmpty(plainTextData)) { + return plainTextData; + } + try { + byte[] bytes = sha256(plainTextData.getBytes(EncodeConstants.ENCODING_UTF_8)); + return byteArrayToHexString(bytes); + } catch (UnsupportedEncodingException e) { + LoggerFactory.getLogger().error(e.getMessage(), e); + } + return plainTextData; + } + + private static byte[] sha256(byte[] plainTextData) { + if (plainTextData == null || ArrayUtils.isEmpty(plainTextData)) { + return plainTextData; + } + try { + MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); + messageDigest.update(plainTextData); + return messageDigest.digest(); + } catch (Exception e) { + LoggerFactory.getLogger().error(e.getMessage(), e); + } + return plainTextData; + } + + /** + * 将加密后的字节数组转换成字符串 + * + * @param b 字节数组 + * @return 字符串 + */ + public static String byteArrayToHexString(byte[] b) { + StringBuilder hs = new StringBuilder(); + String tempStr; + for (int n = 0; b != null && n < b.length; n++) { + tempStr = Integer.toHexString(b[n] & 0XFF); + if (tempStr.length() == 1) + hs.append('0'); + hs.append(tempStr); + } + return hs.toString().toLowerCase(); + } + + + /** + * 生成一个2048位的RSA秘钥对 + * + * @return 秘钥对 + * @throws Exception 如果无法生成秘钥对则抛出次异常 + */ + public static KeyPair getKeyPair() throws Exception { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(2048); + return keyPairGenerator.generateKeyPair(); + } + + /** + * 获取RSA公钥的base64编码字符串 + * + * @param keyPair 秘钥对 + * @return 公钥编码字符串 + */ + public static String getPublicKey(KeyPair keyPair) { + PublicKey publicKey = keyPair.getPublic(); + byte[] bytes = publicKey.getEncoded(); + return byte2Base64(bytes); + } + + /** + * 获取RSA私钥的base64编码字符串 + * + * @param keyPair 秘钥对 + * @return 私钥编码字符串 + */ + public static String getPrivateKey(KeyPair keyPair) { + PrivateKey privateKey = keyPair.getPrivate(); + byte[] bytes = privateKey.getEncoded(); + return byte2Base64(bytes); + } + + public static PublicKey string2PublicKey(String pubStr) { + try { + byte[] keyBytes = base642Byte(pubStr); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + return keyFactory.generatePublic(keySpec); + } catch (Exception e) { + LoggerFactory.getLogger().error(e.getMessage(), e); + } + return null; + } + + public static PrivateKey string2PrivateKey(String priStr) { + try { + byte[] keyBytes = base642Byte(priStr); + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + return keyFactory.generatePrivate(keySpec); + } catch (Exception e) { + LoggerFactory.getLogger().error(e.getMessage(), e); + } + return null; + } + + public static String byte2Base64(byte[] bytes) { + BASE64Encoder encoder = new BASE64Encoder(); + return encoder.encode(bytes); + } + + public static byte[] base642Byte(String base64Key) throws IOException { + BASE64Decoder decoder = new BASE64Decoder(); + return decoder.decodeBuffer(base64Key); + } + + public static void main(String... args) { + + } + +} diff --git a/src/helper/StringUtils.java b/src/helper/StringUtils.java new file mode 100644 index 0000000..97928b3 --- /dev/null +++ b/src/helper/StringUtils.java @@ -0,0 +1,555 @@ +package helper; + +import java.io.UnsupportedEncodingException; +import java.util.Arrays; +import java.util.StringTokenizer; + +/** + *

Operations on {@link java.lang.String} that are + * null safe.

+ *

+ *

    + *
  • IsEmpty/IsBlank + * - checks if a String contains text
  • + *
  • Trim/Strip + * - removes leading and trailing whitespace
  • + *
  • Equals + * - compares two strings null-safe
  • + *
  • startsWith + * - check if a String starts with a prefix null-safe
  • + *
  • endsWith + * - check if a String ends with a suffix null-safe
  • + *
  • IndexOf/LastIndexOf/Contains + * - null-safe index-of checks + *
  • IndexOfAny/LastIndexOfAny/IndexOfAnyBut/LastIndexOfAnyBut + * - index-of any of a set of Strings
  • + *
  • ContainsOnly/ContainsNone/ContainsAny + * - does String contains only/none/any of these characters
  • + *
  • Substring/Left/Right/Mid + * - null-safe substring extractions
  • + *
  • SubstringBefore/SubstringAfter/SubstringBetween + * - substring extraction relative to other strings
  • + *
  • Split/Join + * - splits a String into an array of substrings and vice versa
  • + *
  • Remove/Delete + * - removes part of a String
  • + *
  • Replace/Overlay + * - Searches a String and replaces one String with another
  • + *
  • Chomp/Chop + * - removes the last part of a String
  • + *
  • LeftPad/RightPad/Center/Repeat + * - pads a String
  • + *
  • UpperCase/LowerCase/SwapCase/Capitalize/Uncapitalize + * - changes the case of a String
  • + *
  • CountMatches + * - counts the number of occurrences of one String in another
  • + *
  • IsAlpha/IsNumeric/IsWhitespace/IsAsciiPrintable + * - checks the characters in a String
  • + *
  • DefaultString + * - protects against a null input String
  • + *
  • Reverse/ReverseDelimited + * - reverses a String
  • + *
  • Abbreviate + * - abbreviates a string using ellipsis
  • + *
  • Difference + * - compares Strings and reports on their differences
  • + *
  • LevensteinDistance + * - the number of changes needed to change one String into another
  • + *
+ *

+ *

The helper.StringUtils class defines certain words related to + * String handling.

+ *

+ *

    + *
  • null - null
  • + *
  • empty - a zero-length string ("")
  • + *
  • space - the space character (' ', char 32)
  • + *
  • whitespace - the characters defined by {@link Character#isWhitespace(char)}
  • + *
  • trim - the characters <= 32 as in {@link String#trim()}
  • + *
+ *

+ *

helper.StringUtils handles null input Strings quietly. + * That is to say that a null input will return null. + * Where a boolean or int is being returned + * details vary by method.

+ *

+ *

A side effect of the null handling is that a + * NullPointerException should be considered a bug in + * helper.StringUtils (except for deprecated methods).

+ *

+ *

Methods in this class give sample code to explain their operation. + * The symbol * is used to indicate any input including null.

+ * + * @author Apache Jakarta Turbine + * @author Jon S. Stevens + * @author Daniel L. Rall + * @author Greg Coladonato + * @author Ed Korthof + * @author Rand McNeely + * @author Stephen Colebourne + * @author Fredrik Westermarck + * @author Holger Krauth + * @author Alexander Day Chaffee + * @author Henning P. Schmiedehausen + * @author Arun Mammen Thomas + * @author Gary Gregory + * @author Phil Steitz + * @author Al Chou + * @author Michael Davey + * @author Reuben Sivan + * @author Chris Hyzer + * @author Scott Johnson + * @version $Id: helper.StringUtils.java 635447 2008-03-10 06:27:09Z bayard $ + * @see java.lang.String + * @since 1.0 + */ +public class StringUtils { + // Performance testing notes (JDK 1.4, Jul03, scolebourne) + // Whitespace: + // Character.isWhitespace() is faster than WHITESPACE.indexOf() + // where WHITESPACE is a string of all whitespace characters + // + // Character access: + // String.charAt(n) versus toCharArray(), then array[n] + // String.charAt(n) is about 15% worse for a 10K string + // They are about equal for a length 50 string + // String.charAt(n) is about 4 times better for a length 3 string + // String.charAt(n) is best bet overall + // + // Append: + // String.concat about twice as fast as StringBuffer.append + // (not sure who tested this) + + /** + * 空字符串 + */ + public static final String EMPTY = ""; + + /** + * 空白字符串 + */ + public static final String BLANK = " "; + + + private StringUtils() { + + } + + /** + * 生成一个非null的字符串 + * + * @param txt 原对象 + * @return 非null的字符窜 + */ + public static String alwaysNotNull(String txt) { + + return txt == null ? StringUtils.EMPTY : txt; + } + + + // Empty checks + //----------------------------------------------------------------------- + + /** + *

检查一个字符串是否是空字符串

+ *

+ *

+     * helper.StringUtils.isEmpty(null)      = true
+     * helper.StringUtils.isEmpty("")        = true
+     * helper.StringUtils.isEmpty(" ")       = false
+     * helper.StringUtils.isEmpty("bob")     = false
+     * helper.StringUtils.isEmpty("  bob  ") = false
+     * 
+ *

+ * + * @param str 被检查的字符串,可能为null + * @return 如果字符串为空或者是null则返回true,否则返回false + */ + public static boolean isEmpty(String str) { + + return str == null || str.length() == 0; + } + + /** + *

检查一个字符串是否不为空字符串

+ *

+ *

+     * helper.StringUtils.isNotEmpty(null)      = false
+     * helper.StringUtils.isNotEmpty("")        = false
+     * helper.StringUtils.isNotEmpty(" ")       = true
+     * helper.StringUtils.isNotEmpty("bob")     = true
+     * helper.StringUtils.isNotEmpty("  bob  ") = true
+     * 
+ * + * @param str 被检查的字符串,可能是null + * @return 如果字符串不为空且不是null则返回true,否则返回false + */ + public static boolean isNotEmpty(String str) { + + return !StringUtils.isEmpty(str); + } + + /** + *

检查一个字符串是否为空白字符串

+ *

+ *

+     * helper.StringUtils.isBlank(null)      = true
+     * helper.StringUtils.isBlank("")        = true
+     * helper.StringUtils.isBlank(" ")       = true
+     * helper.StringUtils.isBlank("bob")     = false
+     * helper.StringUtils.isBlank("  bob  ") = false
+     * 
+ * + * @param str 被检查的字符串 + * @return 如果字符串为空、空格符或者null那么返回true,否则返回false + */ + public static boolean isBlank(String str) { + + int strLen; + return str == null || (strLen = str.length()) == 0 ? true : isBlank(str, strLen); + } + + /** + * for JIT + */ + private static boolean isBlank(String str, int strLen) { + + for (int i = 0; i < strLen; i++) { + if ((Character.isWhitespace(str.charAt(i)) == false)) { + return false; + } + } + return true; + } + + /** + * 处理已A字符开头的字符,去除掉A + * + * @param org 原字符 + * @param mark 标记字符 + * @return 处理后的字符 + */ + public static String cutStringStartWith(String org, String mark) { + + if (org == null) { + return null; + } + + if (mark == null) { + return org; + } + if (!org.startsWith(mark)) { + return org; + } + return org.substring(mark.length()); + } + + /** + * 1??某一个特定字符B结束的字符AB,得到去掉B的前面的字符A + * + * @param org 全部字符 + * @param mark 标记B + * @return 处理后的字符 + */ + public static String cutStringEndWith(String org, String mark) { + + if (org == null) { + return null; + } + + if (mark == null) { + return org; + } + + if (!org.endsWith(mark)) { + return org; + } + int location = org.indexOf(mark); + if (location == -1) { + return org; + } + return org.substring(0, location); + } + + /** + *

检查一个字符串是否不是空白字符串

+ *

+ *

+     * helper.StringUtils.isNotBlank(null)      = false
+     * helper.StringUtils.isNotBlank("")        = false
+     * helper.StringUtils.isNotBlank(" ")       = false
+     * helper.StringUtils.isNotBlank("bob")     = true
+     * helper.StringUtils.isNotBlank("  bob  ") = true
+     * 
+ * + * @param str 被检查的字符串 + * @return 如果字符串不是空字符串、空格符以及null那么就返回true,否则返回false + */ + public static boolean isNotBlank(String str) { + + return !StringUtils.isBlank(str); + } + + // Trim + //----------------------------------------------------------------------- + + /** + *

Removes control characters (char <= 32) from both + * ends of this String, handling null by returning + * null.

+ *

+ *

The String is trimmed using {@link String#trim()}. + * Trim removes start and end characters <= 32. + * To strip whitespace use {@link #(String)}.

+ *

+ *

To trim your choice of characters, use the + * {@link #(String, String)} methods.

+ *

+ *

+     * helper.StringUtils.trim(null)          = null
+     * helper.StringUtils.trim("")            = ""
+     * helper.StringUtils.trim("     ")       = ""
+     * helper.StringUtils.trim("abc")         = "abc"
+     * helper.StringUtils.trim("    abc    ") = "abc"
+     * 
+ * + * @param str the String to be trimmed, may be null + * @return the trimmed string, null if null String input + */ + public static String trim(String str) { + + return str == null ? null : str.trim(); + } + + /** + * 去掉字符串首尾的空白,如果剩余的结果是空白字符串那么返回null + */ + public static String trimToNull(String str) { + + String ts = trim(str); + return isEmpty(ts) ? null : ts; + } + + /** + * 检查一个字符串是否以某个指定的字符串开始,如果是的话不做改变,如果不是的话将把指定的字符串添加到原 + * 字符串的起始位置 + */ + public static String perfectStart(String str, String attach) { + + if (str == null) { + return attach; + } + return str.startsWith(attach) ? str : (attach + str); + } + + /** + * 检查一个字符串是否以某个指定的字符串结束,如果是的话不做改变,如果不是的话将把指定的字符串添加到原 + * 字符串的末尾位置 + */ + public static String perfectEnd(String str, String attach) { + + if (str == null) { + return attach; + } + return str.endsWith(attach) ? str : (str + attach); + } + + public static String perfectSurround(String str, String attach) { + + if (str == null) { + return attach; + } + str = str.endsWith(attach) ? str : (str + attach); + str = str.startsWith(attach) ? str : (attach + str); + + return str; + } + + /** + * 获取字符串的长度,如果是null则返回0 + */ + public static int getLength(String str) { + + return str == null ? 0 : str.length(); + } + + /** + * richer:判断两个字符串是否出去前后的附加字符串外是相等的 + * eg:equalsIgnore("/File/", "File", "/") == true + * 不支持传null path + */ + public static boolean equalsIgnore(String str1, String str2, String attach) { + if(str1 ==null || str2 == null) { + throw new RuntimeException("null path"); + } + return equals(str1, str2) || perfectStart(perfectEnd(str1, attach), attach).equals(perfectStart(perfectEnd(str2, attach), attach)); + } + + /** + * 判断字符串text是否包含字符串ch + * + * @param text 主字符串 + * @param ch 寻找的字符串 + * @return 是否包含 + * @date 2014-12-3-上午11:50:25 + */ + public static boolean contains(String text, String ch) { + + return text != null && text.indexOf(ch) > -1; + } + + /** + * text 做兼容类. + * + * @param text 文本兼容 + * @return StringTokenizer + */ + public static StringTokenizer text2StringTokenizer(String text) { + + return new StringTokenizer(text, "\r\n"); + } + + /** + * carl:拼接数组字符 + */ + public static String join(String seperator, String[] strings) { + + if (strings == null) { + return null; + } + int length = strings.length; + if (length == 0) { + return ""; + } + StringBuffer buf = new StringBuffer(length * strings[0].length()) + .append(strings[0]); + for (int i = 1; i < length; i++) { + buf.append(seperator).append(strings[i]); + } + return buf.toString(); + } + + public static String parseVersion(String xmlDesignerVersion) { + + xmlDesignerVersion = xmlDesignerVersion.replace('A', '0'); + xmlDesignerVersion = xmlDesignerVersion.replace('B', '1'); + xmlDesignerVersion = xmlDesignerVersion.replace('C', '2'); + xmlDesignerVersion = xmlDesignerVersion.replace('D', '3'); + xmlDesignerVersion = xmlDesignerVersion.replace('E', '4'); + xmlDesignerVersion = xmlDesignerVersion.replace('F', '5'); + xmlDesignerVersion = xmlDesignerVersion.replace('G', '6'); + xmlDesignerVersion = xmlDesignerVersion.replace('H', '7'); + xmlDesignerVersion = xmlDesignerVersion.replace('I', '8'); + xmlDesignerVersion = xmlDesignerVersion.replace('J', '9'); + return xmlDesignerVersion; + } + + /** + * 是否是数组类型的字符串 + * + * @param text 目标字符串 + * @return 是否是数组类型的字符串 + */ + public static boolean isArrayType(String text) { + + return text != null && ((text.startsWith("[") && text.endsWith("]")) || (text.startsWith("[[") && text.endsWith("]]"))); + } + + public static String[][] stringToArray(String v) { + //[["华东","江苏"],["华东","上海"]] 或者 ["华东","江苏"] + if (isArrayType(v)) { + v = v.replaceAll("\"", ""); + if (v.startsWith("[[") && v.endsWith("]]")) { + String[] temp = (v.substring(2, v.length() - 2)).split("],\\["); + String[][] strs = new String[temp.length][]; + for (int i = 0; i < strs.length; i++) { + strs[i] = temp[i].split(","); + } + return strs; + } else { + String[][] strs = new String[1][]; + strs[0] = v.substring(1, v.length() - 1).split(","); + return strs; + } + } else { + //华东,江苏;华东,上海 + String[] temp = v.split(";"); + String[][] strs = new String[temp.length][]; + for (int i = 0; i < strs.length; i++) { + strs[i] = temp[i].split(","); + } + return strs; + } + } + + /** + * 根据字节数截取字符串 + * + * @param originString 原始字符串 + * @param charsetName 字符编码 + * @param byteLength 字节长度 + * @return 截取后的字符串 + * @throws UnsupportedEncodingException + */ + public static String subStringByByteLength(String originString, String charsetName, int byteLength) + throws UnsupportedEncodingException { + + if (StringUtils.isBlank(originString) || byteLength <= 0) { + return StringUtils.EMPTY; + } + char[] chars = originString.toCharArray(); + int length = 0, index = chars.length; + for (int i = 0; i < chars.length; i++) { + final int len = String.valueOf(chars[i]).getBytes(charsetName).length + length; + if (len <= byteLength) { + length = len; + } else { + index = i; + break; + } + } + return String.valueOf(chars, 0, index); + } + + + /** + * peter:比较相等. + * + * @param obj1 may be null. + * @param obj2 may be null. + */ + public static boolean equals(String obj1, String obj2) { + + if (obj1 == obj2) { + return true; + } + if (obj1 == null || obj2 == null) { + return false; + } + return obj1.equals(obj2); + } + + /** + * 不区分大小写比较字符串 + */ + public static boolean equalsIgnoreCase(String s1, String s2) { + + if (s1 == null) { + return s2 == null; + } + return s2 != null && s1.equalsIgnoreCase(s2); + } + + /** + * 右侧填充空格直到字符串达到指定长度 + */ + public static String rightPad(String str, int size) { + int len = size - str.length(); + if (len <= 0) { + return str; + } + char[] spaces = new char[len]; + Arrays.fill(spaces, ' '); + return str + String.valueOf(spaces); + } +} \ No newline at end of file diff --git a/src/key.txt b/src/key.txt new file mode 100644 index 0000000..9a49bbb --- /dev/null +++ b/src/key.txt @@ -0,0 +1,32 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx9rvqPePsTPZ+vARSpi7wfg8KokGUqnC +RVUzgQKFOMz/oGVvf9MPXyxw4NVYNJFWpyj1tBMXfsoPZs6/ET8/xd29xbl5UihMhz2AR+0Pu0ym +1znQRSp8SWInvAZxJe/B1fkhWyor+JYLOW5tN2sFlZ8NEFLjoGJ4AbjoMbcX3aHgCOaat5/+GNIr +R0yirJkv+gPgeKiO0H4YMbrqQaMhsSn/9WVCEh9sL5VQHi/Q5vQI4Qfs2cLBgQ7aH9LfnYnKoMD4 +mlczgmE56XVjuA7BpwdFr+AYx2/NY/K83Dpckxmv/WbsHKU8nPqfCo6kmqctDz3ieZSI7RK9fFsi +AYS7GwIDAQAB +-----END PUBLIC KEY----- +-----BEGIN PRIVATE KEY----- +MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDH2u+o94+xM9n68BFKmLvB+Dwq +iQZSqcJFVTOBAoU4zP+gZW9/0w9fLHDg1Vg0kVanKPW0Exd+yg9mzr8RPz/F3b3FuXlSKEyHPYBH +7Q+7TKbXOdBFKnxJYie8BnEl78HV+SFbKiv4lgs5bm03awWVnw0QUuOgYngBuOgxtxfdoeAI5pq3 +n/4Y0itHTKKsmS/6A+B4qI7QfhgxuupBoyGxKf/1ZUISH2wvlVAeL9Dm9AjhB+zZwsGBDtof0t+d +icqgwPiaVzOCYTnpdWO4DsGnB0Wv4BjHb81j8rzcOlyTGa/9ZuwcpTyc+p8KjqSapy0PPeJ5lIjt +Er18WyIBhLsbAgMBAAECggEBAKMzQJPdHQTaT72f/q7IzEIYQKGHZZdpMtBFRBqsgTeiB3jmfEeI +hbv1YXPoI/BBYt58DzBuirgprqwIVnRyDtS4P3jP/ac+a0fgy/lwN3F+pZuJhW6FxBp0wffD1u/g +uovNthRo+qEzfZT3fM5NYbENwbA7z8+vuUnGwi2e0ylSzlGwMokmWRerPHocf7olkcFbd+ZenjiL +leM/MyNkxhtTgk1Jbrp09eZmK0pOg1fZJ3hm6uBPU5swFgMkP7z7LUdn23t2Ww36v7mjcDDJc74Y +VybvnWmYDpSYxTA1w7Wl8yZP6Ob55h/DnRHoxwwT0PauZSVpChhndTtCDXQYP1ECgYEA5l3kMl2x +n8xzKxPH9ZRNlM+HFZv2CaxVsFD7hp05UqStDY6cPvh2BJusEWIw06ngDouM3bxApEIgyGM1jsDI +mHekbtbmfsjCtmoIhc1q3zYyqV1P2CBy6i9vhxvZKLDamzE0eTpVhSTC/IcDP+Q1QSgNYwbnbLIf +FllbWYqAz0kCgYEA3hfooMzO3h+nMqbElH6zHM84s9XBBCD1ZZ7zJSgvf/7o06YxLtJ7/i0DKK4W +JKX5PvmQOY26lFMQtyUvmfo4uvFYLzlei5NY3e7qBOMKdb8wZoo9dSVN3y3WfMcCiENh4Kkl24T5 +5lSku8cmnAey2lci+IoBLG4SF5qDozg7o0MCgYEAtQabSCjwaA6VgghtXcJIpOPf109TrI5MV92L +imEKprLZeonSpnlA5KYgNRjgHbSkaUmoTKaedXWxpUaw05kTCR0bji45uu+wcwAn6l1d2kIQ1Z6K +G+CD7RuRnK55m8w+PS4ReiIpChO1VhQSraZ7YtRCkMrgGT5vx3Q4oMiCKGECgYEAkKRNkvwP9kXz +JF/MQ1HI4QhsS2L5E/FLIOXGQPrNBLVFeSIRggb/TeiO2B2YukGF9GegcHtHenYmusBzIfr+m3G3 +FvpsAsbx54hDzO74zvq3UPDTWcnzz1gRCq6pjYkk46YFy9Ps1P9nUgw/rvqsltqNIgTvArqk+c5d +0R08afUCgYEAnUUNC1FozLVTh2YV5MUuqymXRCmlvcYcWwxY6wjBPJBLBn7hxuoKIZAT7fQbKqwu +ErMUn1wxjCl0Tr+q/BYlujd/WFKqWQg/7jcs6tgLqJwyc1W1N9P2yUb8NdntuadhTEI0EufqAm1O +J8o+Gpm7JlhDmgF6rGKXaFojuDFzuRA= +-----END PRIVATE KEY-----