package com.github.seanlinwang.tkv.util; import java.util.ArrayList; import java.util.List; public class ArrayKit { /** * An empty immutable <code>String</code> array. */ public static final String[] EMPTY_STRING_ARRAY = new String[0]; public static final byte[][] EMPTY_BYTE_ARRAY_ARRAY = new byte[0][0]; /** * <p> * Checks if an array of Objects is empty or <code>null</code>. * </p> * * @param array * the array to test * @return <code>true</code> if the array is empty or <code>null</code> */ public static boolean isEmpty(Object[] array) { if (array == null || array.length == 0) { return true; } return false; } /** * <p> * Checks if an array of Objects is not<code>null</code> and not empty. * </p> * * @param array * the array to test * @return <code>true</code> if the array is not null and not empty. */ public static boolean isNotEmpty(Object[] array) { return !isEmpty(array); } /** * <p> * Find the last index of the given value within the array. * </p> * * <p> * This method returns <code>-1</code> if <code>null</code> array input. * </p> * * @param array * the array to travers backwords looking for the object, may be <code>null</code> * * @param valueToFind * the object to find * * @return the last index of the value within the array, <code>-1</code> if not found or <code>null</code> array input */ public static int lastIndexOf(final byte[] array, final byte valueToFind) { return lastIndexOf(array, valueToFind, Integer.MAX_VALUE); } /** * <p> * Find the last index of the given value in the array starting at the given index. * </p> * * <p> * This method returns <code>-1</code> if <code>null</code> array input. * </p> * * <p> * A negative startIndex will return -1. A startIndex larger than the array length will search from the end of the array. * </p> * * @param array * the array to traverse for looking for the object, may be <code>null</code> * @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, <code>-1</code> if not found or <code>null</code> array input */ public static int lastIndexOf(final byte[] array, final byte valueToFind, int startIndex) { if (array == null) { return -1; } if (startIndex < 0) { return -1; } else if (startIndex >= array.length) { startIndex = array.length - 1; } for (int i = startIndex; i >= 0; i--) { if (valueToFind == array[i]) { return i; } } return -1; } /** * <p> * Find the last index of the given array within the array. * </p> * * <p> * This method returns <code>-1</code> if <code>null</code> array input. * </p> * * @param array * the array to travers backwords looking for the object, may be <code>null</code> * * @param arrayToFind * the array to find * * @return the last index of the given array within the array, <code>-1</code> if not found or <code>null</code> array input */ public static int lastIndexOf(byte[] array, byte[] arrayToFind) { return lastIndexOf(array, arrayToFind, Integer.MAX_VALUE); } /** * <p> * Find the last index of the given array within the array. * </p> * * <p> * This method returns <code>-1</code> if <code>null</code> array input. * </p> * * @param array * the array to travers backwords looking for the object, may be <code>null</code> * * @param arrayToFind * the array to find * * @param startIndex * the start index to travers backwards from * * @return the last index of the given array within the array, <code>-1</code> if not found or <code>null</code> array input */ public static int lastIndexOf(byte[] array, byte[] arrayToFind, int startIndex) { if ((array == null) || (arrayToFind == null)) { return -1; } int sourceLength = array.length; int targetLength = arrayToFind.length; int rightIndex = sourceLength - targetLength; if (startIndex < 0) { return -1; } if (startIndex > rightIndex) { startIndex = rightIndex; } if (targetLength == 0) { return startIndex; } int lastIndex = targetLength - 1; byte last = arrayToFind[lastIndex]; int min = targetLength - 1; int i = min + startIndex; startSearchForLast: while (true) { while ((i >= min) && (array[i] != last)) { i--; } if (i < min) { return -1; } int j = i - 1; int start = j - (targetLength - 1); int k = lastIndex - 1; while (j > start) { if (array[j--] != arrayToFind[k--]) { i--; continue startSearchForLast; } } return start + 1; } } // ----------------------------------------------------------------------- /** * <p> * Find the index of the given value in the array. * </p> * * <p> * This method returns <code>-1</code> if <code>null</code> array input. * </p> * * @param array * the array to search through for the object, may be <code>null</code> * @param valueToFind * the value to find * @return the index of the value within the array, <code>-1</code> if not found or <code>null</code> array input */ public static int indexOf(final byte[] array, final byte valueToFind) { return indexOf(array, valueToFind, 0); } /** * <p> * Find the index of the given value in the array starting at the given index. * </p> * * <p> * This method returns <code>-1</code> if <code>null</code> array input. * </p> * * <p> * A negative startIndex is treated as zero. A startIndex larger than the array length will return -1. * </p> * * @param array * the array to search through for the object, may be <code>null</code> * @param valueToFind * the value to find * @param startIndex * the index to start searching at * @return the index of the value within the array, <code>-1</code> if not found or <code>null</code> array input */ public static int indexOf(final byte[] array, final byte valueToFind, int startIndex) { if (array == null) { return -1; } if (startIndex < 0) { startIndex = 0; } for (int i = startIndex; i < array.length; i++) { if (valueToFind == array[i]) { return i; } } return -1; } public static int indexOf(byte[] array, byte[] arrayToFind) { return indexOf(array, arrayToFind, 0); } public static int indexOf(byte[] array, byte[] arrayToFind, int startIndex) { if ((array == null) || (arrayToFind == null)) { return -1; } int sourceLength = array.length; int targetLength = arrayToFind.length; if (startIndex >= sourceLength) { return (targetLength == 0) ? sourceLength : (-1); } if (startIndex < 0) { startIndex = 0; } if (targetLength == 0) { return startIndex; } byte first = arrayToFind[0]; int i = startIndex; int max = sourceLength - targetLength; startSearchForFirst: while (true) { while ((i <= max) && (array[i] != first)) { i++; } if (i > max) { return -1; } int j = i + 1; int end = (j + targetLength) - 1; int k = 1; while (j < end) { if (array[j++] != arrayToFind[k++]) { i++; continue startSearchForFirst; } } return i; } } /** * <p> * Splits the provided text into an array, separator specified. This is an * alternative to using StringTokenizer. * </p> * * <p> * The separator is not included in the returned String array. Adjacent * separators are treated as one separator. For more control over the split * use the StrTokenizer class. * </p> * * <p> * A <code>null</code> input String returns <code>null</code>. * </p> * * <pre> * StringUtils.split(null, *) = null * StringUtils.split("", *) = [] * StringUtils.split("a.b.c", '.') = ["a", "b", "c"] * StringUtils.split("a..b.c", '.') = ["a", "b", "c"] * StringUtils.split("a:b:c", '.') = ["a:b:c"] * StringUtils.split("a b c", ' ') = ["a", "b", "c"] * </pre> * * @param str * the String to parse, may be null * @param separatorChar * the character used as the delimiter * @return an array of parsed Strings, <code>null</code> if null String * input * @since 2.0 */ public static byte[][] split(byte[] str, byte separatorChar) { return splitWorker(str, separatorChar, false); } private static byte[][] splitWorker(byte[] str, byte separatorChar, boolean preserveAllTokens) { // Performance tuned for 2.0 (JDK1.4) if (str == null) { return null; } int len = str.length; if (len == 0) { return ArrayKit.EMPTY_BYTE_ARRAY_ARRAY; } List<byte[]> list = new ArrayList<byte[]>(); int i = 0, start = 0; boolean match = false; boolean lastMatch = false; while (i < len) { if (str[i] == separatorChar) { if (match || preserveAllTokens) { byte[] tmp = new byte[i - start]; System.arraycopy(str, start, tmp, 0, tmp.length); list.add(tmp); match = false; lastMatch = true; } start = ++i; continue; } lastMatch = false; match = true; i++; } if (match || (preserveAllTokens && lastMatch)) { byte[] tmp = new byte[i - start]; System.arraycopy(str, start, tmp, 0, tmp.length); list.add(tmp); } return list.toArray(new byte[list.size()][]); } }