diff --git a/.classpath b/.classpath deleted file mode 100644 index d58ab93..0000000 --- a/.classpath +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.project b/.project deleted file mode 100644 index 81ca3d1..0000000 --- a/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - utility - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 8626026..0000000 --- a/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,5 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.compliance=1.5 -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.source=1.5 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index 14b697b..0000000 --- a/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/all/pom.xml b/all/pom.xml new file mode 100644 index 0000000..b2c5063 --- /dev/null +++ b/all/pom.xml @@ -0,0 +1,36 @@ + + + + utility + com.utility + 0.0.1-SNAPSHOT + + 4.0.0 + + all + + + + com.utility + result + 0.0.1-SNAPSHOT + + + com.utility + core + 0.0.1-SNAPSHOT + + + com.utility + convert + 0.0.1-SNAPSHOT + + + com.utility + system + 0.0.1-SNAPSHOT + + + \ No newline at end of file diff --git a/bean/pom.xml b/bean/pom.xml new file mode 100644 index 0000000..9fb9a1e --- /dev/null +++ b/bean/pom.xml @@ -0,0 +1,15 @@ + + + + utility + com.utility + 0.0.1-SNAPSHOT + + 4.0.0 + + bean + + + \ No newline at end of file diff --git a/codec/pom.xml b/codec/pom.xml new file mode 100644 index 0000000..5336f7c --- /dev/null +++ b/codec/pom.xml @@ -0,0 +1,21 @@ + + + + utility + com.utility + 0.0.1-SNAPSHOT + + 4.0.0 + + codec + + + + commons-codec + commons-codec + 1.13 + + + \ No newline at end of file diff --git a/codec/src/main/java/com/utils/codec/BCD.java b/codec/src/main/java/com/utils/codec/BCD.java new file mode 100644 index 0000000..60126fe --- /dev/null +++ b/codec/src/main/java/com/utils/codec/BCD.java @@ -0,0 +1,4 @@ +package com.utils.codec; + +public class BCD { +} diff --git a/codec/src/main/java/com/utils/codec/Base32.java b/codec/src/main/java/com/utils/codec/Base32.java new file mode 100644 index 0000000..bd68516 --- /dev/null +++ b/codec/src/main/java/com/utils/codec/Base32.java @@ -0,0 +1,176 @@ +//package com.utils.codec; +// +//import java.nio.charset.Charset; +// +//public class Base32 { +// +// private Base32() {} +// +// private static final String base32Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; +// private static final int[] base32Lookup = {// +// 0xFF, 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, // '0', '1', '2', '3', '4', '5', '6', '7' +// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // '8', '9', ':', ';', '<', '=', '>', '?' +// 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G' +// 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, // 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O' +// 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, // 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W' +// 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 'X', 'Y', 'Z', '[', '\', ']', '^', '_' +// 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g' +// 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, // 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o' +// 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, // 'p', 'q', 'r', 's', 't', 'u', 'v', 'w' +// 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // 'x', 'y', 'z', '{', '|', '}', '~', 'DEL' +// }; +// +// //----------------------------------------------------------------------------------------- encode +// /** +// * 编码 +// * @param bytes 数据 +// * @return base32 +// */ +// public static String encode(final byte[] bytes) { +// int i = 0, index = 0, digit = 0; +// int currByte, nextByte; +// StringBuilder base32 = new StringBuilder((bytes.length + 7) * 8 / 5); +// +// while (i < bytes.length) { +// currByte = (bytes[i] >= 0) ? bytes[i] : (bytes[i] + 256); // unsign +// +// /* Is the current digit going to span a byte boundary? */ +// if (index > 3) { +// if ((i + 1) < bytes.length) { +// nextByte = (bytes[i + 1] >= 0) ? bytes[i + 1] : (bytes[i + 1] + 256); +// } else { +// nextByte = 0; +// } +// +// digit = currByte & (0xFF >> index); +// index = (index + 5) % 8; +// digit <<= index; +// digit |= nextByte >> (8 - index); +// i++; +// } else { +// digit = (currByte >> (8 - (index + 5))) & 0x1F; +// index = (index + 5) % 8; +// if (index == 0) { +// i++; +// } +// } +// base32.append(base32Chars.charAt(digit)); +// } +// +// return base32.toString(); +// } +// +// /** +// * base32编码 +// * +// * @param source 被编码的base32字符串 +// * @return 被加密后的字符串 +// */ +// public static String encode(String source) { +// return encode(source, CharEncoding.UTF_8); +// } +// +// /** +// * base32编码 +// * +// * @param source 被编码的base32字符串 +// * @param charset 字符集 +// * @return 被加密后的字符串 +// */ +// public static String encode(String source, String charset) { +// return encode(StrUtil.bytes(source, charset)); +// } +// +// /** +// * base32编码 +// * +// * @param source 被编码的base32字符串 +// * @param charset 字符集 +// * @return 被加密后的字符串 +// */ +// public static String encode(String source, Charset charset) { +// return encode(StrUtil.bytes(source, charset)); +// } +// +// //----------------------------------------------------------------------------------------- decode +// /** +// * 解码 +// * @param base32 base32编码 +// * @return 数据 +// */ +// public static byte[] decode(final String base32) { +// int i, index, lookup, offset, digit; +// byte[] bytes = new byte[base32.length() * 5 / 8]; +// +// for (i = 0, index = 0, offset = 0; i < base32.length(); i++) { +// lookup = base32.charAt(i) - '0'; +// +// /* Skip chars outside the lookup table */ +// if (lookup < 0 || lookup >= base32Lookup.length) { +// continue; +// } +// +// digit = base32Lookup[lookup]; +// +// /* If this digit is not in the table, ignore it */ +// if (digit == 0xFF) { +// continue; +// } +// +// if (index <= 3) { +// index = (index + 5) % 8; +// if (index == 0) { +// bytes[offset] |= digit; +// offset++; +// if (offset >= bytes.length) { +// break; +// } +// } else { +// bytes[offset] |= digit << (8 - index); +// } +// } else { +// index = (index + 5) % 8; +// bytes[offset] |= (digit >>> index); +// offset++; +// +// if (offset >= bytes.length) { +// break; +// } +// bytes[offset] |= digit << (8 - index); +// } +// } +// return bytes; +// } +// +// /** +// * base32解码 +// * +// * @param source 被解码的base32字符串 +// * @return 被加密后的字符串 +// */ +// public static String decodeStr(String source) { +// return decodeStr(source, CharEncoding.UTF_8); +// } +// +// /** +// * base32解码 +// * +// * @param source 被解码的base32字符串 +// * @param charset 字符集 +// * @return 被加密后的字符串 +// */ +// public static String decodeStr(String source, String charset) { +// return StrUtil.str(decode(source), charset); +// } +// +// /** +// * base32解码 +// * +// * @param source 被解码的base32字符串 +// * @param charset 字符集 +// * @return 被加密后的字符串 +// */ +// public static String decodeStr(String source, Charset charset) { +// return StrUtil.str(decode(source), charset); +// } +//} diff --git a/codec/src/main/java/com/utils/codec/Base62.java b/codec/src/main/java/com/utils/codec/Base62.java new file mode 100644 index 0000000..b939003 --- /dev/null +++ b/codec/src/main/java/com/utils/codec/Base62.java @@ -0,0 +1,4 @@ +package com.utils.codec; + +public class Base62 { +} diff --git a/codec/src/main/java/com/utils/codec/Base64.java b/codec/src/main/java/com/utils/codec/Base64.java new file mode 100644 index 0000000..4456b9f --- /dev/null +++ b/codec/src/main/java/com/utils/codec/Base64.java @@ -0,0 +1,4 @@ +package com.utils.codec; + +public class Base64 { +} diff --git a/codec/src/main/java/com/utils/codec/Caesar.java b/codec/src/main/java/com/utils/codec/Caesar.java new file mode 100644 index 0000000..e149f35 --- /dev/null +++ b/codec/src/main/java/com/utils/codec/Caesar.java @@ -0,0 +1,4 @@ +package com.utils.codec; + +public class Caesar { +} diff --git a/codec/src/main/java/com/utils/codec/CharEncoding.java b/codec/src/main/java/com/utils/codec/CharEncoding.java new file mode 100644 index 0000000..d2130bd --- /dev/null +++ b/codec/src/main/java/com/utils/codec/CharEncoding.java @@ -0,0 +1,20 @@ +package com.utils.codec; + +/** + * 编码方式 + */ +public class CharEncoding { + + public static final String ISO_8859_1 = "ISO-8859-1"; + + public static final String US_ASCII = "US-ASCII"; + + public static final String UTF_16 = "UTF-16"; + + public static final String UTF_16BE = "UTF-16BE"; + + public static final String UTF_16LE = "UTF-16LE"; + + public static final String UTF_8 = "UTF-8"; + +} diff --git a/codec/src/main/java/com/utils/codec/Hex.java b/codec/src/main/java/com/utils/codec/Hex.java new file mode 100644 index 0000000..7234ffe --- /dev/null +++ b/codec/src/main/java/com/utils/codec/Hex.java @@ -0,0 +1,4 @@ +package com.utils.codec; + +public class Hex { +} diff --git a/codec/src/main/java/com/utils/codec/Morse.java b/codec/src/main/java/com/utils/codec/Morse.java new file mode 100644 index 0000000..ac80803 --- /dev/null +++ b/codec/src/main/java/com/utils/codec/Morse.java @@ -0,0 +1,4 @@ +package com.utils.codec; + +public class Morse { +} diff --git a/codec/src/main/java/com/utils/codec/Rot.java b/codec/src/main/java/com/utils/codec/Rot.java new file mode 100644 index 0000000..2f2485b --- /dev/null +++ b/codec/src/main/java/com/utils/codec/Rot.java @@ -0,0 +1,4 @@ +package com.utils.codec; + +public class Rot { +} diff --git a/collection/pom.xml b/collection/pom.xml new file mode 100644 index 0000000..7f9239b --- /dev/null +++ b/collection/pom.xml @@ -0,0 +1,15 @@ + + + + utility + com.utility + 0.0.1-SNAPSHOT + + 4.0.0 + + collection + + + \ No newline at end of file diff --git a/convert/pom.xml b/convert/pom.xml new file mode 100644 index 0000000..df091ef --- /dev/null +++ b/convert/pom.xml @@ -0,0 +1,21 @@ + + + + utility + com.utility + 0.0.1-SNAPSHOT + + 4.0.0 + + convert + + + + com.utility + core + 0.0.1-SNAPSHOT + + + \ No newline at end of file diff --git a/convert/src/main/java/com/utils/Converter.java b/convert/src/main/java/com/utils/Converter.java new file mode 100644 index 0000000..ab6ad96 --- /dev/null +++ b/convert/src/main/java/com/utils/Converter.java @@ -0,0 +1,17 @@ +package com.utils; + +/** + * 类型转换接口 + * @param + * @param + */ +public interface Converter { + + /** + * 类型转换接口 + * @param source + * @return + */ + T convert(S source); + +} diff --git a/convert/src/main/java/com/utils/converter/StringToUUIDConverter.java b/convert/src/main/java/com/utils/converter/StringToUUIDConverter.java new file mode 100644 index 0000000..99b2545 --- /dev/null +++ b/convert/src/main/java/com/utils/converter/StringToUUIDConverter.java @@ -0,0 +1,16 @@ +package com.utils.converter; + +import com.utils.Converter; +import com.utils.StringUtils; + +import java.util.UUID; + +final class StringToUUIDConverter implements Converter { + @Override + public UUID convert(String source) { + if (StringUtils.hasLength(source)) { + return UUID.fromString(source.trim()); + } + return null; + } +} diff --git a/core/pom.xml b/core/pom.xml new file mode 100644 index 0000000..e680122 --- /dev/null +++ b/core/pom.xml @@ -0,0 +1,15 @@ + + + + utility + com.utility + 0.0.1-SNAPSHOT + + 4.0.0 + + core + + + \ No newline at end of file diff --git a/core/src/main/java/com/utils/ArrayUtils.java b/core/src/main/java/com/utils/ArrayUtils.java new file mode 100644 index 0000000..166684e --- /dev/null +++ b/core/src/main/java/com/utils/ArrayUtils.java @@ -0,0 +1,8 @@ +package com.utils; + +public class ArrayUtils { + + public static boolean isArray(Object obj) { + return (obj != null && obj.getClass().isArray()); + } +} diff --git a/core/src/main/java/com/utils/AssertUtils.java b/core/src/main/java/com/utils/AssertUtils.java new file mode 100644 index 0000000..0f6eb1f --- /dev/null +++ b/core/src/main/java/com/utils/AssertUtils.java @@ -0,0 +1,191 @@ +package com.utils; + +import java.util.Collection; +import java.util.Map; + +/** + * 断言工具类 + */ +public class AssertUtils { + /** + * 断言为true + * @param expression + * @param message + */ + public static void isTrue(boolean expression, String message) { + if (!expression) { + throw new IllegalArgumentException(message); + } + } + + /** + * + * @param expression + */ + public static void isTrue(boolean expression) { + isTrue(expression, "[Assertion failed] - this expression must be true"); + } + + /** + * + * @param object + * @param message + */ + public static void isNull(Object object, String message) { + if (object != null) { + throw new IllegalArgumentException(message); + } + } + + /** + * + * @param object + */ + public static void isNull(Object object) { + isNull(object, "[Assertion failed] - the object argument must be null"); + } + + /** + * + * @param object + * @param message + */ + public static void notNull(Object object, String message) { + if (object == null) { + throw new IllegalArgumentException(message); + } + } + + /** + * + * @param object + */ + public static void notNull(Object object) { + notNull(object, "[Assertion failed] - this argument is required; it must not be null"); + } + + /** + * + * @param text + * @param message + */ + public static void hasLength(String text, String message) { + if (!StringUtils.hasLength(text)) { + throw new IllegalArgumentException(message); + } + } + + + public static void hasLength(String text) { + hasLength(text, + "[Assertion failed] - this String argument must have length; it must not be null or empty"); + } + + public static void hasText(String text, String message) { + if (!StringUtils.hasText(text)) { + throw new IllegalArgumentException(message); + } + } + + public static void hasText(String text) { + hasText(text, + "[Assertion failed] - this String argument must have text; it must not be null, empty, or blank"); + } + + + public static void doesNotContain(String textToSearch, String substring, String message) { + if (StringUtils.hasLength(textToSearch) && StringUtils.hasLength(substring) && + textToSearch.contains(substring)) { + throw new IllegalArgumentException(message); + } + } + + public static void doesNotContain(String textToSearch, String substring) { + doesNotContain(textToSearch, substring, + "[Assertion failed] - this String argument must not contain the substring [" + substring + "]"); + } + + + + public static void notEmpty(Object[] array, String message) { + if (ObjectUtils.isEmpty(array)) { + throw new IllegalArgumentException(message); + } + } + + public static void notEmpty(Object[] array) { + notEmpty(array, "[Assertion failed] - this array must not be empty: it must contain at least 1 element"); + } + + + public static void noNullElements(Object[] array, String message) { + if (array != null) { + for (Object element : array) { + if (element == null) { + throw new IllegalArgumentException(message); + } + } + } + } + + public static void noNullElements(Object[] array) { + noNullElements(array, "[Assertion failed] - this array must not contain any null elements"); + } + + public static void notEmpty(Collection collection, String message) { + if (CollectionUtils.isEmpty(collection)) { + throw new IllegalArgumentException(message); + } + } + + + public static void notEmpty(Collection collection) { + notEmpty(collection, + "[Assertion failed] - this collection must not be empty: it must contain at least 1 element"); + } + + public static void notEmpty(Map map, String message) { + if (CollectionUtils.isEmpty(map)) { + throw new IllegalArgumentException(message); + } + } + + public static void notEmpty(Map map) { + notEmpty(map, "[Assertion failed] - this map must not be empty; it must contain at least one entry"); + } + + public static void isInstanceOf(Class clazz, Object obj) { + isInstanceOf(clazz, obj, ""); + } + + public static void isInstanceOf(Class type, Object obj, String message) { + notNull(type, "Type to check against must not be null"); + if (!type.isInstance(obj)) { + throw new IllegalArgumentException( + (StringUtils.hasLength(message) ? message + " " : "") + + "Object of class [" + (obj != null ? obj.getClass().getName() : "null") + + "] must be an instance of " + type); + } + } + + public static void isAssignable(Class superType, Class subType) { + isAssignable(superType, subType, ""); + } + + public static void isAssignable(Class superType, Class subType, String message) { + notNull(superType, "Type to check against must not be null"); + if (subType == null || !superType.isAssignableFrom(subType)) { + throw new IllegalArgumentException(message + subType + " is not assignable to " + superType); + } + } + + public static void state(boolean expression, String message) { + if (!expression) { + throw new IllegalStateException(message); + } + } + public static void state(boolean expression) { + state(expression, "[Assertion failed] - this state invariant must be true"); + } + +} diff --git a/core/src/main/java/com/utils/BooleanUtils.java b/core/src/main/java/com/utils/BooleanUtils.java new file mode 100644 index 0000000..f153a49 --- /dev/null +++ b/core/src/main/java/com/utils/BooleanUtils.java @@ -0,0 +1,7 @@ +package com.utils; + +/** + * Boolean类型工具类 + */ +public class BooleanUtils { +} diff --git a/core/src/main/java/com/utils/CharUtils.java b/core/src/main/java/com/utils/CharUtils.java new file mode 100644 index 0000000..238ed6f --- /dev/null +++ b/core/src/main/java/com/utils/CharUtils.java @@ -0,0 +1,24 @@ +package com.utils; + +/** + * 字符工具类 + */ +public class CharUtils { + + /** + * 比较两个字符是否相同 + * + * @param c1 字符1 + * @param c2 字符2 + * @param ignoreCase 是否忽略大小写 + * @return 是否相同 + * @since 4.0.3 + */ + public static boolean equals(char c1, char c2, boolean ignoreCase) { + if (ignoreCase) { + return Character.toLowerCase(c1) == Character.toLowerCase(c2); + } + return c1 == c2; + } + +} diff --git a/core/src/main/java/com/utils/ClassUtils.java b/core/src/main/java/com/utils/ClassUtils.java new file mode 100644 index 0000000..f26fdf7 --- /dev/null +++ b/core/src/main/java/com/utils/ClassUtils.java @@ -0,0 +1,4 @@ +package com.utils; + +public class ClassUtils { +} diff --git a/core/src/main/java/com/utils/CollectionUtils.java b/core/src/main/java/com/utils/CollectionUtils.java new file mode 100644 index 0000000..af73acf --- /dev/null +++ b/core/src/main/java/com/utils/CollectionUtils.java @@ -0,0 +1,15 @@ +package com.utils; + +import java.util.Collection; +import java.util.Map; + +public class CollectionUtils { + + public static boolean isEmpty(Collection collection) { + return (collection == null || collection.isEmpty()); + } + + public static boolean isEmpty(Map map) { + return (map == null || map.isEmpty()); + } +} diff --git a/core/src/main/java/com/utils/ExceptionUtils.java b/core/src/main/java/com/utils/ExceptionUtils.java new file mode 100644 index 0000000..ec114c2 --- /dev/null +++ b/core/src/main/java/com/utils/ExceptionUtils.java @@ -0,0 +1,36 @@ +package com.utils; + +/** + * 异常工具类 + */ +public class ExceptionUtils { + /** + * + * @param ex + * @return + */ + public static boolean isCheckedException(Throwable ex) { + return !(ex instanceof RuntimeException || ex instanceof Error); + } + + /** + * 判断是否是特定的异常类 + * @param ex + * @param declaredExceptions + * @return + */ + public static boolean isCompatibleWithThrowsClause(Throwable ex, Class... declaredExceptions) { + if (!isCheckedException(ex)) { + return true; + } + if (declaredExceptions != null) { + for (Class declaredException : declaredExceptions) { + if (declaredException.isInstance(ex)) { + return true; + } + } + } + return false; + } + +} diff --git a/core/src/main/java/com/utils/NumberUtil.java b/core/src/main/java/com/utils/NumberUtil.java new file mode 100644 index 0000000..8fe9dc3 --- /dev/null +++ b/core/src/main/java/com/utils/NumberUtil.java @@ -0,0 +1,7 @@ +package com.utils; + +/** + * 数字工具类 + */ +public class NumberUtil { +} diff --git a/core/src/main/java/com/utils/ObjectUtils.java b/core/src/main/java/com/utils/ObjectUtils.java new file mode 100644 index 0000000..46907b9 --- /dev/null +++ b/core/src/main/java/com/utils/ObjectUtils.java @@ -0,0 +1,31 @@ +package com.utils; + +import java.util.Objects; + +/** + * 对象工具类 + */ +public class ObjectUtils { + + /** + * 判断对象为空 + * @param obj + * @return + */ + public boolean isNull(Object obj){ + return Objects.isNull(obj); + } + + /** + * 判断对象非空 + * @param obj + * @return + */ + public boolean nonNull(Object obj){ + return Objects.nonNull(obj); + } + + public static boolean isEmpty(Object[] array) { + return (array == null || array.length == 0); + } +} diff --git a/core/src/main/java/com/utils/StringUtils.java b/core/src/main/java/com/utils/StringUtils.java new file mode 100644 index 0000000..f991767 --- /dev/null +++ b/core/src/main/java/com/utils/StringUtils.java @@ -0,0 +1,229 @@ +package com.utils; + +/** + * 字符串工具类 + */ +public class StringUtils { + + /** + * 字符串为空 + * @param s + * @return + */ + public static boolean isEmpty(CharSequence s) { + return s == null || s.length() == 0; + } + + public static boolean hasLength(String str) { + return hasLength((CharSequence) str); + } + + public static boolean hasLength(CharSequence str) { + return (str != null && str.length() > 0); + } + + public static boolean hasText(String str) { + return hasText((CharSequence) str); + } + + public static boolean hasText(CharSequence str) { + if (!hasLength(str)) { + return false; + } + int strLen = str.length(); + for (int i = 0; i < strLen; i++) { + if (!Character.isWhitespace(str.charAt(i))) { + return true; + } + } + return false; + } + + + public static boolean containsWhitespace(CharSequence str) { + if (!hasLength(str)) { + return false; + } + int strLen = str.length(); + for (int i = 0; i < strLen; i++) { + if (Character.isWhitespace(str.charAt(i))) { + return true; + } + } + return false; + } + + public static boolean containsWhitespace(String str) { + return containsWhitespace((CharSequence) str); + } + + public static String trimWhitespace(String str) { + if (!hasLength(str)) { + return str; + } + StringBuilder sb = new StringBuilder(str); + while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) { + sb.deleteCharAt(0); + } + while (sb.length() > 0 && Character.isWhitespace(sb.charAt(sb.length() - 1))) { + sb.deleteCharAt(sb.length() - 1); + } + return sb.toString(); + } + + public static String trimAllWhitespace(String str) { + if (!hasLength(str)) { + return str; + } + StringBuilder sb = new StringBuilder(str); + int index = 0; + while (sb.length() > index) { + if (Character.isWhitespace(sb.charAt(index))) { + sb.deleteCharAt(index); + } + else { + index++; + } + } + return sb.toString(); + } + + public static String trimLeadingWhitespace(String str) { + if (!hasLength(str)) { + return str; + } + StringBuilder sb = new StringBuilder(str); + while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) { + sb.deleteCharAt(0); + } + return sb.toString(); + } + + + public static String trimTrailingWhitespace(String str) { + if (!hasLength(str)) { + return str; + } + StringBuilder sb = new StringBuilder(str); + while (sb.length() > 0 && Character.isWhitespace(sb.charAt(sb.length() - 1))) { + sb.deleteCharAt(sb.length() - 1); + } + return sb.toString(); + } + + + public static String trimLeadingCharacter(String str, char leadingCharacter) { + if (!hasLength(str)) { + return str; + } + StringBuilder sb = new StringBuilder(str); + while (sb.length() > 0 && sb.charAt(0) == leadingCharacter) { + sb.deleteCharAt(0); + } + return sb.toString(); + } + + public static String trimTrailingCharacter(String str, char trailingCharacter) { + if (!hasLength(str)) { + return str; + } + StringBuilder sb = new StringBuilder(str); + while (sb.length() > 0 && sb.charAt(sb.length() - 1) == trailingCharacter) { + sb.deleteCharAt(sb.length() - 1); + } + return sb.toString(); + } + + public static boolean startsWithIgnoreCase(String str, String prefix) { + if (str == null || prefix == null) { + return false; + } + if (str.startsWith(prefix)) { + return true; + } + if (str.length() < prefix.length()) { + return false; + } + String lcStr = str.substring(0, prefix.length()).toLowerCase(); + String lcPrefix = prefix.toLowerCase(); + return lcStr.equals(lcPrefix); + } + + public static boolean endsWithIgnoreCase(String str, String suffix) { + if (str == null || suffix == null) { + return false; + } + if (str.endsWith(suffix)) { + return true; + } + if (str.length() < suffix.length()) { + return false; + } + + String lcStr = str.substring(str.length() - suffix.length()).toLowerCase(); + String lcSuffix = suffix.toLowerCase(); + return lcStr.equals(lcSuffix); + } + + public static boolean substringMatch(CharSequence str, int index, CharSequence substring) { + for (int j = 0; j < substring.length(); j++) { + int i = index + j; + if (i >= str.length() || str.charAt(i) != substring.charAt(j)) { + return false; + } + } + return true; + } + + public static int countOccurrencesOf(String str, String sub) { + if (str == null || sub == null || str.length() == 0 || sub.length() == 0) { + return 0; + } + int count = 0; + int pos = 0; + int idx; + while ((idx = str.indexOf(sub, pos)) != -1) { + ++count; + pos = idx + sub.length(); + } + return count; + } + + public static String replace(String inString, String oldPattern, String newPattern) { + if (!hasLength(inString) || !hasLength(oldPattern) || newPattern == null) { + return inString; + } + StringBuilder sb = new StringBuilder(); + int pos = 0; // our position in the old string + int index = inString.indexOf(oldPattern); + // the index of an occurrence we've found, or -1 + int patLen = oldPattern.length(); + while (index >= 0) { + sb.append(inString.substring(pos, index)); + sb.append(newPattern); + pos = index + patLen; + index = inString.indexOf(oldPattern, pos); + } + sb.append(inString.substring(pos)); + // remember to append any characters to the right of a match + return sb.toString(); + } + + public static String delete(String inString, String pattern) { + return replace(inString, pattern, ""); + } + + public static String deleteAny(String inString, String charsToDelete) { + if (!hasLength(inString) || !hasLength(charsToDelete)) { + return inString; + } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < inString.length(); i++) { + char c = inString.charAt(i); + if (charsToDelete.indexOf(c) == -1) { + sb.append(c); + } + } + return sb.toString(); + } +} diff --git a/core/src/main/java/com/utils/TypeUtils.java b/core/src/main/java/com/utils/TypeUtils.java new file mode 100644 index 0000000..d59207a --- /dev/null +++ b/core/src/main/java/com/utils/TypeUtils.java @@ -0,0 +1,4 @@ +package com.utils; + +public class TypeUtils { +} diff --git a/crypto/pom.xml b/crypto/pom.xml new file mode 100644 index 0000000..21488e5 --- /dev/null +++ b/crypto/pom.xml @@ -0,0 +1,15 @@ + + + + utility + com.utility + 0.0.1-SNAPSHOT + + 4.0.0 + + crypto + + + \ No newline at end of file diff --git a/csv/pom.xml b/csv/pom.xml new file mode 100644 index 0000000..6b9505b --- /dev/null +++ b/csv/pom.xml @@ -0,0 +1,15 @@ + + + + utility + com.utility + 0.0.1-SNAPSHOT + + 4.0.0 + + csv + + + \ No newline at end of file diff --git a/io/pom.xml b/io/pom.xml new file mode 100644 index 0000000..13c5b2d --- /dev/null +++ b/io/pom.xml @@ -0,0 +1,15 @@ + + + + utility + com.utility + 0.0.1-SNAPSHOT + + 4.0.0 + + io + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 614b331..d98651e 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,38 @@ - - 4.0.0 - com.zero - utility - 0.0.1-SNAPSHOT + + 4.0.0 + com.utility + utility + pom + 0.0.1-SNAPSHOT + + result + test + core + convert + bean + collection + io + codec + thread + system + all + csv + crypto + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5 + + 1.8 + 1.8 + UTF-8 + + + + \ No newline at end of file diff --git a/result/pom.xml b/result/pom.xml new file mode 100644 index 0000000..d0da872 --- /dev/null +++ b/result/pom.xml @@ -0,0 +1,15 @@ + + + + utility + com.utility + 0.0.1-SNAPSHOT + + 4.0.0 + + result + + + \ No newline at end of file diff --git a/result/src/main/java/com/utils/ResultHelper.java b/result/src/main/java/com/utils/ResultHelper.java new file mode 100644 index 0000000..3528fd7 --- /dev/null +++ b/result/src/main/java/com/utils/ResultHelper.java @@ -0,0 +1,27 @@ +package com.utils; + +/** + * 返回结果静态工具类 + */ +public class ResultHelper { + /** + * 返回成功结果 + * @param data + * @param + * @return + */ + public static ResultT success(T data) { + return new ResultT(data); + } + + /** + * 返回失败结果 + * @param code + * @param message + * @param + * @return + */ + public static ResultT fail(String code,String message) { + return new ResultT(code,message); + } +} diff --git a/result/src/main/java/com/utils/ResultT.java b/result/src/main/java/com/utils/ResultT.java new file mode 100644 index 0000000..5705b98 --- /dev/null +++ b/result/src/main/java/com/utils/ResultT.java @@ -0,0 +1,75 @@ +package com.utils; + +/** + * 通用的结果返回 + * + * @param + */ +public class ResultT { + + private Boolean success; + + private String code; + + private String message; + + private T data; + + private final static String SUCCESS_CODE = "0"; + private final static String SUCCESS_MESSAGE = "成功"; + + public ResultT(String code, String message) { + this.success = false; + this.code = code; + this.message = message; + } + + public ResultT(T data) { + this.success = true; + this.data = data; + this.code = SUCCESS_CODE; + this.message = SUCCESS_MESSAGE; + } + + public Boolean getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + @Override + public String toString() { + return "ResultT{" + + "success=" + success + + ", code='" + code + '\'' + + ", message='" + message + '\'' + + ", data=" + data + + '}'; + } +} diff --git a/src/main/java/com/zero/utils/AnnotationAttributes.java b/src/main/java/com/zero/utils/AnnotationAttributes.java deleted file mode 100644 index 774095c..0000000 --- a/src/main/java/com/zero/utils/AnnotationAttributes.java +++ /dev/null @@ -1,116 +0,0 @@ -/** - * Copyright (c) 1997-2013, www.tinygroup.org (luo_guo@icloud.com). - * - * Licensed under the GPL, Version 3.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.gnu.org/licenses/gpl.html - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.zero.utils; - -import java.util.LinkedHashMap; -import java.util.Map; - -public class AnnotationAttributes extends LinkedHashMap { - - /** - * Create a new, empty {@link AnnotationAttributes} instance. - */ - public AnnotationAttributes() { - } - - /** - * Create a new, empty {@link AnnotationAttributes} instance with the given initial - * capacity to optimize performance. - * @param initialCapacity initial size of the underlying map - */ - public AnnotationAttributes(int initialCapacity) { - super(initialCapacity); - } - - /** - * Create a new {@link AnnotationAttributes} instance, wrapping the provided map - * and all its key/value pairs. - * @param map original source of annotation attribute key/value pairs to wrap - * @see #fromMap(Map) - */ - public AnnotationAttributes(Map map) { - super(map); - } - - /** - * Return an {@link AnnotationAttributes} instance based on the given map; if the map - * is already an {@code AnnotationAttributes} instance, it is casted and returned - * immediately without creating any new instance; otherwise create a new instance by - * wrapping the map with the {@link #AnnotationAttributes(Map)} constructor. - * @param map original source of annotation attribute key/value pairs - */ - public static AnnotationAttributes fromMap(Map map) { - if (map == null) { - return null; - } - - if (map instanceof AnnotationAttributes) { - return (AnnotationAttributes) map; - } - - return new AnnotationAttributes(map); - } - - public String getString(String attributeName) { - return doGet(attributeName, String.class); - } - - public String[] getStringArray(String attributeName) { - return doGet(attributeName, String[].class); - } - - public boolean getBoolean(String attributeName) { - return doGet(attributeName, Boolean.class); - } - - @SuppressWarnings("unchecked") - public N getNumber(String attributeName) { - return (N) doGet(attributeName, Integer.class); - } - - @SuppressWarnings("unchecked") - public > E getEnum(String attributeName) { - return (E) doGet(attributeName, Enum.class); - } - - @SuppressWarnings("unchecked") - public Class getClass(String attributeName) { - return (Class)doGet(attributeName, Class.class); - } - - public Class[] getClassArray(String attributeName) { - return doGet(attributeName, Class[].class); - } - - public AnnotationAttributes getAnnotation(String attributeName) { - return doGet(attributeName, AnnotationAttributes.class); - } - - public AnnotationAttributes[] getAnnotationArray(String attributeName) { - return doGet(attributeName, AnnotationAttributes[].class); - } - - @SuppressWarnings("unchecked") - private T doGet(String attributeName, Class expectedType) { - Assert.hasText(attributeName, "attributeName must not be null or empty"); - Object value = this.get(attributeName); - Assert.assertNotNull(value, String.format("Attribute '%s' not found", attributeName)); - Assert.isAssignable(expectedType, value.getClass(), - String.format("Attribute '%s' is of type [%s], but [%s] was expected. Cause: ", - attributeName, value.getClass().getSimpleName(), expectedType.getSimpleName())); - return (T) value; - } -} \ No newline at end of file diff --git a/src/main/java/com/zero/utils/AnnotationUtils.java b/src/main/java/com/zero/utils/AnnotationUtils.java deleted file mode 100644 index 0e630fe..0000000 --- a/src/main/java/com/zero/utils/AnnotationUtils.java +++ /dev/null @@ -1,473 +0,0 @@ -/** - * Copyright (c) 1997-2013, www.tinygroup.org (luo_guo@icloud.com). - * - * Licensed under the GPL, Version 3.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.gnu.org/licenses/gpl.html - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.zero.utils; - -import java.lang.annotation.Annotation; -import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.Map; -import java.util.WeakHashMap; - - -/** - * General utility methods for working with annotations, handling bridge methods (which the compiler - * generates for generic declarations) as well as super methods (for optional "annotation inheritance"). - * Note that none of this is provided by the JDK's introspection facilities themselves. - * - *

As a general rule for runtime-retained annotations (e.g. for transaction control, authorization or service - * exposure), always use the lookup methods on this class (e.g., {@link #findAnnotation(Method, Class)}, {@link - * #getAnnotation(Method, Class)}, and {@link #getAnnotations(Method)}) instead of the plain annotation lookup - * methods in the JDK. You can still explicitly choose between lookup on the given class level only ({@link - * #getAnnotation(Method, Class)}) and lookup in the entire inheritance hierarchy of the given method ({@link - * #findAnnotation(Method, Class)}). - * - * @author Rob Harrop - * @author Juergen Hoeller - * @author Sam Brannen - * @author Mark Fisher - * @author Chris Beams - * @since 2.0 - * @see java.lang.reflect.Method#getAnnotations() - * @see java.lang.reflect.Method#getAnnotation(Class) - */ -public abstract class AnnotationUtils { - - /** The attribute name for annotations with a single element */ - static final String VALUE = "value"; - - private static final Map, Boolean> annotatedInterfaceCache = new WeakHashMap, Boolean>(); - - - /** - * Get a single {@link Annotation} of {@code annotationType} from the supplied - * Method, Constructor or Field. Meta-annotations will be searched if the annotation - * is not declared locally on the supplied element. - * @param ae the Method, Constructor or Field from which to get the annotation - * @param annotationType the annotation class to look for, both locally and as a meta-annotation - * @return the matching annotation or {@code null} if not found - * @since 3.1 - */ - public static T getAnnotation(AnnotatedElement ae, Class annotationType) { - T ann = ae.getAnnotation(annotationType); - if (ann == null) { - for (Annotation metaAnn : ae.getAnnotations()) { - ann = metaAnn.annotationType().getAnnotation(annotationType); - if (ann != null) { - break; - } - } - } - return ann; - } - - /** - * Get all {@link Annotation Annotations} from the supplied {@link Method}. - *

Correctly handles bridge {@link Method Methods} generated by the compiler. - * @param method the method to look for annotations on - * @return the annotations found - * @see org.springframework.core.BridgeMethodResolver#findBridgedMethod(Method) - */ - public static Annotation[] getAnnotations(Method method) { - return BridgeMethodResolver.findBridgedMethod(method).getAnnotations(); - } - - /** - * Get a single {@link Annotation} of annotationType from the supplied {@link Method}. - *

Correctly handles bridge {@link Method Methods} generated by the compiler. - * @param method the method to look for annotations on - * @param annotationType the annotation class to look for - * @return the annotations found - * @see org.springframework.core.BridgeMethodResolver#findBridgedMethod(Method) - */ - public static A getAnnotation(Method method, Class annotationType) { - Method resolvedMethod = BridgeMethodResolver.findBridgedMethod(method); - A ann = resolvedMethod.getAnnotation(annotationType); - if (ann == null) { - for (Annotation metaAnn : resolvedMethod.getAnnotations()) { - ann = metaAnn.annotationType().getAnnotation(annotationType); - if (ann != null) { - break; - } - } - } - return ann; - } - - /** - * Get a single {@link Annotation} of annotationType from the supplied {@link Method}, - * traversing its super methods if no annotation can be found on the given method itself. - *

Annotations on methods are not inherited by default, so we need to handle this explicitly. - * @param method the method to look for annotations on - * @param annotationType the annotation class to look for - * @return the annotation found, or null if none found - */ - public static A findAnnotation(Method method, Class annotationType) { - A annotation = getAnnotation(method, annotationType); - Class cl = method.getDeclaringClass(); - if (annotation == null) { - annotation = searchOnInterfaces(method, annotationType, cl.getInterfaces()); - } - while (annotation == null) { - cl = cl.getSuperclass(); - if (cl == null || cl == Object.class) { - break; - } - try { - Method equivalentMethod = cl.getDeclaredMethod(method.getName(), method.getParameterTypes()); - annotation = getAnnotation(equivalentMethod, annotationType); - if (annotation == null) { - annotation = searchOnInterfaces(method, annotationType, cl.getInterfaces()); - } - } - catch (NoSuchMethodException ex) { - // We're done... - } - } - return annotation; - } - - private static A searchOnInterfaces(Method method, Class annotationType, Class[] ifcs) { - A annotation = null; - for (Class iface : ifcs) { - if (isInterfaceWithAnnotatedMethods(iface)) { - try { - Method equivalentMethod = iface.getMethod(method.getName(), method.getParameterTypes()); - annotation = getAnnotation(equivalentMethod, annotationType); - } - catch (NoSuchMethodException ex) { - // Skip this interface - it doesn't have the method... - } - if (annotation != null) { - break; - } - } - } - return annotation; - } - - private static boolean isInterfaceWithAnnotatedMethods(Class iface) { - synchronized (annotatedInterfaceCache) { - Boolean flag = annotatedInterfaceCache.get(iface); - if (flag != null) { - return flag; - } - boolean found = false; - for (Method ifcMethod : iface.getMethods()) { - if (ifcMethod.getAnnotations().length > 0) { - found = true; - break; - } - } - annotatedInterfaceCache.put(iface, found); - return found; - } - } - - /** - * Find a single {@link Annotation} of annotationType from the supplied {@link Class}, - * traversing its interfaces and superclasses if no annotation can be found on the given class itself. - *

This method explicitly handles class-level annotations which are not declared as - * {@link java.lang.annotation.Inherited inherited} as well as annotations on interfaces. - *

The algorithm operates as follows: Searches for an annotation on the given class and returns - * it if found. Else searches all interfaces that the given class declares, returning the annotation - * from the first matching candidate, if any. Else proceeds with introspection of the superclass - * of the given class, checking the superclass itself; if no annotation found there, proceeds - * with the interfaces that the superclass declares. Recursing up through the entire superclass - * hierarchy if no match is found. - * @param clazz the class to look for annotations on - * @param annotationType the annotation class to look for - * @return the annotation found, or null if none found - */ - public static A findAnnotation(Class clazz, Class annotationType) { - Assert.assertNotNull(clazz, "Class must not be null"); - A annotation = clazz.getAnnotation(annotationType); - if (annotation != null) { - return annotation; - } - for (Class ifc : clazz.getInterfaces()) { - annotation = findAnnotation(ifc, annotationType); - if (annotation != null) { - return annotation; - } - } - if (!Annotation.class.isAssignableFrom(clazz)) { - for (Annotation ann : clazz.getAnnotations()) { - annotation = findAnnotation(ann.annotationType(), annotationType); - if (annotation != null) { - return annotation; - } - } - } - Class superClass = clazz.getSuperclass(); - if (superClass == null || superClass == Object.class) { - return null; - } - return findAnnotation(superClass, annotationType); - } - - /** - * Find the first {@link Class} in the inheritance hierarchy of the specified clazz - * (including the specified clazz itself) which declares an annotation for the - * specified annotationType, or null if not found. If the supplied - * clazz is null, null will be returned. - *

If the supplied clazz is an interface, only the interface itself will be checked; - * the inheritance hierarchy for interfaces will not be traversed. - *

The standard {@link Class} API does not provide a mechanism for determining which class - * in an inheritance hierarchy actually declares an {@link Annotation}, so we need to handle - * this explicitly. - * @param annotationType the Class object corresponding to the annotation type - * @param clazz the Class object corresponding to the class on which to check for the annotation, - * or null - * @return the first {@link Class} in the inheritance hierarchy of the specified clazz - * which declares an annotation for the specified annotationType, or null - * if not found - * @see Class#isAnnotationPresent(Class) - * @see Class#getDeclaredAnnotations() - */ - public static Class findAnnotationDeclaringClass(Class annotationType, Class clazz) { - Assert.assertNotNull(annotationType, "Annotation type must not be null"); - if (clazz == null || clazz.equals(Object.class)) { - return null; - } - return (isAnnotationDeclaredLocally(annotationType, clazz)) ? clazz : - findAnnotationDeclaringClass(annotationType, clazz.getSuperclass()); - } - - /** - * Determine whether an annotation for the specified annotationType is - * declared locally on the supplied clazz. The supplied {@link Class} - * may represent any type. - *

Note: This method does not determine if the annotation is - * {@link java.lang.annotation.Inherited inherited}. For greater clarity regarding inherited - * annotations, consider using {@link #isAnnotationInherited(Class, Class)} instead. - * @param annotationType the Class object corresponding to the annotation type - * @param clazz the Class object corresponding to the class on which to check for the annotation - * @return true if an annotation for the specified annotationType - * is declared locally on the supplied clazz - * @see Class#getDeclaredAnnotations() - * @see #isAnnotationInherited(Class, Class) - */ - public static boolean isAnnotationDeclaredLocally(Class annotationType, Class clazz) { - Assert.assertNotNull(annotationType, "Annotation type must not be null"); - Assert.assertNotNull(clazz, "Class must not be null"); - boolean declaredLocally = false; - for (Annotation annotation : Arrays.asList(clazz.getDeclaredAnnotations())) { - if (annotation.annotationType().equals(annotationType)) { - declaredLocally = true; - break; - } - } - return declaredLocally; - } - - /** - * Determine whether an annotation for the specified annotationType is present - * on the supplied clazz and is {@link java.lang.annotation.Inherited inherited} - * i.e., not declared locally for the class). - *

If the supplied clazz is an interface, only the interface itself will be checked. - * In accordance with standard meta-annotation semantics, the inheritance hierarchy for interfaces - * will not be traversed. See the {@link java.lang.annotation.Inherited JavaDoc} for the - * @Inherited meta-annotation for further details regarding annotation inheritance. - * @param annotationType the Class object corresponding to the annotation type - * @param clazz the Class object corresponding to the class on which to check for the annotation - * @return true if an annotation for the specified annotationType is present - * on the supplied clazz and is {@link java.lang.annotation.Inherited inherited} - * @see Class#isAnnotationPresent(Class) - * @see #isAnnotationDeclaredLocally(Class, Class) - */ - public static boolean isAnnotationInherited(Class annotationType, Class clazz) { - Assert.assertNotNull(annotationType, "Annotation type must not be null"); - Assert.assertNotNull(clazz, "Class must not be null"); - return (clazz.isAnnotationPresent(annotationType) && !isAnnotationDeclaredLocally(annotationType, clazz)); - } - - /** - * Retrieve the given annotation's attributes as a Map, preserving all attribute types - * as-is. - *

Note: As of Spring 3.1.1, the returned map is actually an - * {@link AnnotationAttributes} instance, however the Map signature of this method has - * been preserved for binary compatibility. - * @param annotation the annotation to retrieve the attributes for - * @return the Map of annotation attributes, with attribute names as keys and - * corresponding attribute values as values - */ - public static Map getAnnotationAttributes(Annotation annotation) { - return getAnnotationAttributes(annotation, false, false); - } - - /** - * Retrieve the given annotation's attributes as a Map. Equivalent to calling - * {@link #getAnnotationAttributes(Annotation, boolean, boolean)} with - * the {@code nestedAnnotationsAsMap} parameter set to {@code false}. - *

Note: As of Spring 3.1.1, the returned map is actually an - * {@link AnnotationAttributes} instance, however the Map signature of this method has - * been preserved for binary compatibility. - * @param annotation the annotation to retrieve the attributes for - * @param classValuesAsString whether to turn Class references into Strings (for - * compatibility with {@link org.springframework.core.type.AnnotationMetadata} or to - * preserve them as Class references - * @return the Map of annotation attributes, with attribute names as keys and - * corresponding attribute values as values - */ - public static Map getAnnotationAttributes(Annotation annotation, boolean classValuesAsString) { - return getAnnotationAttributes(annotation, classValuesAsString, false); - } - - /** - * Retrieve the given annotation's attributes as an {@link AnnotationAttributes} - * map structure. Implemented in Spring 3.1.1 to provide fully recursive annotation - * reading capabilities on par with that of the reflection-based - * {@link org.springframework.core.type.StandardAnnotationMetadata}. - * @param annotation the annotation to retrieve the attributes for - * @param classValuesAsString whether to turn Class references into Strings (for - * compatibility with {@link org.springframework.core.type.AnnotationMetadata} or to - * preserve them as Class references - * @param nestedAnnotationsAsMap whether to turn nested Annotation instances into - * {@link AnnotationAttributes} maps (for compatibility with - * {@link org.springframework.core.type.AnnotationMetadata} or to preserve them as - * Annotation instances - * @return the annotation attributes (a specialized Map) with attribute names as keys - * and corresponding attribute values as values - * @since 3.1.1 - */ - public static AnnotationAttributes getAnnotationAttributes( - Annotation annotation, boolean classValuesAsString, boolean nestedAnnotationsAsMap) { - - AnnotationAttributes attrs = new AnnotationAttributes(); - Method[] methods = annotation.annotationType().getDeclaredMethods(); - for (Method method : methods) { - if (method.getParameterTypes().length == 0 && method.getReturnType() != void.class) { - try { - Object value = method.invoke(annotation); - if (classValuesAsString) { - if (value instanceof Class) { - value = ((Class) value).getName(); - } - else if (value instanceof Class[]) { - Class[] clazzArray = (Class[]) value; - String[] newValue = new String[clazzArray.length]; - for (int i = 0; i < clazzArray.length; i++) { - newValue[i] = clazzArray[i].getName(); - } - value = newValue; - } - } - if (nestedAnnotationsAsMap && value instanceof Annotation) { - attrs.put(method.getName(), getAnnotationAttributes( - (Annotation)value, classValuesAsString, nestedAnnotationsAsMap)); - } - else if (nestedAnnotationsAsMap && value instanceof Annotation[]) { - Annotation[] realAnnotations = (Annotation[])value; - AnnotationAttributes[] mappedAnnotations = new AnnotationAttributes[realAnnotations.length]; - for (int i = 0; i < realAnnotations.length; i++) { - mappedAnnotations[i] = getAnnotationAttributes( - realAnnotations[i], classValuesAsString, nestedAnnotationsAsMap); - } - attrs.put(method.getName(), mappedAnnotations); - } - else { - attrs.put(method.getName(), value); - } - } - catch (Exception ex) { - throw new IllegalStateException("Could not obtain annotation attribute values", ex); - } - } - } - return attrs; - } - - /** - * Retrieve the value of the "value" attribute of a - * single-element Annotation, given an annotation instance. - * @param annotation the annotation instance from which to retrieve the value - * @return the attribute value, or null if not found - * @see #getValue(Annotation, String) - */ - public static Object getValue(Annotation annotation) { - return getValue(annotation, VALUE); - } - - /** - * Retrieve the value of a named Annotation attribute, given an annotation instance. - * @param annotation the annotation instance from which to retrieve the value - * @param attributeName the name of the attribute value to retrieve - * @return the attribute value, or null if not found - * @see #getValue(Annotation) - */ - public static Object getValue(Annotation annotation, String attributeName) { - try { - Method method = annotation.annotationType().getDeclaredMethod(attributeName, new Class[0]); - return method.invoke(annotation); - } - catch (Exception ex) { - return null; - } - } - - /** - * Retrieve the default value of the "value" attribute - * of a single-element Annotation, given an annotation instance. - * @param annotation the annotation instance from which to retrieve the default value - * @return the default value, or null if not found - * @see #getDefaultValue(Annotation, String) - */ - public static Object getDefaultValue(Annotation annotation) { - return getDefaultValue(annotation, VALUE); - } - - /** - * Retrieve the default value of a named Annotation attribute, given an annotation instance. - * @param annotation the annotation instance from which to retrieve the default value - * @param attributeName the name of the attribute value to retrieve - * @return the default value of the named attribute, or null if not found - * @see #getDefaultValue(Class, String) - */ - public static Object getDefaultValue(Annotation annotation, String attributeName) { - return getDefaultValue(annotation.annotationType(), attributeName); - } - - /** - * Retrieve the default value of the "value" attribute - * of a single-element Annotation, given the {@link Class annotation type}. - * @param annotationType the annotation type for which the default value should be retrieved - * @return the default value, or null if not found - * @see #getDefaultValue(Class, String) - */ - public static Object getDefaultValue(Class annotationType) { - return getDefaultValue(annotationType, VALUE); - } - - /** - * Retrieve the default value of a named Annotation attribute, given the {@link Class annotation type}. - * @param annotationType the annotation type for which the default value should be retrieved - * @param attributeName the name of the attribute value to retrieve. - * @return the default value of the named attribute, or null if not found - * @see #getDefaultValue(Annotation, String) - */ - public static Object getDefaultValue(Class annotationType, String attributeName) { - try { - Method method = annotationType.getDeclaredMethod(attributeName, new Class[0]); - return method.getDefaultValue(); - } - catch (Exception ex) { - return null; - } - } - - -} diff --git a/src/main/java/com/zero/utils/ArrayUtil.java b/src/main/java/com/zero/utils/ArrayUtil.java deleted file mode 100644 index 7bf09da..0000000 --- a/src/main/java/com/zero/utils/ArrayUtil.java +++ /dev/null @@ -1,3287 +0,0 @@ -/** - * Copyright (c) 1997-2013, www.tinygroup.org (luo_guo@icloud.com). - * - * Licensed under the GPL, Version 3.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.gnu.org/licenses/gpl.html - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.zero.utils; - -import java.util.List; - - -/** - * 有关数组处理的工具类。 - */ -public class ArrayUtil { - - private static final Object[] EMPTY_ARRAY=new Object[0]; - // ========================================================================== - // 取得数组长度。 - // ========================================================================== - - /** - * 取得数组的长度。 - *

- * 此方法比Array.getLength()要快得多。 - *

- * - * @param array 要检查的数组 - * @return 如果为空,或者非数组,则返回0。 - */ - public static int arrayLength(Object array) { - return arrayLength(array, 0, 0); - } - - private static int arrayLength(Object array, int defaultIfNull, int defaultIfNotArray) { - if (array == null) { - return defaultIfNull; // null - } else if (array instanceof Object[]) { - return ((Object[]) array).length; - } else if (array instanceof long[]) { - return ((long[]) array).length; - } else if (array instanceof int[]) { - return ((int[]) array).length; - } else if (array instanceof short[]) { - return ((short[]) array).length; - } else if (array instanceof byte[]) { - return ((byte[]) array).length; - } else if (array instanceof double[]) { - return ((double[]) array).length; - } else if (array instanceof float[]) { - return ((float[]) array).length; - } else if (array instanceof boolean[]) { - return ((boolean[]) array).length; - } else if (array instanceof char[]) { - return ((char[]) array).length; - } else { - return defaultIfNotArray; // not an array - } - } - - // ========================================================================== - // 判空函数。 - // - // 判断一个数组是否为null或包含0个元素。 - // ========================================================================== - - /** - * 检查数组是否为null或空数组[]。 - *

- *

-     * ArrayUtil.isEmptyArray(null)              = true
-     * ArrayUtil.isEmptyArray(new int[0])        = true
-     * ArrayUtil.isEmptyArray(new int[10])       = false
-     * 
- * - * @param array 要检查的数组 - * @return 如果为空, 则返回true - */ - public static boolean isEmptyArray(Object array) { - return arrayLength(array, 0, -1) == 0; - } - - // ========================================================================== - // 默认值函数。 - // - // 当数组为空时,取得默认数组值。 - // 注:判断数组为null时,可用更通用的ObjectUtil.defaultIfNull。 - // ========================================================================== - - /** - * 如果数组是null或空数组[],则返回指定数组默认值。 - *

- *

-     * ArrayUtil.defaultIfEmpty(null, defaultArray)           = defaultArray
-     * ArrayUtil.defaultIfEmpty(new String[0], defaultArray)  = 数组本身
-     * ArrayUtil.defaultIfEmpty(new String[10], defaultArray) = 数组本身
-     * 
- * - * @param array 要转换的数组 - * @param defaultArray 默认数组 - * @return 数组本身或默认数组 - */ - public static T defaultIfEmptyArray(T array, S defaultValue) { - return isEmptyArray(array) ? defaultValue : array; - } - - - - - - - - // ========================================================================== - // 比较数组的长度。 - // ========================================================================== - - /** - * 判断两个数组是否具有相同的长度。如果数组为null则被看作长度为0。 - * - * @param array1 数组1 - * @param array2 数组2 - * @return 如果两个数组长度相同,则返回true - */ - public static boolean isArraySameLength(Object[] array1, Object[] array2) { - int length1 = array1 == null ? 0 : array1.length; - int length2 = array2 == null ? 0 : array2.length; - - return length1 == length2; - } - - /** - * 判断两个数组是否具有相同的长度。如果数组为null则被看作长度为0。 - * - * @param array1 数组1 - * @param array2 数组2 - * @return 如果两个数组长度相同,则返回true - */ - public static boolean isArraySameLength(long[] array1, long[] array2) { - int length1 = array1 == null ? 0 : array1.length; - int length2 = array2 == null ? 0 : array2.length; - - return length1 == length2; - } - - /** - * 判断两个数组是否具有相同的长度。如果数组为null则被看作长度为0。 - * - * @param array1 数组1 - * @param array2 数组2 - * @return 如果两个数组长度相同,则返回true - */ - public static boolean isArraySameLength(int[] array1, int[] array2) { - int length1 = array1 == null ? 0 : array1.length; - int length2 = array2 == null ? 0 : array2.length; - - return length1 == length2; - } - - /** - * 判断两个数组是否具有相同的长度。如果数组为null则被看作长度为0。 - * - * @param array1 数组1 - * @param array2 数组2 - * @return 如果两个数组长度相同,则返回true - */ - public static boolean isArraySameLength(short[] array1, short[] array2) { - int length1 = array1 == null ? 0 : array1.length; - int length2 = array2 == null ? 0 : array2.length; - - return length1 == length2; - } - - /** - * 判断两个数组是否具有相同的长度。如果数组为null则被看作长度为0。 - * - * @param array1 数组1 - * @param array2 数组2 - * @return 如果两个数组长度相同,则返回true - */ - public static boolean isArraySameLength(byte[] array1, byte[] array2) { - int length1 = array1 == null ? 0 : array1.length; - int length2 = array2 == null ? 0 : array2.length; - - return length1 == length2; - } - - /** - * 判断两个数组是否具有相同的长度。如果数组为null则被看作长度为0。 - * - * @param array1 数组1 - * @param array2 数组2 - * @return 如果两个数组长度相同,则返回true - */ - public static boolean isArraySameLength(double[] array1, double[] array2) { - int length1 = array1 == null ? 0 : array1.length; - int length2 = array2 == null ? 0 : array2.length; - - return length1 == length2; - } - - /** - * 判断两个数组是否具有相同的长度。如果数组为null则被看作长度为0。 - * - * @param array1 数组1 - * @param array2 数组2 - * @return 如果两个数组长度相同,则返回true - */ - public static boolean isArraySameLength(float[] array1, float[] array2) { - int length1 = array1 == null ? 0 : array1.length; - int length2 = array2 == null ? 0 : array2.length; - - return length1 == length2; - } - - /** - * 判断两个数组是否具有相同的长度。如果数组为null则被看作长度为0。 - * - * @param array1 数组1 - * @param array2 数组2 - * @return 如果两个数组长度相同,则返回true - */ - public static boolean isArraySameLength(boolean[] array1, boolean[] array2) { - int length1 = array1 == null ? 0 : array1.length; - int length2 = array2 == null ? 0 : array2.length; - - return length1 == length2; - } - - /** - * 判断两个数组是否具有相同的长度。如果数组为null则被看作长度为0。 - * - * @param array1 数组1 - * @param array2 数组2 - * @return 如果两个数组长度相同,则返回true - */ - public static boolean isArraySameLength(char[] array1, char[] array2) { - int length1 = array1 == null ? 0 : array1.length; - int length2 = array2 == null ? 0 : array2.length; - - return length1 == length2; - } - - // ========================================================================== - // 反转数组的元素顺序。 - // ========================================================================== - - /** - * 反转数组的元素顺序。如果数组为null,则什么也不做。 - * - * @param array 要反转的数组 - */ - public static void arrayReverse(Object[] array) { - if (array == null) { - return; - } - - Object tmp; - - for (int i = 0, j = array.length - 1; j > i; i++, j--) { - tmp = array[j]; - array[j] = array[i]; - array[i] = tmp; - } - } - - /** - * 反转数组的元素顺序。如果数组为null,则什么也不做。 - * - * @param array 要反转的数组 - */ - public static void arrayReverse(long[] array) { - if (array == null) { - return; - } - - long tmp; - - for (int i = 0, j = array.length - 1; j > i; i++, j--) { - tmp = array[j]; - array[j] = array[i]; - array[i] = tmp; - } - } - - /** - * 反转数组的元素顺序。如果数组为null,则什么也不做。 - * - * @param array 要反转的数组 - */ - public static void arrayReverse(int[] array) { - if (array == null) { - return; - } - - int tmp; - - for (int i = 0, j = array.length - 1; j > i; i++, j--) { - tmp = array[j]; - array[j] = array[i]; - array[i] = tmp; - } - } - - /** - * 反转数组的元素顺序。如果数组为null,则什么也不做。 - * - * @param array 要反转的数组 - */ - public static void arrayReverse(short[] array) { - if (array == null) { - return; - } - - short tmp; - - for (int i = 0, j = array.length - 1; j > i; i++, j--) { - tmp = array[j]; - array[j] = array[i]; - array[i] = tmp; - } - } - - /** - * 反转数组的元素顺序。如果数组为null,则什么也不做。 - * - * @param array 要反转的数组 - */ - public static void arrayReverse(byte[] array) { - if (array == null) { - return; - } - - byte tmp; - - for (int i = 0, j = array.length - 1; j > i; i++, j--) { - tmp = array[j]; - array[j] = array[i]; - array[i] = tmp; - } - } - - /** - * 反转数组的元素顺序。如果数组为null,则什么也不做。 - * - * @param array 要反转的数组 - */ - public static void arrayReverse(double[] array) { - if (array == null) { - return; - } - - double tmp; - - for (int i = 0, j = array.length - 1; j > i; i++, j--) { - tmp = array[j]; - array[j] = array[i]; - array[i] = tmp; - } - } - - /** - * 反转数组的元素顺序。如果数组为null,则什么也不做。 - * - * @param array 要反转的数组 - */ - public static void arrayReverse(float[] array) { - if (array == null) { - return; - } - - float tmp; - - for (int i = 0, j = array.length - 1; j > i; i++, j--) { - tmp = array[j]; - array[j] = array[i]; - array[i] = tmp; - } - } - - /** - * 反转数组的元素顺序。如果数组为null,则什么也不做。 - * - * @param array 要反转的数组 - */ - public static void arrayReverse(boolean[] array) { - if (array == null) { - return; - } - - boolean tmp; - - for (int i = 0, j = array.length - 1; j > i; i++, j--) { - tmp = array[j]; - array[j] = array[i]; - array[i] = tmp; - } - } - - /** - * 反转数组的元素顺序。如果数组为null,则什么也不做。 - * - * @param array 要反转的数组 - */ - public static void arrayReverse(char[] array) { - if (array == null) { - return; - } - - char tmp; - - for (int i = 0, j = array.length - 1; j > i; i++, j--) { - tmp = array[j]; - array[j] = array[i]; - array[i] = tmp; - } - } - - // ========================================================================== - // 在数组中查找一个元素或一个元素序列。 - // - // 类型:Object[] - // ========================================================================== - - /** - * 在数组中查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param objectToFind 要查找的元素 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(Object[] array, Object objectToFind) { - return arrayIndexOf(array, objectToFind, 0); - } - - /** - * 在数组中查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(Object[] array, Object[] arrayToFind) { - return arrayIndexOf(array, arrayToFind, 0); - } - - /** - * 在数组中查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param objectToFind 要查找的元素 - * @param startIndex 起始索引 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(Object[] array, Object objectToFind, int startIndex) { - if (array == null) { - return -1; - } - - 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 -1; - } - - - - /** - * 在数组中从末尾开始查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param objectToFind 要查找的元素 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(Object[] array, Object objectToFind) { - return arrayLastIndexOf(array, objectToFind, Integer.MAX_VALUE); - } - - /** - * 在数组中从末尾开始查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(Object[] array, Object[] arrayToFind) { - return arrayLastIndexOf(array, arrayToFind, Integer.MAX_VALUE); - } - - /** - * 在数组中从末尾开始查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 - *

- * - * @param array 要扫描的数组 - * @param objectToFind 要查找的元素 - * @param startIndex 起始索引 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(Object[] array, Object objectToFind, int startIndex) { - if (array == null) { - return -1; - } - - if (startIndex < 0) { - return -1; - } 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 -1; - } - - - - /** - * 判断指定对象是否存在于指定数组中。 - *

- * 如果数组为null则返回false。 - *

- * - * @param array 要扫描的数组 - * @param objectToFind 要查找的元素 - * @return 如果找到则返回true - */ - public static boolean arrayContains(Object[] array, Object objectToFind) { - return arrayIndexOf(array, objectToFind) != -1; - } - - /** - * 判断指定元素序列是否存在于指定数组中。 - *

- * 如果数组为null则返回false。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 如果找到则返回true - */ - public static boolean arrayContains(Object[] array, Object[] arrayToFind) { - return arrayIndexOf(array, arrayToFind) != -1; - } - - // ========================================================================== - // 在数组中查找一个元素或一个元素序列。 - // - // 类型:long[] - // ========================================================================== - - /** - * 在数组中查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param longToFind 要查找的元素 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(long[] array, long longToFind) { - return arrayIndexOf(array, longToFind, 0); - } - - /** - * 在数组中查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(long[] array, long[] arrayToFind) { - return arrayIndexOf(array, arrayToFind, 0); - } - - /** - * 在数组中查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param longToFind 要查找的元素 - * @param startIndex 起始索引 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(long[] array, long longToFind, int startIndex) { - if (array == null) { - return -1; - } - - if (startIndex < 0) { - startIndex = 0; - } - - for (int i = startIndex; i < array.length; i++) { - if (longToFind == array[i]) { - return i; - } - } - - return -1; - } - - /** - * 在数组中查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param startIndex 起始索引 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(long[] array, long[] 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; - } - - long 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; - } - } - - /** - * 在数组中从末尾开始查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param longToFind 要查找的元素 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(long[] array, long longToFind) { - return arrayLastIndexOf(array, longToFind, Integer.MAX_VALUE); - } - - /** - * 在数组中从末尾开始查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(long[] array, long[] arrayToFind) { - return arrayLastIndexOf(array, arrayToFind, Integer.MAX_VALUE); - } - - /** - * 在数组中从末尾开始查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 - *

- * - * @param array 要扫描的数组 - * @param longToFind 要查找的元素 - * @param startIndex 起始索引 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(long[] array, long longToFind, 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 (longToFind == array[i]) { - return i; - } - } - - return -1; - } - - /** - * 在数组中从末尾开始查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param startIndex 起始索引 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(long[] array, long[] 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; - long 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; - } - } - - /** - * 判断指定对象是否存在于指定数组中。 - *

- * 如果数组为null则返回false。 - *

- * - * @param array 要扫描的数组 - * @param longToFind 要查找的元素 - * @return 如果找到则返回true - */ - public static boolean arrayContains(long[] array, long longToFind) { - return arrayIndexOf(array, longToFind) != -1; - } - - /** - * 判断指定元素序列是否存在于指定数组中。 - *

- * 如果数组为null则返回false。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 如果找到则返回true - */ - public static boolean arrayContains(long[] array, long[] arrayToFind) { - return arrayIndexOf(array, arrayToFind) != -1; - } - - // ========================================================================== - // 在数组中查找一个元素或一个元素序列。 - // - // 类型:int[] - // ========================================================================== - - /** - * 在数组中查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param intToFind 要查找的元素 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(int[] array, int intToFind) { - return arrayIndexOf(array, intToFind, 0); - } - - /** - * 在数组中查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(int[] array, int[] arrayToFind) { - return arrayIndexOf(array, arrayToFind, 0); - } - - /** - * 在数组中查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param intToFind 要查找的元素 - * @param startIndex 起始索引 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(int[] array, int intToFind, int startIndex) { - if (array == null) { - return -1; - } - - if (startIndex < 0) { - startIndex = 0; - } - - for (int i = startIndex; i < array.length; i++) { - if (intToFind == array[i]) { - return i; - } - } - - return -1; - } - - /** - * 在数组中查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param startIndex 起始索引 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(int[] array, int[] 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; - } - - int 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; - } - } - - /** - * 在数组中从末尾开始查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param intToFind 要查找的元素 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(int[] array, int intToFind) { - return arrayLastIndexOf(array, intToFind, Integer.MAX_VALUE); - } - - /** - * 在数组中从末尾开始查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(int[] array, int[] arrayToFind) { - return arrayLastIndexOf(array, arrayToFind, Integer.MAX_VALUE); - } - - /** - * 在数组中从末尾开始查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 - *

- * - * @param array 要扫描的数组 - * @param intToFind 要查找的元素 - * @param startIndex 起始索引 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(int[] array, int intToFind, 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 (intToFind == array[i]) { - return i; - } - } - - return -1; - } - - /** - * 在数组中从末尾开始查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param startIndex 起始索引 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(int[] array, int[] 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; - int 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; - } - } - - /** - * 判断指定对象是否存在于指定数组中。 - *

- * 如果数组为null则返回false。 - *

- * - * @param array 要扫描的数组 - * @param intToFind 要查找的元素 - * @return 如果找到则返回true - */ - public static boolean arrayContains(int[] array, int intToFind) { - return arrayIndexOf(array, intToFind) != -1; - } - - /** - * 判断指定元素序列是否存在于指定数组中。 - *

- * 如果数组为null则返回false。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 如果找到则返回true - */ - public static boolean arrayContains(int[] array, int[] arrayToFind) { - return arrayIndexOf(array, arrayToFind) != -1; - } - - // ========================================================================== - // 在数组中查找一个元素或一个元素序列。 - // - // 类型:short[] - // ========================================================================== - - /** - * 在数组中查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param shortToFind 要查找的元素 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(short[] array, short shortToFind) { - return arrayIndexOf(array, shortToFind, 0); - } - - /** - * 在数组中查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(short[] array, short[] arrayToFind) { - return arrayIndexOf(array, arrayToFind, 0); - } - - /** - * 在数组中查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param shortToFind 要查找的元素 - * @param startIndex 起始索引 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(short[] array, short shortToFind, int startIndex) { - if (array == null) { - return -1; - } - - if (startIndex < 0) { - startIndex = 0; - } - - for (int i = startIndex; i < array.length; i++) { - if (shortToFind == array[i]) { - return i; - } - } - - return -1; - } - - /** - * 在数组中查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param startIndex 起始索引 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(short[] array, short[] 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; - } - - short 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; - } - } - - /** - * 在数组中从末尾开始查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param shortToFind 要查找的元素 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(short[] array, short shortToFind) { - return arrayLastIndexOf(array, shortToFind, Integer.MAX_VALUE); - } - - /** - * 在数组中从末尾开始查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(short[] array, short[] arrayToFind) { - return arrayLastIndexOf(array, arrayToFind, Integer.MAX_VALUE); - } - - /** - * 在数组中从末尾开始查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 - *

- * - * @param array 要扫描的数组 - * @param shortToFind 要查找的元素 - * @param startIndex 起始索引 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(short[] array, short shortToFind, 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 (shortToFind == array[i]) { - return i; - } - } - - return -1; - } - - /** - * 在数组中从末尾开始查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param startIndex 起始索引 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(short[] array, short[] 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; - short 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; - } - } - - /** - * 判断指定对象是否存在于指定数组中。 - *

- * 如果数组为null则返回false。 - *

- * - * @param array 要扫描的数组 - * @param shortToFind 要查找的元素 - * @return 如果找到则返回true - */ - public static boolean arrayContains(short[] array, short shortToFind) { - return arrayIndexOf(array, shortToFind) != -1; - } - - /** - * 判断指定元素序列是否存在于指定数组中。 - *

- * 如果数组为null则返回false。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 如果找到则返回true - */ - public static boolean arrayContains(short[] array, short[] arrayToFind) { - return arrayIndexOf(array, arrayToFind) != -1; - } - - // ========================================================================== - // 在数组中查找一个元素或一个元素序列。 - // - // 类型:byte[] - // ========================================================================== - - /** - * 在数组中查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param byteToFind 要查找的元素 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(byte[] array, byte byteToFind) { - return arrayIndexOf(array, byteToFind, 0); - } - - /** - * 在数组中查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(byte[] array, byte[] arrayToFind) { - return arrayIndexOf(array, arrayToFind, 0); - } - - /** - * 在数组中查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param byteToFind 要查找的元素 - * @param startIndex 起始索引 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(byte[] array, byte byteToFind, int startIndex) { - if (array == null) { - return -1; - } - - if (startIndex < 0) { - startIndex = 0; - } - - for (int i = startIndex; i < array.length; i++) { - if (byteToFind == array[i]) { - return i; - } - } - - return -1; - } - - /** - * 在数组中查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param startIndex 起始索引 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(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; - } - } - - /** - * 在数组中从末尾开始查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param byteToFind 要查找的元素 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(byte[] array, byte byteToFind) { - return arrayLastIndexOf(array, byteToFind, Integer.MAX_VALUE); - } - - /** - * 在数组中从末尾开始查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(byte[] array, byte[] arrayToFind) { - return arrayLastIndexOf(array, arrayToFind, Integer.MAX_VALUE); - } - - /** - * 在数组中从末尾开始查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 - *

- * - * @param array 要扫描的数组 - * @param byteToFind 要查找的元素 - * @param startIndex 起始索引 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(byte[] array, byte byteToFind, 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 (byteToFind == array[i]) { - return i; - } - } - - return -1; - } - - /** - * 在数组中从末尾开始查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param startIndex 起始索引 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(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; - } - } - - /** - * 判断指定对象是否存在于指定数组中。 - *

- * 如果数组为null则返回false。 - *

- * - * @param array 要扫描的数组 - * @param byteToFind 要查找的元素 - * @return 如果找到则返回true - */ - public static boolean arrayContains(byte[] array, byte byteToFind) { - return arrayIndexOf(array, byteToFind) != -1; - } - - /** - * 判断指定元素序列是否存在于指定数组中。 - *

- * 如果数组为null则返回false。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 如果找到则返回true - */ - public static boolean arrayContains(byte[] array, byte[] arrayToFind) { - return arrayIndexOf(array, arrayToFind) != -1; - } - - // ========================================================================== - // 在数组中查找一个元素或一个元素序列。 - // - // 类型:double[] - // ========================================================================== - - /** - * 在数组中查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param doubleToFind 要查找的元素 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(double[] array, double doubleToFind) { - return arrayIndexOf(array, doubleToFind, 0, 0); - } - - /** - * 在数组中查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param doubleToFind 要查找的元素 - * @param tolerance 误差 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(double[] array, double doubleToFind, double tolerance) { - return arrayIndexOf(array, doubleToFind, 0, tolerance); - } - - /** - * 在数组中查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(double[] array, double[] arrayToFind) { - return arrayIndexOf(array, arrayToFind, 0, 0); - } - - /** - * 在数组中查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param tolerance 误差 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(double[] array, double[] arrayToFind, double tolerance) { - return arrayIndexOf(array, arrayToFind, 0, tolerance); - } - - /** - * 在数组中查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param doubleToFind 要查找的元素 - * @param startIndex 起始索引 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(double[] array, double doubleToFind, int startIndex) { - return arrayIndexOf(array, doubleToFind, startIndex, 0); - } - - /** - * 在数组中查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param doubleToFind 要查找的元素 - * @param startIndex 起始索引 - * @param tolerance 误差 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(double[] array, double doubleToFind, int startIndex, double tolerance) { - if (array == null) { - return -1; - } - - if (startIndex < 0) { - startIndex = 0; - } - - double min = doubleToFind - tolerance; - double max = doubleToFind + tolerance; - - for (int i = startIndex; i < array.length; i++) { - if (array[i] >= min && array[i] <= max) { - return i; - } - } - - return -1; - } - - /** - * 在数组中查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param startIndex 起始索引 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(double[] array, double[] arrayToFind, int startIndex) { - return arrayIndexOf(array, arrayToFind, startIndex, 0); - } - - /** - * 在数组中查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param startIndex 起始索引 - * @param tolerance 误差 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(double[] array, double[] arrayToFind, int startIndex, double tolerance) { - 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; - } - - double firstMin = arrayToFind[0] - tolerance; - double firstMax = arrayToFind[0] + tolerance; - int i = startIndex; - int max = sourceLength - targetLength; - - startSearchForFirst: - while (true) { - // 查找第一个元素 - while (i <= max && (array[i] < firstMin || array[i] > firstMax)) { - i++; - } - - if (i > max) { - return -1; - } - - // 已经找到第一个元素,接着找 - int j = i + 1; - int end = j + targetLength - 1; - int k = 1; - - while (j < end) { - if (Math.abs(array[j++] - arrayToFind[k++]) > tolerance) { - i++; - - // 重新查找第一个元素 - continue startSearchForFirst; - } - } - - // 找到了 - return i; - } - } - - /** - * 在数组中从末尾开始查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param doubleToFind 要查找的元素 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(double[] array, double doubleToFind) { - return arrayLastIndexOf(array, doubleToFind, Integer.MAX_VALUE, 0); - } - - /** - * 在数组中从末尾开始查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param doubleToFind 要查找的元素 - * @param tolerance 误差 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(double[] array, double doubleToFind, double tolerance) { - return arrayLastIndexOf(array, doubleToFind, Integer.MAX_VALUE, tolerance); - } - - /** - * 在数组中从末尾开始查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(double[] array, double[] arrayToFind) { - return arrayLastIndexOf(array, arrayToFind, Integer.MAX_VALUE, 0); - } - - /** - * 在数组中从末尾开始查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param tolerance 误差 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(double[] array, double[] arrayToFind, double tolerance) { - return arrayLastIndexOf(array, arrayToFind, Integer.MAX_VALUE, tolerance); - } - - /** - * 在数组中从末尾开始查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 - *

- * - * @param array 要扫描的数组 - * @param doubleToFind 要查找的元素 - * @param startIndex 起始索引 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(double[] array, double doubleToFind, int startIndex) { - return arrayLastIndexOf(array, doubleToFind, startIndex, 0); - } - - /** - * 在数组中从末尾开始查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 - *

- * - * @param array 要扫描的数组 - * @param doubleToFind 要查找的元素 - * @param startIndex 起始索引 - * @param tolerance 误差 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(double[] array, double doubleToFind, int startIndex, double tolerance) { - if (array == null) { - return -1; - } - - if (startIndex < 0) { - return -1; - } else if (startIndex >= array.length) { - startIndex = array.length - 1; - } - - double min = doubleToFind - tolerance; - double max = doubleToFind + tolerance; - - for (int i = startIndex; i >= 0; i--) { - if (array[i] >= min && array[i] <= max) { - return i; - } - } - - return -1; - } - - /** - * 在数组中从末尾开始查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param startIndex 起始索引 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(double[] array, double[] arrayToFind, int startIndex) { - return arrayLastIndexOf(array, arrayToFind, startIndex, 0); - } - - /** - * 在数组中从末尾开始查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param startIndex 起始索引 - * @param tolerance 误差 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(double[] array, double[] arrayToFind, int startIndex, double tolerance) { - 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; - double lastMin = arrayToFind[lastIndex] - tolerance; - double lastMax = arrayToFind[lastIndex] + tolerance; - int min = targetLength - 1; - int i = min + startIndex; - - startSearchForLast: - while (true) { - while (i >= min && (array[i] < lastMin || array[i] > lastMax)) { - i--; - } - - if (i < min) { - return -1; - } - - int j = i - 1; - int start = j - (targetLength - 1); - int k = lastIndex - 1; - - while (j > start) { - if (Math.abs(array[j--] - arrayToFind[k--]) > tolerance) { - i--; - continue startSearchForLast; - } - } - - return start + 1; - } - } - - /** - * 判断指定对象是否存在于指定数组中。 - *

- * 如果数组为null则返回false。 - *

- * - * @param array 要扫描的数组 - * @param doubleToFind 要查找的元素 - * @return 如果找到则返回true - */ - public static boolean arrayContains(double[] array, double doubleToFind) { - return arrayIndexOf(array, doubleToFind) != -1; - } - - /** - * 判断指定对象是否存在于指定数组中。 - *

- * 如果数组为null则返回false。 - *

- * - * @param array 要扫描的数组 - * @param doubleToFind 要查找的元素 - * @param tolerance 误差 - * @return 如果找到则返回true - */ - public static boolean arrayContains(double[] array, double doubleToFind, double tolerance) { - return arrayIndexOf(array, doubleToFind, tolerance) != -1; - } - - /** - * 判断指定元素序列是否存在于指定数组中。 - *

- * 如果数组为null则返回false。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 如果找到则返回true - */ - public static boolean arrayContains(double[] array, double[] arrayToFind) { - return arrayIndexOf(array, arrayToFind) != -1; - } - - /** - * 判断指定元素序列是否存在于指定数组中。 - *

- * 如果数组为null则返回false。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param tolerance 误差 - * @return 如果找到则返回true - */ - public static boolean arrayContains(double[] array, double[] arrayToFind, double tolerance) { - return arrayIndexOf(array, arrayToFind, tolerance) != -1; - } - - // ========================================================================== - // 在数组中查找一个元素或一个元素序列。 - // - // 类型:float[] - // ========================================================================== - - /** - * 在数组中查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param floatToFind 要查找的元素 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(float[] array, float floatToFind) { - return arrayIndexOf(array, floatToFind, 0, 0); - } - - /** - * 在数组中查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param floatToFind 要查找的元素 - * @param tolerance 误差 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(float[] array, float floatToFind, float tolerance) { - return arrayIndexOf(array, floatToFind, 0, tolerance); - } - - /** - * 在数组中查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(float[] array, float[] arrayToFind) { - return arrayIndexOf(array, arrayToFind, 0, 0); - } - - /** - * 在数组中查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param tolerance 误差 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(float[] array, float[] arrayToFind, float tolerance) { - return arrayIndexOf(array, arrayToFind, 0, tolerance); - } - - /** - * 在数组中查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param floatToFind 要查找的元素 - * @param startIndex 起始索引 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(float[] array, float floatToFind, int startIndex) { - return arrayIndexOf(array, floatToFind, startIndex, 0); - } - - /** - * 在数组中查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param floatToFind 要查找的元素 - * @param startIndex 起始索引 - * @param tolerance 误差 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(float[] array, float floatToFind, int startIndex, float tolerance) { - if (array == null) { - return -1; - } - - if (startIndex < 0) { - startIndex = 0; - } - - float min = floatToFind - tolerance; - float max = floatToFind + tolerance; - - for (int i = startIndex; i < array.length; i++) { - if (array[i] >= min && array[i] <= max) { - return i; - } - } - - return -1; - } - - /** - * 在数组中查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param startIndex 起始索引 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(float[] array, float[] arrayToFind, int startIndex) { - return arrayIndexOf(array, arrayToFind, startIndex, 0); - } - - /** - * 在数组中查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param startIndex 起始索引 - * @param tolerance 误差 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(float[] array, float[] arrayToFind, int startIndex, float tolerance) { - 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; - } - - float firstMin = arrayToFind[0] - tolerance; - float firstMax = arrayToFind[0] + tolerance; - int i = startIndex; - int max = sourceLength - targetLength; - - startSearchForFirst: - while (true) { - // 查找第一个元素 - while (i <= max && (array[i] < firstMin || array[i] > firstMax)) { - i++; - } - - if (i > max) { - return -1; - } - - // 已经找到第一个元素,接着找 - int j = i + 1; - int end = j + targetLength - 1; - int k = 1; - - while (j < end) { - if (Math.abs(array[j++] - arrayToFind[k++]) > tolerance) { - i++; - - // 重新查找第一个元素 - continue startSearchForFirst; - } - } - - // 找到了 - return i; - } - } - - /** - * 在数组中从末尾开始查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param floatToFind 要查找的元素 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(float[] array, float floatToFind) { - return arrayLastIndexOf(array, floatToFind, Integer.MAX_VALUE, 0); - } - - /** - * 在数组中从末尾开始查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param floatToFind 要查找的元素 - * @param tolerance 误差 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(float[] array, float floatToFind, float tolerance) { - return arrayLastIndexOf(array, floatToFind, Integer.MAX_VALUE, tolerance); - } - - /** - * 在数组中从末尾开始查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(float[] array, float[] arrayToFind) { - return arrayLastIndexOf(array, arrayToFind, Integer.MAX_VALUE, 0); - } - - /** - * 在数组中从末尾开始查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param tolerance 误差 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(float[] array, float[] arrayToFind, float tolerance) { - return arrayLastIndexOf(array, arrayToFind, Integer.MAX_VALUE, tolerance); - } - - /** - * 在数组中从末尾开始查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 - *

- * - * @param array 要扫描的数组 - * @param floatToFind 要查找的元素 - * @param startIndex 起始索引 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(float[] array, float floatToFind, int startIndex) { - return arrayLastIndexOf(array, floatToFind, startIndex, 0); - } - - /** - * 在数组中从末尾开始查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 - *

- * - * @param array 要扫描的数组 - * @param floatToFind 要查找的元素 - * @param startIndex 起始索引 - * @param tolerance 误差 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(float[] array, float floatToFind, int startIndex, float tolerance) { - if (array == null) { - return -1; - } - - if (startIndex < 0) { - return -1; - } else if (startIndex >= array.length) { - startIndex = array.length - 1; - } - - float min = floatToFind - tolerance; - float max = floatToFind + tolerance; - - for (int i = startIndex; i >= 0; i--) { - if (array[i] >= min && array[i] <= max) { - return i; - } - } - - return -1; - } - - /** - * 在数组中从末尾开始查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param startIndex 起始索引 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(float[] array, float[] arrayToFind, int startIndex) { - return arrayLastIndexOf(array, arrayToFind, startIndex, 0); - } - - /** - * 在数组中从末尾开始查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param startIndex 起始索引 - * @param tolerance 误差 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(float[] array, float[] arrayToFind, int startIndex, float tolerance) { - 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; - float lastMin = arrayToFind[lastIndex] - tolerance; - float lastMax = arrayToFind[lastIndex] + tolerance; - int min = targetLength - 1; - int i = min + startIndex; - - startSearchForLast: - while (true) { - while (i >= min && (array[i] < lastMin || array[i] > lastMax)) { - i--; - } - - if (i < min) { - return -1; - } - - int j = i - 1; - int start = j - (targetLength - 1); - int k = lastIndex - 1; - - while (j > start) { - if (Math.abs(array[j--] - arrayToFind[k--]) > tolerance) { - i--; - continue startSearchForLast; - } - } - - return start + 1; - } - } - - /** - * 判断指定对象是否存在于指定数组中。 - *

- * 如果数组为null则返回false。 - *

- * - * @param array 要扫描的数组 - * @param floatToFind 要查找的元素 - * @return 如果找到则返回true - */ - public static boolean arrayContains(float[] array, float floatToFind) { - return arrayIndexOf(array, floatToFind) != -1; - } - - /** - * 判断指定对象是否存在于指定数组中。 - *

- * 如果数组为null则返回false。 - *

- * - * @param array 要扫描的数组 - * @param floatToFind 要查找的元素 - * @param tolerance 误差 - * @return 如果找到则返回true - */ - public static boolean arrayContains(float[] array, float floatToFind, float tolerance) { - return arrayIndexOf(array, floatToFind, tolerance) != -1; - } - - /** - * 判断指定元素序列是否存在于指定数组中。 - *

- * 如果数组为null则返回false。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 如果找到则返回true - */ - public static boolean arrayContains(float[] array, float[] arrayToFind) { - return arrayIndexOf(array, arrayToFind) != -1; - } - - /** - * 判断指定元素序列是否存在于指定数组中。 - *

- * 如果数组为null则返回false。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param tolerance 误差 - * @return 如果找到则返回true - */ - public static boolean arrayContains(float[] array, float[] arrayToFind, float tolerance) { - return arrayIndexOf(array, arrayToFind, tolerance) != -1; - } - - // ========================================================================== - // 在数组中查找一个元素或一个元素序列。 - // - // 类型:boolean[] - // ========================================================================== - - /** - * 在数组中查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param booleanToFind 要查找的元素 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(boolean[] array, boolean booleanToFind) { - return arrayIndexOf(array, booleanToFind, 0); - } - - /** - * 在数组中查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(boolean[] array, boolean[] arrayToFind) { - return arrayIndexOf(array, arrayToFind, 0); - } - - /** - * 在数组中查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param booleanToFind 要查找的元素 - * @param startIndex 起始索引 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(boolean[] array, boolean booleanToFind, int startIndex) { - if (array == null) { - return -1; - } - - if (startIndex < 0) { - startIndex = 0; - } - - for (int i = startIndex; i < array.length; i++) { - if (booleanToFind == array[i]) { - return i; - } - } - - return -1; - } - - /** - * 在数组中查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param startIndex 起始索引 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(boolean[] array, boolean[] 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; - } - - boolean 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; - } - } - - /** - * 在数组中从末尾开始查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param booleanToFind 要查找的元素 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(boolean[] array, boolean booleanToFind) { - return arrayLastIndexOf(array, booleanToFind, Integer.MAX_VALUE); - } - - /** - * 在数组中从末尾开始查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(boolean[] array, boolean[] arrayToFind) { - return arrayLastIndexOf(array, arrayToFind, Integer.MAX_VALUE); - } - - /** - * 在数组中从末尾开始查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 - *

- * - * @param array 要扫描的数组 - * @param booleanToFind 要查找的元素 - * @param startIndex 起始索引 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(boolean[] array, boolean booleanToFind, 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 (booleanToFind == array[i]) { - return i; - } - } - - return -1; - } - - /** - * 在数组中从末尾开始查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param startIndex 起始索引 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(boolean[] array, boolean[] 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; - boolean 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; - } - } - - /** - * 判断指定对象是否存在于指定数组中。 - *

- * 如果数组为null则返回false。 - *

- * - * @param array 要扫描的数组 - * @param booleanToFind 要查找的元素 - * @return 如果找到则返回true - */ - public static boolean arrayContains(boolean[] array, boolean booleanToFind) { - return arrayIndexOf(array, booleanToFind) != -1; - } - - /** - * 判断指定元素序列是否存在于指定数组中。 - *

- * 如果数组为null则返回false。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 如果找到则返回true - */ - public static boolean arrayContains(boolean[] array, boolean[] arrayToFind) { - return arrayIndexOf(array, arrayToFind) != -1; - } - - // ========================================================================== - // 在数组中查找一个元素或一个元素序列。 - // - // 类型:char[] - // ========================================================================== - - /** - * 在数组中查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param charToFind 要查找的元素 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(char[] array, char charToFind) { - return arrayIndexOf(array, charToFind, 0); - } - - /** - * 在数组中查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(char[] array, char[] arrayToFind) { - return arrayIndexOf(array, arrayToFind, 0); - } - - /** - * 在数组中查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param charToFind 要查找的元素 - * @param startIndex 起始索引 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(char[] array, char charToFind, int startIndex) { - if (array == null) { - return -1; - } - - if (startIndex < 0) { - startIndex = 0; - } - - for (int i = startIndex; i < array.length; i++) { - if (charToFind == array[i]) { - return i; - } - } - - return -1; - } - - /** - * 在数组中查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param startIndex 起始索引 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayIndexOf(char[] array, char[] 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; - } - - char 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; - } - } - - /** - * 在数组中从末尾开始查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param charToFind 要查找的元素 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(char[] array, char charToFind) { - return arrayLastIndexOf(array, charToFind, Integer.MAX_VALUE); - } - - /** - * 在数组中从末尾开始查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(char[] array, char[] arrayToFind) { - return arrayLastIndexOf(array, arrayToFind, Integer.MAX_VALUE); - } - - /** - * 在数组中从末尾开始查找一个元素。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 - *

- * - * @param array 要扫描的数组 - * @param charToFind 要查找的元素 - * @param startIndex 起始索引 - * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(char[] array, char charToFind, 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 (charToFind == array[i]) { - return i; - } - } - - return -1; - } - - /** - * 在数组中从末尾开始查找一个元素序列。 - *

- * 如果未找到或数组为null则返回-1。 - *

- *

- * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @param startIndex 起始索引 - * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 - */ - public static int arrayLastIndexOf(char[] array, char[] 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; - char 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; - } - } - - /** - * 判断指定对象是否存在于指定数组中。 - *

- * 如果数组为null则返回false。 - *

- * - * @param array 要扫描的数组 - * @param charToFind 要查找的元素 - * @return 如果找到则返回true - */ - public static boolean arrayContains(char[] array, char charToFind) { - return arrayIndexOf(array, charToFind) != -1; - } - - /** - * 判断指定元素序列是否存在于指定数组中。 - *

- * 如果数组为null则返回false。 - *

- * - * @param array 要扫描的数组 - * @param arrayToFind 要查找的元素序列 - * @return 如果找到则返回true - */ - public static boolean arrayContains(char[] array, char[] arrayToFind) { - return arrayIndexOf(array, arrayToFind) != -1; - } - - @SuppressWarnings("unchecked") - public static Object[] toArray(Object value){ - if(value==null){ - return EMPTY_ARRAY; - } - Object[] values; - if(value.getClass().isArray()){ - values=(Object[])value; - }else if(List.class.isInstance(value)){ - List list=(List)value; - values=list.toArray(); - }else{ - values=new Object[]{value}; - } - return values; - } -} diff --git a/src/main/java/com/zero/utils/Assert.java b/src/main/java/com/zero/utils/Assert.java deleted file mode 100644 index 564696e..0000000 --- a/src/main/java/com/zero/utils/Assert.java +++ /dev/null @@ -1,333 +0,0 @@ -/** - * Copyright (c) 1997-2013, www.tinygroup.org (luo_guo@icloud.com). - * - * Licensed under the GPL, Version 3.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.gnu.org/licenses/gpl.html - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.zero.utils; - -import static com.zero.utils.Assert.ExceptionType.ILLEGAL_ARGUMENT; -import static com.zero.utils.Assert.ExceptionType.UNEXPECTED_FAILURE; -import static com.zero.utils.Assert.ExceptionType.UNREACHABLE_CODE; -import static com.zero.utils.Assert.ExceptionType.UNSUPPORTED_OPERATION; - -import com.zero.utils.exceptions.UnexpectedFailureException; -import com.zero.utils.exceptions.UnreachableCodeException; - -/** - * 断言工具,用来实现Fail-Fast。 - *

- * 注意事项: - *

- *
    - *
  • Assertion是用来明确设置程序中的条件和约定的,它是一种程序员之间交流的工具,而不是和最终用户交流的工具。
  • - *
  • 一个经过完整单元测试的正确程序,不应该使任何一条assertion失败。
  • - *
  • 应避免过于复杂的assertion条件,而占用过多的运行时间。除非Assertion失败。
  • - *
  • Assertion的出现异常信息不是给最终用户看的,因此没必要写得过于详细,更没必要考虑国际化的问题,以至于浪费CPU的时间。 - * 例如下面的语句是要避免的: - *

    - *

    - * assertTrue(type instanceof MyType, "Unsupported type: " + type);
    - * 
    - *

    - * 可以替换成: - *

    - *

    - * assertTrue(type instanceof MyType, "Unsupported type: %s", type);
    - * 
    - *

    - * 这样,当assertion顺利通过时,不会占用CPU时间。

  • - *
- *

- * 此外,部分方法具有返回值,以方便编程,例如: - *

- *

- *

- * void foo(String param) {
- *     bar(assertNotNull(param));
- * }
- *
- * int bar(String param) {
- *     if (true) {
- *         ...
- *     }
- *
- *     return unreachableCode();
- * }
- * 
- * - * @author renhui - */ -public final class Assert { - /** 确保对象不为空,否则抛出IllegalArgumentException。 */ - public static T assertNotNull(T object) { - return assertNotNull(object, null, null, (Object[]) null); - } - - /** 确保对象不为空,否则抛出IllegalArgumentException。 */ - public static T assertNotNull(T object, String message, Object... args) { - return assertNotNull(object, null, message, args); - } - - /** 确保对象不为空,否则抛出指定异常,默认为IllegalArgumentException。 */ - public static T assertNotNull(T object, ExceptionType exceptionType, String message, Object... args) { - if (object == null) { - if (exceptionType == null) { - exceptionType = ILLEGAL_ARGUMENT; - } - - throw exceptionType.newInstance(getMessage(message, args, - "[Assertion failed] - the argument is required; it must not be null")); - } - - return object; - } - - /** 确保对象为空,否则抛出IllegalArgumentException。 */ - public static T assertNull(T object) { - return assertNull(object, null, null, (Object[]) null); - } - - /** 确保对象为空,否则抛出IllegalArgumentException。 */ - public static T assertNull(T object, String message, Object... args) { - return assertNull(object, null, message, args); - } - - /** 确保对象为空,否则抛出指定异常,默认为IllegalArgumentException。 */ - public static T assertNull(T object, ExceptionType exceptionType, String message, Object... args) { - if (object != null) { - if (exceptionType == null) { - exceptionType = ILLEGAL_ARGUMENT; - } - - throw exceptionType.newInstance(getMessage(message, args, - "[Assertion failed] - the object argument must be null")); - } - - return object; - } - - /** 确保表达式为真,否则抛出IllegalArgumentException。 */ - public static void assertTrue(boolean expression) { - assertTrue(expression, null, null, (Object[]) null); - } - - /** 确保表达式为真,否则抛出IllegalArgumentException。 */ - public static void assertTrue(boolean expression, String message, Object... args) { - assertTrue(expression, null, message, args); - } - - /** 确保表达式为真,否则抛出指定异常,默认为IllegalArgumentException。 */ - public static void assertTrue(boolean expression, ExceptionType exceptionType, String message, Object... args) { - if (!expression) { - if (exceptionType == null) { - exceptionType = ILLEGAL_ARGUMENT; - } - - throw exceptionType.newInstance(getMessage(message, args, - "[Assertion failed] - the expression must be true")); - } - } - - /** 不可能到达的代码。 */ - public static T unreachableCode() { - unreachableCode(null, (Object[]) null); - return null; - } - - /** 不可能到达的代码。 */ - public static T unreachableCode(String message, Object... args) { - throw UNREACHABLE_CODE.newInstance(getMessage(message, args, - "[Assertion failed] - the code is expected as unreachable")); - } - - /** 不可能发生的异常。 */ - public static T unexpectedException(Throwable e) { - unexpectedException(e, null, (Object[]) null); - return null; - } - - /** 不可能发生的异常。 */ - public static T unexpectedException(Throwable e, String message, Object... args) { - RuntimeException exception = UNEXPECTED_FAILURE.newInstance(getMessage(message, args, - "[Assertion failed] - unexpected exception is thrown")); - - exception.initCause(e); - - throw exception; - } - - /** 未预料的失败。 */ - public static T fail() { - fail(null, (Object[]) null); - return null; - } - - /** 未预料的失败。 */ - public static T fail(String message, Object... args) { - throw UNEXPECTED_FAILURE.newInstance(getMessage(message, args, "[Assertion failed] - unexpected failure")); - } - - /** 不支持的操作。 */ - public static T unsupportedOperation() { - unsupportedOperation(null, (Object[]) null); - return null; - } - - /** 不支持的操作。 */ - public static T unsupportedOperation(String message, Object... args) { - throw UNSUPPORTED_OPERATION.newInstance(getMessage(message, args, - "[Assertion failed] - unsupported operation or unimplemented function")); - } - - /** - * Assert that the given String is not empty; that is, - * it must not be null and not the empty String. - *
Assert.hasLength(name, "Name must not be empty");
- * @param text the String to check - * @param message the exception message to use if the assertion fails - * @see StringUtils#hasLength - */ - public static void hasLength(String text, String message) { - if (StringUtil.isBlank(text)) { - throw new IllegalArgumentException(message); - } - } - - /** - * Assert that the given String is not empty; that is, - * it must not be null and not the empty String. - *
Assert.hasLength(name);
- * @param text the String to check - * @see StringUtils#hasLength - */ - public static void hasLength(String text) { - hasLength(text, - "[Assertion failed] - this String argument must have length; it must not be null or empty"); - } - - /** - * Assert that the given String has valid text content; that is, it must not - * be null and must contain at least one non-whitespace character. - *
Assert.hasText(name, "'name' must not be empty");
- * @param text the String to check - * @param message the exception message to use if the assertion fails - * @see StringUtils#hasText - */ - public static void hasText(String text, String message) { - if (StringUtil.isBlank(text)) { - throw new IllegalArgumentException(message); - } - } - - /** - * Assert that the given String has valid text content; that is, it must not - * be null and must contain at least one non-whitespace character. - *
Assert.hasText(name, "'name' must not be empty");
- * @param text the String to check - * @see StringUtils#hasText - */ - public static void hasText(String text) { - hasText(text, - "[Assertion failed] - this String argument must have text; it must not be null, empty, or blank"); - } - - /** - * Assert that superType.isAssignableFrom(subType) is true. - *
Assert.isAssignable(Number.class, myClass);
- * @param superType the super type to check - * @param subType the sub type to check - * @throws IllegalArgumentException if the classes are not assignable - */ - public static void isAssignable(Class superType, Class subType) { - isAssignable(superType, subType, ""); - } - - /** - * Assert that superType.isAssignableFrom(subType) is true. - *
Assert.isAssignable(Number.class, myClass);
- * @param superType the super type to check against - * @param subType the sub type to check - * @param message a message which will be prepended to the message produced by - * the function itself, and which may be used to provide context. It should - * normally end in a ": " or ". " so that the function generate message looks - * ok when prepended to it. - * @throws IllegalArgumentException if the classes are not assignable - */ - public static void isAssignable(Class superType, Class subType, String message) { - assertNotNull(superType, "Type to check against must not be null"); - if (subType == null || !superType.isAssignableFrom(subType)) { - throw new IllegalArgumentException(message + subType + " is not assignable to " + superType); - } - } - - /** 取得带参数的消息。 */ - private static String getMessage(String message, Object[] args, String defaultMessage) { - if (message == null) { - message = defaultMessage; - } - - if (args == null || args.length == 0) { - return message; - } - - return String.format(message, args); - } - - /** Assertion错误类型。 */ - public static enum ExceptionType { - ILLEGAL_ARGUMENT { - - RuntimeException newInstance(String message) { - return new IllegalArgumentException(message); - } - }, - - ILLEGAL_STATE { - - RuntimeException newInstance(String message) { - return new IllegalStateException(message); - } - }, - - NULL_POINT { - - RuntimeException newInstance(String message) { - return new NullPointerException(message); - } - }, - - UNREACHABLE_CODE { - - RuntimeException newInstance(String message) { - return new UnreachableCodeException(message); - } - }, - - UNEXPECTED_FAILURE { - - RuntimeException newInstance(String message) { - return new UnexpectedFailureException(message); - } - }, - - UNSUPPORTED_OPERATION { - - RuntimeException newInstance(String message) { - return new UnsupportedOperationException(message); - } - }; - - abstract RuntimeException newInstance(String message); - } -} diff --git a/src/main/java/com/zero/utils/BasicConstant.java b/src/main/java/com/zero/utils/BasicConstant.java deleted file mode 100644 index bfc07b6..0000000 --- a/src/main/java/com/zero/utils/BasicConstant.java +++ /dev/null @@ -1,107 +0,0 @@ -/** - * Copyright (c) 1997-2013, www.tinygroup.org (luo_guo@icloud.com). - * - * Licensed under the GPL, Version 3.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.gnu.org/licenses/gpl.html - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.zero.utils; - -import java.io.Serializable; - -/** - * 基本常量。 - * - * @author renhui - */ -public final class BasicConstant { - // ============================================================= - // 数组常量 - // ============================================================= - - // primitive arrays - - /** 空的byte数组。 */ - public static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; - public static final Byte[] EMPTY_BYTE_OBJECT_ARRAY = new Byte[0]; - - /** 空的short数组。 */ - public static final short[] EMPTY_SHORT_ARRAY = new short[0]; - public static final Short[] EMPTY_SHORT_OBJECT_ARRAY = new Short[0]; - - /** 空的int数组。 */ - public static final int[] EMPTY_INT_ARRAY = new int[0]; - public static final Integer[] EMPTY_INTEGER_OBJECT_ARRAY = new Integer[0]; - - /** 空的long数组。 */ - public static final long[] EMPTY_LONG_ARRAY = new long[0]; - public static final Long[] EMPTY_LONG_OBJECT_ARRAY = new Long[0]; - - /** 空的float数组。 */ - public static final float[] EMPTY_FLOAT_ARRAY = new float[0]; - public static final Float[] EMPTY_FLOAT_OBJECT_ARRAY = new Float[0]; - - /** 空的double数组。 */ - public static final double[] EMPTY_DOUBLE_ARRAY = new double[0]; - public static final Double[] EMPTY_DOUBLE_OBJECT_ARRAY = new Double[0]; - - /** 空的char数组。 */ - public static final char[] EMPTY_CHAR_ARRAY = new char[0]; - public static final Character[] EMPTY_CHARACTER_OBJECT_ARRAY = new Character[0]; - - /** 空的boolean数组。 */ - public static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0]; - public static final Boolean[] EMPTY_BOOLEAN_OBJECT_ARRAY = new Boolean[0]; - - // object arrays - - /** 空的Object数组。 */ - public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; - - /** 空的Class数组。 */ - public static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; - - /** 空的String数组。 */ - public static final String[] EMPTY_STRING_ARRAY = new String[0]; - - // ============================================================= - // 对象常量 - // ============================================================= - - // 0-valued primitive wrappers - public static final Byte BYTE_ZERO = new Byte((byte) 0); - public static final Short SHORT_ZERO = new Short((short) 0); - public static final Integer INT_ZERO = new Integer(0); - public static final Long LONG_ZERO = new Long(0L); - public static final Float FLOAT_ZERO = new Float(0); - public static final Double DOUBLE_ZERO = new Double(0); - public static final Character CHAR_NULL = new Character('\0'); - public static final Boolean BOOL_FALSE = Boolean.FALSE; - - /** 代表null值的占位对象。 */ - public static final Object NULL_PLACEHOLDER = new NullPlaceholder(); - - private final static class NullPlaceholder implements Serializable { - private static final long serialVersionUID = 7092611880189329093L; - - - public String toString() { - return "null"; - } - - private Object readResolve() { - return NULL_PLACEHOLDER; - } - } - - /** 空字符串。 */ - public static final String EMPTY_STRING = ""; -} diff --git a/src/main/java/com/zero/utils/BridgeMethodResolver.java b/src/main/java/com/zero/utils/BridgeMethodResolver.java deleted file mode 100644 index 79df7a3..0000000 --- a/src/main/java/com/zero/utils/BridgeMethodResolver.java +++ /dev/null @@ -1,229 +0,0 @@ -/** - * Copyright (c) 1997-2013, www.tinygroup.org (luo_guo@icloud.com). - * - * Licensed under the GPL, Version 3.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.gnu.org/licenses/gpl.html - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.zero.utils; - -import java.lang.reflect.GenericArrayType; -import java.lang.reflect.Method; -import java.lang.reflect.Type; -import java.lang.reflect.TypeVariable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - - - -/** - * Helper for resolving synthetic {@link Method#isBridge bridge Methods} to the - * {@link Method} being bridged. - * - *

Given a synthetic {@link Method#isBridge bridge Method} returns the {@link Method} - * being bridged. A bridge method may be created by the compiler when extending a - * parameterized type whose methods have parameterized arguments. During runtime - * invocation the bridge {@link Method} may be invoked and/or used via reflection. - * When attempting to locate annotations on {@link Method Methods}, it is wise to check - * for bridge {@link Method Methods} as appropriate and find the bridged {@link Method}. - * - *

See - * The Java Language Specification for more details on the use of bridge methods. - * - * @author Rob Harrop - * @author Juergen Hoeller - * @since 2.0 - */ -public abstract class BridgeMethodResolver { - - /** - * Find the original method for the supplied {@link Method bridge Method}. - *

It is safe to call this method passing in a non-bridge {@link Method} instance. - * In such a case, the supplied {@link Method} instance is returned directly to the caller. - * Callers are not required to check for bridging before calling this method. - * @param bridgeMethod the method to introspect - * @return the original method (either the bridged method or the passed-in method - * if no more specific one could be found) - */ - public static Method findBridgedMethod(Method bridgeMethod) { - if (bridgeMethod == null || !bridgeMethod.isBridge()) { - return bridgeMethod; - } - // Gather all methods with matching name and parameter size. - List candidateMethods = new ArrayList(); - Method[] methods = ReflectionUtils.getAllDeclaredMethods(bridgeMethod.getDeclaringClass()); - for (Method candidateMethod : methods) { - if (isBridgedCandidateFor(candidateMethod, bridgeMethod)) { - candidateMethods.add(candidateMethod); - } - } - // Now perform simple quick check. - if (candidateMethods.size() == 1) { - return candidateMethods.get(0); - } - // Search for candidate match. - Method bridgedMethod = searchCandidates(candidateMethods, bridgeMethod); - if (bridgedMethod != null) { - // Bridged method found... - return bridgedMethod; - } - else { - // A bridge method was passed in but we couldn't find the bridged method. - // Let's proceed with the passed-in method and hope for the best... - return bridgeMethod; - } - } - - /** - * Searches for the bridged method in the given candidates. - * @param candidateMethods the List of candidate Methods - * @param bridgeMethod the bridge method - * @return the bridged method, or null if none found - */ - private static Method searchCandidates(List candidateMethods, Method bridgeMethod) { - if (candidateMethods.isEmpty()) { - return null; - } - Map typeParameterMap = GenericTypeResolver.getTypeVariableMap(bridgeMethod.getDeclaringClass()); - Method previousMethod = null; - boolean sameSig = true; - for (Method candidateMethod : candidateMethods) { - if (isBridgeMethodFor(bridgeMethod, candidateMethod, typeParameterMap)) { - return candidateMethod; - } - else if (previousMethod != null) { - sameSig = sameSig && - Arrays.equals(candidateMethod.getGenericParameterTypes(), previousMethod.getGenericParameterTypes()); - } - previousMethod = candidateMethod; - } - return (sameSig ? candidateMethods.get(0) : null); - } - - /** - * Returns true if the supplied 'candidateMethod' can be - * consider a validate candidate for the {@link Method} that is {@link Method#isBridge() bridged} - * by the supplied {@link Method bridge Method}. This method performs inexpensive - * checks and can be used quickly filter for a set of possible matches. - */ - private static boolean isBridgedCandidateFor(Method candidateMethod, Method bridgeMethod) { - return (!candidateMethod.isBridge() && !candidateMethod.equals(bridgeMethod) && - candidateMethod.getName().equals(bridgeMethod.getName()) && - candidateMethod.getParameterTypes().length == bridgeMethod.getParameterTypes().length); - } - - /** - * Determines whether or not the bridge {@link Method} is the bridge for the - * supplied candidate {@link Method}. - */ - static boolean isBridgeMethodFor(Method bridgeMethod, Method candidateMethod, Map typeVariableMap) { - if (isResolvedTypeMatch(candidateMethod, bridgeMethod, typeVariableMap)) { - return true; - } - Method method = findGenericDeclaration(bridgeMethod); - return (method != null && isResolvedTypeMatch(method, candidateMethod, typeVariableMap)); - } - - /** - * Searches for the generic {@link Method} declaration whose erased signature - * matches that of the supplied bridge method. - * @throws IllegalStateException if the generic declaration cannot be found - */ - private static Method findGenericDeclaration(Method bridgeMethod) { - // Search parent types for method that has same signature as bridge. - Class superclass = bridgeMethod.getDeclaringClass().getSuperclass(); - while (!Object.class.equals(superclass)) { - Method method = searchForMatch(superclass, bridgeMethod); - if (method != null && !method.isBridge()) { - return method; - } - superclass = superclass.getSuperclass(); - } - - // Search interfaces. - Class[] interfaces = ClassUtil.getAllInterfacesForClass(bridgeMethod.getDeclaringClass()); - for (Class ifc : interfaces) { - Method method = searchForMatch(ifc, bridgeMethod); - if (method != null && !method.isBridge()) { - return method; - } - } - - return null; - } - - /** - * Returns true if the {@link Type} signature of both the supplied - * {@link Method#getGenericParameterTypes() generic Method} and concrete {@link Method} - * are equal after resolving all {@link TypeVariable TypeVariables} using the supplied - * TypeVariable Map, otherwise returns false. - */ - private static boolean isResolvedTypeMatch( - Method genericMethod, Method candidateMethod, Map typeVariableMap) { - - Type[] genericParameters = genericMethod.getGenericParameterTypes(); - Class[] candidateParameters = candidateMethod.getParameterTypes(); - if (genericParameters.length != candidateParameters.length) { - return false; - } - for (int i = 0; i < genericParameters.length; i++) { - Type genericParameter = genericParameters[i]; - Class candidateParameter = candidateParameters[i]; - if (candidateParameter.isArray()) { - // An array type: compare the component type. - Type rawType = GenericTypeResolver.getRawType(genericParameter, typeVariableMap); - if (rawType instanceof GenericArrayType) { - if (!candidateParameter.getComponentType().equals( - GenericTypeResolver.resolveType(((GenericArrayType) rawType).getGenericComponentType(), typeVariableMap))) { - return false; - } - break; - } - } - // A non-array type: compare the type itself. - Class resolvedParameter = GenericTypeResolver.resolveType(genericParameter, typeVariableMap); - if (!candidateParameter.equals(resolvedParameter)) { - return false; - } - } - return true; - } - - /** - * If the supplied {@link Class} has a declared {@link Method} whose signature matches - * that of the supplied {@link Method}, then this matching {@link Method} is returned, - * otherwise null is returned. - */ - private static Method searchForMatch(Class type, Method bridgeMethod) { - return ReflectionUtils.findMethod(type, bridgeMethod.getName(), bridgeMethod.getParameterTypes()); - } - - /** - * Compare the signatures of the bridge method and the method which it bridges. If - * the parameter and return types are the same, it is a 'visibility' bridge method - * introduced in Java 6 to fix http://bugs.sun.com/view_bug.do?bug_id=6342411. - * See also http://stas-blogspot.blogspot.com/2010/03/java-bridge-methods-explained.html - * @return whether signatures match as described - */ - public static boolean isVisibilityBridgeMethodPair(Method bridgeMethod, Method bridgedMethod) { - Assert.assertTrue(bridgeMethod != null); - Assert.assertTrue(bridgedMethod != null); - if (bridgeMethod == bridgedMethod) { - return true; - } - return Arrays.equals(bridgeMethod.getParameterTypes(), bridgedMethod.getParameterTypes()) && - bridgeMethod.getReturnType().equals(bridgedMethod.getReturnType()); - } - - -} diff --git a/src/main/java/com/zero/utils/ClassLoaderUtil.java b/src/main/java/com/zero/utils/ClassLoaderUtil.java deleted file mode 100644 index 988d4f4..0000000 --- a/src/main/java/com/zero/utils/ClassLoaderUtil.java +++ /dev/null @@ -1,591 +0,0 @@ -/** - * Copyright (c) 1997-2013, www.tinygroup.org (luo_guo@icloud.com). - * - * Licensed under the GPL, Version 3.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.gnu.org/licenses/gpl.html - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.zero.utils; - -import static com.zero.utils.CollectionUtil.createHashSet; -import static com.zero.utils.CollectionUtil.createLinkedList; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import com.zero.utils.exceptions.ClassInstantiationException; - -/** - *

- * 查找并装入类和资源的辅助类。 - *

- *

- * ClassLoaderUtil查找类和资源的效果, 相当于ClassLoader.loadClass - * 方法和ClassLoader.getResource方法。 但ClassLoaderUtil - * 总是首先尝试从Thread.getContextClassLoader()方法取得 - * ClassLoader中并装入类和资源。 这种方法避免了在多级ClassLoader - * 的情况下,找不到类或资源的情况。 - *

- *

- * 假设有如下情况: - *

- *
    - *
  • 工具类A是从系统ClassLoader装入的(classpath)
  • - *
  • B是Web Application中的一个类,是由servlet引擎的ClassLoader - * 动态装入的
  • - *
  • 资源文件C.properties也在Web Application中,只有servlet引擎的动态 - * ClassLoader可以找到它
  • - *
  • B调用工具类A的方法,希望通过类A取得资源文件 - * C.properties
  • - *
- *

- * 如果类A使用 - * getClass().getClassLoader().getResource("C.properties") - * , 就会失败,因为系统ClassLoader不能找到此资源。 - * 但类A可以使用ClassLoaderUtil.getResource("C.properties"),就可以找到这个资源, - * 因为ClassLoaderUtil调用Thread.currentThead().getContextClassLoader() - * 取得了servlet引擎的ClassLoader, 从而找到了这个资源文件。 - *

- * - * @author renhui - */ -public class ClassLoaderUtil { - - // ========================================================================== - // 取得context class loader的方法。 - // ========================================================================== - - /** - * 取得当前线程的ClassLoader。这个功能需要JDK1.2或更高版本的JDK的支持。 - * - * @return 当前线程的ClassLoader - */ - public static ClassLoader getContextClassLoader() { - return Thread.currentThread().getContextClassLoader(); - } - - // ========================================================================== - // 装入类的方法。 - // ========================================================================== - - /** - * 从当前线程的ClassLoader装入类。对于JDK1.2以下,则相当于 - * Class.forName。 - * - * @param className 要装入的类名 - * @return 已装入的类 - * @throws ClassNotFoundException 如果类没找到 - */ - public static Class loadClass(String className) throws ClassNotFoundException { - return loadClass(className, getContextClassLoader()); - } - - /** - * 从指定的调用者的ClassLoader装入类。 - * - * @param className 要装入的类名 - * @param referrer 调用者类,如果为null,则该方法相当于 - * Class.forName - * @return 已装入的类 - * @throws ClassNotFoundException 如果类没找到 - */ - public static Class loadClass(String className, Class referrer) throws ClassNotFoundException { - ClassLoader classLoader = getReferrerClassLoader(referrer); - - // 如果classLoader为null,表示从ClassLoaderUtil所在的classloader中装载, - // 这个classloader未必是System class loader。 - return loadClass(className, classLoader); - } - - /** - * 从指定的ClassLoader中装入类。如果未指定ClassLoader, 则从装载 - * ClassLoaderUtilClassLoader中装入。 - * - * @param className 要装入的类名 - * @param classLoader 从指定的ClassLoader中装入类,如果为null - * ,表示从ClassLoaderUtil所在的class loader中装载 - * @return 已装入的类 - * @throws ClassNotFoundException 如果类没找到 - */ - public static Class loadClass(String className, ClassLoader classLoader) throws ClassNotFoundException { - if (className == null) { - return null; - } - - if (classLoader == null) { - return Class.forName(className); - } else { - return Class.forName(className, true, classLoader); - } - } - - - /** - * 取得调用者的class loader。 - * - * @param referrer 调用者类 - * @return 调用者的class loader,如果referrer为null,则返回 - * null - */ - private static ClassLoader getReferrerClassLoader(Class referrer) { - ClassLoader classLoader = null; - - if (referrer != null) { - classLoader = referrer.getClassLoader(); - - // classLoader为null,说明referrer类是由bootstrap classloader装载的, - // 例如:java.lang.String - if (classLoader == null) { - classLoader = ClassLoader.getSystemClassLoader(); - } - } - - return classLoader; - } - - // ========================================================================== - // 装入并实例化类的方法。 - // ========================================================================== - - /** - * 从当前线程的ClassLoader装入类并实例化之。 - * - * @param className 要实例化的类名 - * @return 指定类名的实例 - * @throws ClassNotFoundException 如果类没找到 - * @throws ClassInstantiationException 如果实例化失败 - */ - public static Object newInstance(String className) throws ClassNotFoundException, ClassInstantiationException { - return newInstance(loadClass(className)); - } - - /** - * 从指定的调用者的ClassLoader装入类并实例化之。 - * - * @param className 要实例化的类名 - * @param referrer 调用者类,如果为null,则从ClassLoaderUtil - * 所在的class loader装载 - * @return 指定类名的实例 - * @throws ClassNotFoundException 如果类没找到 - * @throws ClassInstantiationException 如果实例化失败 - */ - public static Object newInstance(String className, Class referrer) throws ClassNotFoundException, - ClassInstantiationException { - return newInstance(loadClass(className, referrer)); - } - - /** - * 从指定的ClassLoader中装入类并实例化之。如果未指定ClassLoader, 则从装载 - * ClassLoaderUtilClassLoader中装入。 - * - * @param className 要实例化的类名 - * @param classLoader 从指定的ClassLoader中装入类,如果为null - * ,表示从ClassLoaderUtil所在的class loader中装载 - * @return 指定类名的实例 - * @throws ClassNotFoundException 如果类没找到 - * @throws ClassInstantiationException 如果实例化失败 - */ - public static Object newInstance(String className, ClassLoader classLoader) throws ClassNotFoundException, - ClassInstantiationException { - return newInstance(loadClass(className, classLoader)); - } - - /** - * 创建指定类的实例。 - * - * @param clazz 要创建实例的类 - * @return 指定类的实例 - * @throws ClassInstantiationException 如果实例化失败 - */ - private static Object newInstance(Class clazz) throws ClassInstantiationException { - if (clazz == null) { - return null; - } - - try { - return clazz.newInstance(); - } catch (InstantiationException e) { - throw new ClassInstantiationException("Failed to instantiate class: " + clazz.getName(), e); - } catch (IllegalAccessException e) { - throw new ClassInstantiationException("Failed to instantiate class: " + clazz.getName(), e); - } catch (Exception e) { - throw new ClassInstantiationException("Failed to instantiate class: " + clazz.getName(), e); - } - } - - // ========================================================================== - // 装入和查找资源文件的方法。 - // ========================================================================== - - /** - * 从ClassLoader取得所有resource URL。按如下顺序查找: - *
    - *
  1. 在当前线程的ClassLoader中查找。
  2. - *
  3. 在装入自己的ClassLoader中查找。
  4. - *
  5. 通过ClassLoader.getSystemResource方法查找。
  6. - *
- * - * @param resourceName 要查找的资源名,就是以"/"分隔的标识符字符串 - * @return resource的URL数组,如果没找到,则返回空数组。数组中保证不包含重复的URL。 - */ - public static URL[] getResources(String resourceName) { - List urls = createLinkedList(); - boolean found = false; - - // 首先试着从当前线程的ClassLoader中查找。 - found = getResources(urls, resourceName, getContextClassLoader(), false); - - // 如果没找到,试着从装入自己的ClassLoader中查找。 - if (!found) { - found = getResources(urls, resourceName, ClassLoaderUtil.class.getClassLoader(), false); - } - - // 最后的尝试: 在系统ClassLoader中查找(JDK1.2以上), - // 或者在JDK的内部ClassLoader中查找(JDK1.2以下)。 - if (!found) { - found = getResources(urls, resourceName, null, true); - } - - // 返回不重复的列表。 - return getDistinctURLs(urls); - } - - /** - * 从指定调用者所属的ClassLoader取得所有resource URL。 - * - * @param resourceName 要查找的资源名,就是以"/"分隔的标识符字符串 - * @param referrer 调用者类,如果为null,表示在ClassLoaderUtil - * 的class loader中找 - * @return resource的URL数组,如果没找到,则返回空数组。数组中保证不包含重复的URL。 - */ - public static URL[] getResources(String resourceName, Class referrer) { - ClassLoader classLoader = getReferrerClassLoader(referrer); - List urls = createLinkedList(); - - getResources(urls, resourceName, classLoader, classLoader == null); - - // 返回不重复的列表。 - return getDistinctURLs(urls); - } - - /** - * 从指定的ClassLoader中取得所有resource URL。如果未指定 - * ClassLoader, 则从装载ClassLoaderUtil的 - * ClassLoader中取得所有resource URL。 - * - * @param resourceName 要查找的资源名,就是以"/"分隔的标识符字符串 - * @param classLoader 从指定的ClassLoader中查找 - * @return resource的URL数组,如果没找到,则返回空数组。数组中保证不包含重复的URL。 - */ - public static URL[] getResources(String resourceName, ClassLoader classLoader) { - List urls = createLinkedList(); - - getResources(urls, resourceName, classLoader, classLoader == null); - - // 返回不重复的列表。 - return getDistinctURLs(urls); - } - - /** - * 在指定class loader中查找指定名称的resource,把所有找到的resource的URL放入指定的集合中。 - * - * @param urlSet 存放resource URL的集合 - * @param resourceName 资源名 - * @param classLoader 类装入器 - * @param sysClassLoader 是否用system class loader装载资源 - * @return 如果找到,则返回true - */ - private static boolean getResources(List urlSet, String resourceName, ClassLoader classLoader, - boolean sysClassLoader) { - if (resourceName == null) { - return false; - } - - Enumeration i = null; - - try { - if (classLoader != null) { - i = classLoader.getResources(resourceName); - } else if (sysClassLoader) { - i = ClassLoader.getSystemResources(resourceName); - } - } catch (IOException e) { - } - - if (i != null && i.hasMoreElements()) { - while (i.hasMoreElements()) { - urlSet.add(i.nextElement()); - } - - return true; - } - - return false; - } - - /** - * 去除URL列表中的重复项。 - * - * @param urls URL列表 - * @return 不重复的URL数组,如果urls为null,则返回空数组 - */ - private static URL[] getDistinctURLs(List urls) { - if (urls == null || urls.size() == 0) { - return new URL[0]; - } - - Set urlSet = createHashSet(); - - for (Iterator i = urls.iterator(); i.hasNext(); ) { - URL url = i.next(); - - if (urlSet.contains(url)) { - i.remove(); - } else { - urlSet.add(url); - } - } - - return urls.toArray(new URL[urls.size()]); - } - - /** - *

- * 从ClassLoader取得resource URL。按如下顺序查找: - *

- *
    - *
  1. 在当前线程的ClassLoader中查找。
  2. - *
  3. 在装入自己的ClassLoader中查找。
  4. - *
  5. 通过ClassLoader.getSystemResource方法查找。
  6. - *
- * - * @param resourceName 要查找的资源名,就是以"/"分隔的标识符字符串 - * @return resource的URL - */ - public static URL getResource(String resourceName) { - if (resourceName == null) { - return null; - } - - ClassLoader classLoader = null; - URL url = null; - - // 首先试着从当前线程的ClassLoader中查找。 - classLoader = getContextClassLoader(); - - if (classLoader != null) { - url = classLoader.getResource(resourceName); - - if (url != null) { - return url; - } - } - - // 如果没找到,试着从装入自己的ClassLoader中查找。 - classLoader = ClassLoaderUtil.class.getClassLoader(); - - if (classLoader != null) { - url = classLoader.getResource(resourceName); - - if (url != null) { - return url; - } - } - - // 最后的尝试: 在系统ClassLoader中查找(JDK1.2以上), - // 或者在JDK的内部ClassLoader中查找(JDK1.2以下)。 - return ClassLoader.getSystemResource(resourceName); - } - - /** - * 从指定调用者所属的ClassLoader取得resource URL。 - * - * @param resourceName 要查找的资源名,就是以"/"分隔的标识符字符串 - * @param referrer 调用者类,如果为null,表示在ClassLoaderUtil - * 的class loader中找。 - * @return resource URL,如果没找到,则返回null - */ - public static URL getResource(String resourceName, Class referrer) { - if (resourceName == null) { - return null; - } - - ClassLoader classLoader = getReferrerClassLoader(referrer); - - return classLoader == null ? ClassLoaderUtil.class.getClassLoader().getResource(resourceName) : classLoader - .getResource(resourceName); - } - - /** - * 从指定的ClassLoader取得resource URL。 - * - * @param resourceName 要查找的资源名,就是以"/"分隔的标识符字符串 - * @param classLoader 在指定classLoader中查找,如果为null,表示在 - * ClassLoaderUtil的class loader中找。 - * @return resource URL,如果没找到,则返回null - */ - public static URL getResource(String resourceName, ClassLoader classLoader) { - if (resourceName == null) { - return null; - } - - return classLoader == null ? ClassLoaderUtil.class.getClassLoader().getResource(resourceName) : classLoader - .getResource(resourceName); - } - - /** - * 从ClassLoader取得resource的输入流。 相当于 - * getResource(resourceName).openStream()。 - * - * @param resourceName 要查找的资源名,就是以"/"分隔的标识符字符串 - * @return resource的输入流 - */ - public static InputStream getResourceAsStream(String resourceName) { - URL url = getResource(resourceName); - - try { - if (url != null) { - return url.openStream(); - } - } catch (IOException e) { - // 打开URL失败。 - } - - return null; - } - - /** - * 从ClassLoader取得resource的输入流。 相当于 - * getResource(resourceName, - * referrer).openStream()。 - * - * @param resourceName 要查找的资源名,就是以"/"分隔的标识符字符串 - * @param referrer 调用者类,如果为null,表示在ClassLoaderUtil - * 的class loader中找。 - * @return resource的输入流 - */ - public static InputStream getResourceAsStream(String resourceName, Class referrer) { - URL url = getResource(resourceName, referrer); - - try { - if (url != null) { - return url.openStream(); - } - } catch (IOException e) { - // 打开URL失败。 - } - - return null; - } - - /** - * 从ClassLoader取得resource的输入流。 相当于 - * getResource(resourceName, - * classLoader).openStream()。 - * - * @param resourceName 要查找的资源名,就是以"/"分隔的标识符字符串 - * @param classLoader 在指定classLoader中查找,如果为null,表示在 - * ClassLoaderUtil的class loader中找。 - * @return resource的输入流 - */ - public static InputStream getResourceAsStream(String resourceName, ClassLoader classLoader) { - URL url = getResource(resourceName, classLoader); - - try { - if (url != null) { - return url.openStream(); - } - } catch (IOException e) { - // 打开URL失败。 - } - - return null; - } - - // ========================================================================== - // 查找class的位置。 - // - // 类似于UNIX的which方法。 - // ========================================================================== - - /** - * 从当前线程的ClassLoader中查找指定名称的类。 - * - * @param className 要查找的类名 - * @return URL数组,列举了系统中所有可找到的同名类,如果未找到,则返回一个空数组 - */ - public static URL[] whichClasses(String className) { - return getResources(ClassUtil.getResourceNameForClass(className)); - } - - /** - * 从当前线程的ClassLoader中查找指定名称的类。 - * - * @param className 要查找的类名 - * @param referrer 调用者类,如果为null,表示在ClassLoaderUtil - * 的class loader中找。 - * @return URL数组,列举了系统中所有可找到的同名类,如果未找到,则返回一个空数组 - */ - public static URL[] whichClasses(String className, Class referrer) { - return getResources(ClassUtil.getResourceNameForClass(className), referrer); - } - - /** - * 从当前线程的ClassLoader中查找指定名称的类。 - * - * @param className 要查找的类名 - * @param classLoader 在指定classLoader中查找,如果为null,表示在 - * ClassLoaderUtil的class loader中找。 - * @return URL数组,列举了系统中所有可找到的同名类,如果未找到,则返回一个空数组 - */ - public static URL[] whichClasses(String className, ClassLoader classLoader) { - return getResources(ClassUtil.getResourceNameForClass(className), classLoader); - } - - /** - * 从当前线程的ClassLoader中查找指定名称的类。 - * - * @param className 要查找的类名 - * @return 类文件的URL,如果未找到,则返回null - */ - public static URL whichClass(String className) { - return getResource(ClassUtil.getResourceNameForClass(className)); - } - - /** - * 从当前线程的ClassLoader中查找指定名称的类。 - * - * @param className 要查找的类名 - * @param referrer 调用者类,如果为null,表示在ClassLoaderUtil - * 的class loader中找。 - * @return 类文件的URL,如果未找到,则返回null - */ - public static URL whichClass(String className, Class referrer) { - return getResource(ClassUtil.getResourceNameForClass(className), referrer); - } - - /** - * 从当前线程的ClassLoader中查找指定名称的类。 - * - * @param className 要查找的类名 - * @param classLoader 在指定classLoader中查找,如果为null,表示在 - * ClassLoaderUtil的class loader中找。 - * @return 类文件的URL,如果未找到,则返回null - */ - public static URL whichClass(String className, ClassLoader classLoader) { - return getResource(ClassUtil.getResourceNameForClass(className), classLoader); - } -} diff --git a/src/main/java/com/zero/utils/ClassPathUtil.java b/src/main/java/com/zero/utils/ClassPathUtil.java deleted file mode 100644 index 385a529..0000000 --- a/src/main/java/com/zero/utils/ClassPathUtil.java +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (c) 1997-2013, www.tinygroup.org (luo_guo@icloud.com). - * - * Licensed under the GPL, Version 3.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.gnu.org/licenses/gpl.html - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.zero.utils; - -/** - * 获取程序类根路径 - * @author renhui - * - */ -public final class ClassPathUtil { - private static final String SLASH_MARK="/"; - - public static String getClassRootPath(){ - return ClassPathUtil.class.getResource(SLASH_MARK).getPath(); - } - - -} diff --git a/src/main/java/com/zero/utils/ClassUtil.java b/src/main/java/com/zero/utils/ClassUtil.java deleted file mode 100644 index c2f7a82..0000000 --- a/src/main/java/com/zero/utils/ClassUtil.java +++ /dev/null @@ -1,1281 +0,0 @@ -package com.zero.utils; - - -import static com.zero.utils.ArrayUtil.isArraySameLength; -import static com.zero.utils.ArrayUtil.isEmptyArray; -import static com.zero.utils.Assert.assertNotNull; -import static com.zero.utils.Assert.assertTrue; -import static com.zero.utils.BasicConstant.EMPTY_CLASS_ARRAY; -import static com.zero.utils.BasicConstant.EMPTY_STRING; -import static com.zero.utils.CollectionUtil.createHashMap; -import static com.zero.utils.CollectionUtil.createHashSet; -import static com.zero.utils.StringUtil.trimToNull; - -import java.beans.Introspector; -import java.lang.reflect.Array; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.net.URL; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; - - - -/** - * 有关 Class 处理的工具类。 - *

- * 这个类中的每个方法都可以“安全”地处理 null ,而不会抛出 - * NullPointerException。 - *

- - * @author renhui - * - */ -public class ClassUtil { - - /** Suffix for array class names: "[]" */ - public static final String ARRAY_SUFFIX = "[]"; - - /** The package separator character '.' */ - private static final char PACKAGE_SEPARATOR = '.'; - - /** The inner class separator character '$' */ - private static final char INNER_CLASS_SEPARATOR = '$'; - - /** The CGLIB class separator character "$$" */ - public static final String CGLIB_CLASS_SEPARATOR = "$$"; - - /** The ".class" file suffix */ - public static final String CLASS_FILE_SUFFIX = ".class"; - - /** - * 从接口端计算深度 - * @param pInterface - * @param targetClass - * @return - */ - public static int checkInterfaceDeepth(Class pInterface, - Class targetClass) { - if (targetClass.isAssignableFrom(pInterface)) - return 0; - int min = -1; - for (Class c : targetClass.getInterfaces()) { - if (pInterface.isAssignableFrom(c)) { - int i = checkInterfaceDeepth(pInterface, c) + 1; - if (min == -1 || min > i) { - min = i; - } - } - } - return min; - } - - /** - * @param supperClass - * @param targetClass - * @return - */ - public static int checkSupperClassDeepth(Class supperClass, - Class targetClass) { - if (!supperClass.isAssignableFrom(targetClass)) { - return -1; - } - if (targetClass.isAssignableFrom(supperClass)) - return 0; - int supperDeepth = checkSupperClassDeepth(supperClass, - targetClass.getSuperclass()) + 1; - int interfaceDeepth = checkInterfaceDeepth(supperClass, - targetClass.getSuperclass()) + 1; - if (supperDeepth < interfaceDeepth) - return supperDeepth; - return interfaceDeepth; - } - - /** - * 采取驼峰规则 - * - * @param simpleName - * @return - */ - public static String humpString(Class clazz) { - String simpleName = clazz.getSimpleName(); - String first = simpleName.charAt(0) + ""; - return first.toLowerCase() + simpleName.substring(1); - } - - // ========================================================================== - // 取得友好类名和package名的方法。 - // ========================================================================== - - /** - * 取得对象所属的类的友好类名。 - *

- * 类似object.getClass().getName(),但不同的是,该方法用更友好的方式显示数组类型。 例如: - *

- *

- *

-     *  int[].class.getName() = "[I"
-     *  ClassUtil.getFriendlyClassName(int[].class) = "int[]"
-     *
-     *  Integer[][].class.getName() = "[[Ljava.lang.Integer;"
-     *  ClassUtil.getFriendlyClassName(Integer[][].class) = "java.lang.Integer[][]"
-     * 
- *

- * 对于非数组的类型,该方法等效于 Class.getName() 方法。 - *

- *

- * 注意,该方法所返回的数组类名只能用于显示给人看,不能用于 Class.forName 操作。 - *

- * - * @param object 要显示类名的对象 - * @return 用于显示的友好类名,如果对象为空,则返回null - */ - public static String getFriendlyClassNameForObject(Object object) { - if (object == null) { - return null; - } - - String javaClassName = object.getClass().getName(); - - return toFriendlyClassName(javaClassName, true, javaClassName); - } - - /** - * 取得友好的类名。 - *

- * 类似clazz.getName(),但不同的是,该方法用更友好的方式显示数组类型。 例如: - *

- *

- *

-     *  int[].class.getName() = "[I"
-     *  ClassUtil.getFriendlyClassName(int[].class) = "int[]"
-     *
-     *  Integer[][].class.getName() = "[[Ljava.lang.Integer;"
-     *  ClassUtil.getFriendlyClassName(Integer[][].class) = "java.lang.Integer[][]"
-     * 
- *

- * 对于非数组的类型,该方法等效于 Class.getName() 方法。 - *

- *

- * 注意,该方法所返回的数组类名只能用于显示给人看,不能用于 Class.forName 操作。 - *

- * - * @param object 要显示类名的对象 - * @return 用于显示的友好类名,如果类对象为空,则返回null - */ - public static String getFriendlyClassName(Class clazz) { - if (clazz == null) { - return null; - } - - String javaClassName = clazz.getName(); - - return toFriendlyClassName(javaClassName, true, javaClassName); - } - - /** - * 取得友好的类名。 - *

- * className 必须是从 clazz.getName() - * 所返回的合法类名。该方法用更友好的方式显示数组类型。 例如: - *

- *

- *

-     *  int[].class.getName() = "[I"
-     *  ClassUtil.getFriendlyClassName(int[].class) = "int[]"
-     *
-     *  Integer[][].class.getName() = "[[Ljava.lang.Integer;"
-     *  ClassUtil.getFriendlyClassName(Integer[][].class) = "java.lang.Integer[][]"
-     * 
- *

- * 对于非数组的类型,该方法等效于 Class.getName() 方法。 - *

- *

- * 注意,该方法所返回的数组类名只能用于显示给人看,不能用于 Class.forName 操作。 - *

- * - * @param javaClassName 要转换的类名 - * @return 用于显示的友好类名,如果原类名为空,则返回 null ,如果原类名是非法的,则返回原类名 - */ - public static String getFriendlyClassName(String javaClassName) { - return toFriendlyClassName(javaClassName, true, javaClassName); - } - - /** - * 将Java类名转换成友好类名。 - * - * @param javaClassName Java类名 - * @param processInnerClass 是否将内联类分隔符 '$' 转换成 '.' - * @return 友好的类名。如果参数非法或空,则返回null。 - */ - private static String toFriendlyClassName(String javaClassName, boolean processInnerClass, String defaultIfInvalid) { - String name = StringUtil.trimToNull(javaClassName); - - if (name == null) { - return defaultIfInvalid; - } - - if (processInnerClass) { - name = name.replace('$', '.'); - } - - int length = name.length(); - int dimension = 0; - - // 取得数组的维数,如果不是数组,维数为0 - for (int i = 0; i < length; i++, dimension++) { - if (name.charAt(i) != '[') { - break; - } - } - - // 如果不是数组,则直接返回 - if (dimension == 0) { - return name; - } - - // 确保类名合法 - if (length <= dimension) { - return defaultIfInvalid; // 非法类名 - } - - // 处理数组 - StringBuilder componentTypeName = new StringBuilder(); - - switch (name.charAt(dimension)) { - case 'Z': - componentTypeName.append("boolean"); - break; - - case 'B': - componentTypeName.append("byte"); - break; - - case 'C': - componentTypeName.append("char"); - break; - - case 'D': - componentTypeName.append("double"); - break; - - case 'F': - componentTypeName.append("float"); - break; - - case 'I': - componentTypeName.append("int"); - break; - - case 'J': - componentTypeName.append("long"); - break; - - case 'S': - componentTypeName.append("short"); - break; - - case 'L': - if (name.charAt(length - 1) != ';' || length <= dimension + 2) { - return defaultIfInvalid; // 非法类名 - } - - componentTypeName.append(name.substring(dimension + 1, length - 1)); - break; - - default: - return defaultIfInvalid; // 非法类名 - } - - for (int i = 0; i < dimension; i++) { - componentTypeName.append("[]"); - } - - return componentTypeName.toString(); - } - - /** - * 取得指定对象所属的类的简单类名,不包括package名。 - *

- * 此方法可以正确显示数组和内联类的名称。 例如: - *

- *

-     *  ClassUtil.getSimpleClassNameForObject(Boolean.TRUE) = "Boolean"
-     *  ClassUtil.getSimpleClassNameForObject(new Boolean[10]) = "Boolean[]"
-     *  ClassUtil.getSimpleClassNameForObject(new int[1][2]) = "int[][]"
-     * 
- *

- * 本方法和Class.getSimpleName()的区别在于,本方法会保留inner类的外层类名称。 - *

- * - * @param object 要查看的对象 - * @return 简单类名,如果对象为 null ,则返回 null - */ - public static String getSimpleClassNameForObject(Object object) { - if (object == null) { - return null; - } - - return getSimpleClassName(object.getClass().getName()); - } - - /** - * 取得指定对象所属的类的简单类名,不包括package名。 - *

- * 此方法可以正确显示数组和内联类的名称。 例如: - *

- *

-     *  ClassUtil.getSimpleClassNameForObject(Boolean.TRUE) = "Boolean"
-     *  ClassUtil.getSimpleClassNameForObject(new Boolean[10]) = "Boolean[]"
-     *  ClassUtil.getSimpleClassNameForObject(new int[1][2]) = "int[][]"
-     * 
- *

- * 本方法和Class.getSimpleName()的区别在于,本方法会保留inner类的外层类名称。 - *

- * - * @param object 要查看的对象 - * @return 简单类名,如果对象为 null ,则返回 null - */ - public static String getSimpleClassNameForObject(Object object, boolean processInnerClass) { - if (object == null) { - return null; - } - - return getSimpleClassName(object.getClass().getName(), processInnerClass); - } - - /** - * 取得简单类名,不包括package名。 - *

- * 此方法可以正确显示数组和内联类的名称。 例如: - *

- *

-     *  ClassUtil.getSimpleClassName(Boolean.class) = "Boolean"
-     *  ClassUtil.getSimpleClassName(Boolean[].class) = "Boolean[]"
-     *  ClassUtil.getSimpleClassName(int[][].class) = "int[][]"
-     *  ClassUtil.getSimpleClassName(Map.Entry.class) = "Map.Entry"
-     * 
- *

- * 本方法和Class.getSimpleName()的区别在于,本方法会保留inner类的外层类名称。 - *

- * - * @param clazz 要查看的类 - * @return 简单类名,如果类为 null ,则返回 null - */ - public static String getSimpleClassName(Class clazz) { - if (clazz == null) { - return null; - } - - return getSimpleClassName(clazz.getName()); - } - - /** - * 取得简单类名,不包括package名。 - *

- * 此方法可以正确显示数组和内联类的名称。 例如: - *

- *

-     *  ClassUtil.getSimpleClassName(Boolean.class) = "Boolean"
-     *  ClassUtil.getSimpleClassName(Boolean[].class) = "Boolean[]"
-     *  ClassUtil.getSimpleClassName(int[][].class) = "int[][]"
-     *  ClassUtil.getSimpleClassName(Map.Entry.class) = "Map.Entry"
-     * 
- *

- * 本方法和Class.getSimpleName()的区别在于,本方法会保留inner类的外层类名称。 - *

- * - * @param clazz 要查看的类 - * @return 简单类名,如果类为 null ,则返回 null - */ - public static String getSimpleClassName(Class clazz, boolean proccessInnerClass) { - if (clazz == null) { - return null; - } - - return getSimpleClassName(clazz.getName(), proccessInnerClass); - } - - /** - * 取得类名,不包括package名。 - *

- * 此方法可以正确显示数组和内联类的名称。 例如: - *

- *

-     *  ClassUtil.getSimpleClassName(Boolean.class.getName()) = "Boolean"
-     *  ClassUtil.getSimpleClassName(Boolean[].class.getName()) = "Boolean[]"
-     *  ClassUtil.getSimpleClassName(int[][].class.getName()) = "int[][]"
-     *  ClassUtil.getSimpleClassName(Map.Entry.class.getName()) = "Map.Entry"
-     * 
- *

- * 本方法和Class.getSimpleName()的区别在于,本方法会保留inner类的外层类名称。 - *

- * - * @param javaClassName 要查看的类名 - * @return 简单类名,如果类名为空,则返回 null - */ - public static String getSimpleClassName(String javaClassName) { - return getSimpleClassName(javaClassName, true); - } - - /** - * 取得类名,不包括package名。 - *

- * 此方法可以正确显示数组和内联类的名称。 例如: - *

- *

-     *  ClassUtil.getSimpleClassName(Boolean.class.getName()) = "Boolean"
-     *  ClassUtil.getSimpleClassName(Boolean[].class.getName()) = "Boolean[]"
-     *  ClassUtil.getSimpleClassName(int[][].class.getName()) = "int[][]"
-     *  ClassUtil.getSimpleClassName(Map.Entry.class.getName()) = "Map.Entry"
-     * 
- *

- * 本方法和Class.getSimpleName()的区别在于,本方法会保留inner类的外层类名称。 - *

- * - * @param javaClassName 要查看的类名 - * @return 简单类名,如果类名为空,则返回 null - */ - public static String getSimpleClassName(String javaClassName, boolean proccesInnerClass) { - String friendlyClassName = toFriendlyClassName(javaClassName, false, null); - - if (friendlyClassName == null) { - return javaClassName; - } - - if (proccesInnerClass) { - char[] chars = friendlyClassName.toCharArray(); - int beginIndex = 0; - - for (int i = chars.length - 1; i >= 0; i--) { - if (chars[i] == '.') { - beginIndex = i + 1; - break; - } else if (chars[i] == '$') { - chars[i] = '.'; - } - } - - return new String(chars, beginIndex, chars.length - beginIndex); - } else { - return friendlyClassName.substring(friendlyClassName.lastIndexOf(".") + 1); - } - } - - /** 取得简洁的method描述。 */ - public static String getSimpleMethodSignature(Method method) { - return getSimpleMethodSignature(method, false, false, false, false); - } - - /** 取得简洁的method描述。 */ - public static String getSimpleMethodSignature(Method method, boolean withClassName) { - return getSimpleMethodSignature(method, false, false, withClassName, false); - } - - /** 取得简洁的method描述。 */ - public static String getSimpleMethodSignature(Method method, boolean withModifiers, boolean withReturnType, - boolean withClassName, boolean withExceptionType) { - if (method == null) { - return null; - } - - StringBuilder buf = new StringBuilder(); - - if (withModifiers) { - buf.append(Modifier.toString(method.getModifiers())).append(' '); - } - - if (withReturnType) { - buf.append(getSimpleClassName(method.getReturnType())).append(' '); - } - - if (withClassName) { - buf.append(getSimpleClassName(method.getDeclaringClass())).append('.'); - } - - buf.append(method.getName()).append('('); - - Class[] paramTypes = method.getParameterTypes(); - - for (int i = 0; i < paramTypes.length; i++) { - Class paramType = paramTypes[i]; - - buf.append(getSimpleClassName(paramType)); - - if (i < paramTypes.length - 1) { - buf.append(", "); - } - } - - buf.append(')'); - - if (withExceptionType) { - Class[] exceptionTypes = method.getExceptionTypes(); - - if (!isEmptyArray(exceptionTypes)) { - buf.append(" throws "); - - for (int i = 0; i < exceptionTypes.length; i++) { - Class exceptionType = exceptionTypes[i]; - - buf.append(getSimpleClassName(exceptionType)); - - if (i < exceptionTypes.length - 1) { - buf.append(", "); - } - } - } - } - - return buf.toString(); - } - - /** - * 取得指定对象所属的类的package名。 - *

- * 对于数组,此方法返回的是数组元素类型的package名。 - *

- * - * @param object 要查看的对象 - * @return package名,如果对象为 null ,则返回"" - */ - public static String getPackageNameForObject(Object object) { - if (object == null) { - return EMPTY_STRING; - } - - return getPackageName(object.getClass().getName()); - } - - /** - * 取得指定类的package名。 - *

- * 对于数组,此方法返回的是数组元素类型的package名。 - *

- * - * @param clazz 要查看的类 - * @return package名,如果类为 null ,则返回"" - */ - public static String getPackageName(Class clazz) { - if (clazz == null) { - return EMPTY_STRING; - } - - return getPackageName(clazz.getName()); - } - - /** - * 取得指定类名的package名。 - *

- * 对于数组,此方法返回的是数组元素类型的package名。 - *

- * - * @param javaClassName 要查看的类名 - * @return package名,如果类名为空,则返回 null - */ - public static String getPackageName(String javaClassName) { - String friendlyClassName = toFriendlyClassName(javaClassName, false, null); - - if (friendlyClassName == null) { - return EMPTY_STRING; - } - - int i = friendlyClassName.lastIndexOf('.'); - - if (i == -1) { - return EMPTY_STRING; - } - - return friendlyClassName.substring(0, i); - } - - // ========================================================================== - // 取得类名和package名的resource名的方法。 - // - // 和类名、package名不同的是,resource名符合文件名命名规范,例如: - // java/lang/String.class - // com/alibaba/commons/lang - // etc. - // ========================================================================== - - /** - * 取得对象所属的类的资源名。 - *

- * 例如: - *

- *

- *

-     * ClassUtil.getResourceNameForObjectClass("This is a string") = "java/lang/String.class"
-     * 
- * - * @param object 要显示类名的对象 - * @return 指定对象所属类的资源名,如果对象为空,则返回null - */ - public static String getResourceNameForObjectClass(Object object) { - if (object == null) { - return null; - } - - return object.getClass().getName().replace('.', '/') + ".class"; - } - - /** - * 取得指定类的资源名。 - *

- * 例如: - *

- *

- *

-     * ClassUtil.getResourceNameForClass(String.class) = "java/lang/String.class"
-     * 
- * - * @param clazz 要显示类名的类 - * @return 指定类的资源名,如果指定类为空,则返回null - */ - public static String getResourceNameForClass(Class clazz) { - if (clazz == null) { - return null; - } - - return clazz.getName().replace('.', '/') + ".class"; - } - - /** - * 取得指定类的资源名。 - *

- * 例如: - *

- *

- *

-     * ClassUtil.getResourceNameForClass("java.lang.String") = "java/lang/String.class"
-     * 
- * - * @param className 要显示的类名 - * @return 指定类名对应的资源名,如果指定类名为空,则返回null - */ - public static String getResourceNameForClass(String className) { - if (className == null) { - return null; - } - - return className.replace('.', '/') + ".class"; - } - - /** - * 取得指定对象所属的类的package名的资源名。 - *

- * 对于数组,此方法返回的是数组元素类型的package名。 - *

- * - * @param object 要查看的对象 - * @return package名,如果对象为 null ,则返回 null - */ - public static String getResourceNameForObjectPackage(Object object) { - if (object == null) { - return null; - } - - return getPackageNameForObject(object).replace('.', '/'); - } - - /** - * 取得指定类的package名的资源名。 - *

- * 对于数组,此方法返回的是数组元素类型的package名。 - *

- * - * @param clazz 要查看的类 - * @return package名,如果类为 null ,则返回 null - */ - public static String getResourceNameForPackage(Class clazz) { - if (clazz == null) { - return null; - } - - return getPackageName(clazz).replace('.', '/'); - } - - /** - * 取得指定类名的package名的资源名。 - *

- * 对于数组,此方法返回的是数组元素类型的package名。 - *

- * - * @param className 要查看的类名 - * @return package名,如果类名为空,则返回 null - */ - public static String getResourceNameForPackage(String className) { - if (className == null) { - return null; - } - - return getPackageName(className).replace('.', '/'); - } - - // ========================================================================== - // 取得数组类。 - // ========================================================================== - - /** - * 取得指定一维数组类. - * - * @param componentType 数组的基础类 - * @return 数组类,如果数组的基类为 null ,则返回 null - */ - public static Class getArrayClass(Class componentType) { - return getArrayClass(componentType, 1); - } - - /** - * 取得指定维数的 Array类. - * - * @param componentType 数组的基类 - * @param dimension 维数,如果小于 0 则看作 0 - * @return 如果维数为0, 则返回基类本身, 否则返回数组类,如果数组的基类为 null ,则返回 - * null - */ - public static Class getArrayClass(Class componentClass, int dimension) { - if (componentClass == null) { - return null; - } - - switch (dimension) { - case 1: - return Array.newInstance(componentClass, 0).getClass(); - - case 0: - return componentClass; - - default: - assertTrue(dimension > 0, "wrong dimension: %d", dimension); - - return Array.newInstance(componentClass, new int[dimension]).getClass(); - } - } - - // ========================================================================== - // 取得原子类型或者其wrapper类。 - // ========================================================================== - - /** - * 取得primitive类。 - *

- * 例如: - *

- *

-     * ClassUtil.getPrimitiveType("int") = int.class;
-     * ClassUtil.getPrimitiveType("long") = long.class;
-     * 
- *

- *

- */ - public static Class getPrimitiveType(String name) { - PrimitiveInfo info = PRIMITIVES.get(name); - - if (info != null) { - return info.type; - } - - return null; - } - - /** - * 取得primitive类。 - *

- * 例如: - *

- *

-     * ClassUtil.getPrimitiveType(Integer.class) = int.class;
-     * ClassUtil.getPrimitiveType(Long.class) = long.class;
-     * 
- *

- *

- */ - public static Class getPrimitiveType(Class type) { - return getPrimitiveType(type.getName()); - } - - /** - * 取得primitive类型的wrapper。如果不是primitive,则原样返回。 - *

- * 例如: - *

- *

-     * ClassUtil.getPrimitiveWrapperType(int.class) = Integer.class;
-     * ClassUtil.getPrimitiveWrapperType(int[].class) = int[].class;
-     * ClassUtil.getPrimitiveWrapperType(int[][].class) = int[][].class;
-     * ClassUtil.getPrimitiveWrapperType(String[][].class) = String[][].class;
-     * 
- *

- *

- */ - @SuppressWarnings("unchecked") - public static Class getWrapperTypeIfPrimitive(Class type) { - if (type.isPrimitive()) { - return ((PrimitiveInfo) PRIMITIVES.get(type.getName())).wrapperType; - } - - return type; - } - - /** - * 取得primitive类型的默认值。如果不是primitive,则返回null。 - *

- * 例如: - *

- *

-     * ClassUtil.getPrimitiveDefaultValue(int.class) = 0;
-     * ClassUtil.getPrimitiveDefaultValue(boolean.class) = false;
-     * ClassUtil.getPrimitiveDefaultValue(char.class) = '\0';
-     * 
- *

- *

- */ - @SuppressWarnings("unchecked") - public static T getPrimitiveDefaultValue(Class type) { - PrimitiveInfo info = (PrimitiveInfo) PRIMITIVES.get(type.getName()); - - if (info != null) { - return info.defaultValue; - } - - return null; - } - - private static final Map> PRIMITIVES = createHashMap(); - - static { - addPrimitive(boolean.class, "Z", Boolean.class, "booleanValue", false); - addPrimitive(short.class, "S", Short.class, "shortValue", (short) 0); - addPrimitive(int.class, "I", Integer.class, "intValue", 0); - addPrimitive(long.class, "J", Long.class, "longValue", 0L); - addPrimitive(float.class, "F", Float.class, "floatValue", 0F); - addPrimitive(double.class, "D", Double.class, "doubleValue", 0D); - addPrimitive(char.class, "C", Character.class, "charValue", '\0'); - addPrimitive(byte.class, "B", Byte.class, "byteValue", (byte) 0); - addPrimitive(void.class, "V", Void.class, null, null); - } - - private static void addPrimitive(Class type, String typeCode, Class wrapperType, String unwrapMethod, - T defaultValue) { - PrimitiveInfo info = new PrimitiveInfo(type, typeCode, wrapperType, unwrapMethod, defaultValue); - - PRIMITIVES.put(type.getName(), info); - PRIMITIVES.put(wrapperType.getName(), info); - } - - /** 代表一个primitive类型的信息。 */ - @SuppressWarnings("unused") - private static class PrimitiveInfo { - final Class type; - final String typeCode; - final Class wrapperType; - final String unwrapMethod; - final T defaultValue; - - public PrimitiveInfo(Class type, String typeCode, Class wrapperType, String unwrapMethod, T defaultValue) { - this.type = type; - this.typeCode = typeCode; - this.wrapperType = wrapperType; - this.unwrapMethod = unwrapMethod; - this.defaultValue = defaultValue; - } - } - - // ========================================================================== - // 类型匹配。 - // ========================================================================== - - /** - * 检查一组指定类型 fromClasses 的对象是否可以赋值给另一组类型 classes。 - *

- * 此方法可以用来确定指定类型的参数 object1, object2, ... 是否可以用来调用确定参数类型为 - * class1, class2, - * ... 的方法。 - *

- *

- * 对于 fromClasses 的每个元素 fromClass 和 - * classes 的每个元素 clazz, 按照如下规则: - *

    - *
  1. 如果目标类 clazznull ,总是返回 false - * 。
  2. - *
  3. 如果参数类型 fromClassnull ,并且目标类型 - * clazz 为非原子类型,则返回 true。 因为 null - * 可以被赋给任何引用类型。
  4. - *
  5. 调用 Class.isAssignableFrom 方法来确定目标类 clazz - * 是否和参数类 fromClass 相同或是其父类、接口,如果是,则返回 true
  6. - *
  7. 如果目标类型 clazz 为原子类型,那么根据 The Java Language - * Specification ,sections 5.1.1, 5.1.2, 5.1.4定义的Widening Primitive - * Conversion规则,参数类型 fromClass 可以是任何能扩展成该目标类型的原子类型及其包装类。 例如, - * clazzlong ,那么参数类型可以是 byte、 - * shortintlongchar - * 及其包装类 java.lang.Bytejava.lang.Short、 - * java.lang.Integerjava.lang.Long 和 - * java.lang.Character 。如果满足这个条件,则返回 true
  8. - *
  9. 不满足上述所有条件,则返回 false
  10. - *
- *

- * - * @param classes 目标类型列表,如果是 null 总是返回 false - * @param fromClasses 参数类型列表, null 表示可赋值给任意非原子类型 - * @return 如果可以被赋值,则返回 true - */ - public static boolean isAssignable(Class[] classes, Class[] fromClasses) { - if (!isArraySameLength(fromClasses, classes)) { - return false; - } - - if (fromClasses == null) { - fromClasses = EMPTY_CLASS_ARRAY; - } - - if (classes == null) { - classes = EMPTY_CLASS_ARRAY; - } - - for (int i = 0; i < fromClasses.length; i++) { - if (isAssignable(classes[i], fromClasses[i]) == false) { - return false; - } - } - - return true; - } - - /** - * 检查指定类型 fromClass 的对象是否可以赋值给另一种类型 clazz。 - *

- * 此方法可以用来确定指定类型的参数 object1, object2, ... 是否可以用来调用确定参数类型 - * class1, class2, - * ... 的方法。 - *

- *

- * 按照如下规则: - *

    - *
  1. 如果目标类 clazznull ,总是返回 false - * 。
  2. - *
  3. 如果参数类型 fromClassnull ,并且目标类型 - * clazz 为非原子类型,则返回 true。 因为 null - * 可以被赋给任何引用类型。
  4. - *
  5. 调用 Class.isAssignableFrom 方法来确定目标类 clazz - * 是否和参数类 fromClass 相同或是其父类、接口,如果是,则返回 true
  6. - *
  7. 如果目标类型 clazz 为原子类型,那么根据 The Java Language - * Specification ,sections 5.1.1, 5.1.2, 5.1.4定义的Widening Primitive - * Conversion规则,参数类型 fromClass 可以是任何能扩展成该目标类型的原子类型及其包装类。 例如, - * clazzlong ,那么参数类型可以是 byte、 - * shortintlongchar - * 及其包装类 java.lang.Bytejava.lang.Short、 - * java.lang.Integerjava.lang.Long 和 - * java.lang.Character 。如果满足这个条件,则返回 true
  8. - *
  9. 不满足上述所有条件,则返回 false
  10. - *
- *

- * - * @param clazz 目标类型,如果是 null 总是返回 false - * @param fromClass 参数类型, null 表示可赋值给任意非原子类型 - * @return 如果可以被赋值,则返回 null - */ - public static boolean isAssignable(Class clazz, Class fromClass) { - if (clazz == null) { - return false; - } - - // 如果fromClass是null,只要clazz不是原子类型如int,就一定可以赋值 - if (fromClass == null) { - return !clazz.isPrimitive(); - } - - // 如果类相同或有父子关系,当然可以赋值 - if (clazz.isAssignableFrom(fromClass)) { - return true; - } - - // 对于原子类型,根据JLS的规则进行扩展 - // 目标class为原子类型时,fromClass可以为原子类型和原子类型的包装类型。 - if (clazz.isPrimitive()) { - return assignmentTable.get(clazz).contains(fromClass); - } - - return false; - } - - private final static Map, Set>> assignmentTable = createHashMap(); - - static { - // boolean可以接受:boolean - assignmentTable.put(boolean.class, assignableSet(boolean.class)); - - // byte可以接受:byte - assignmentTable.put(byte.class, assignableSet(byte.class)); - - // char可以接受:char - assignmentTable.put(char.class, assignableSet(char.class)); - - // short可以接受:short, byte - assignmentTable.put(short.class, assignableSet(short.class, byte.class)); - - // int可以接受:int、byte、short、char - assignmentTable.put(int.class, assignableSet(int.class, byte.class, short.class, char.class)); - - // long可以接受:long、int、byte、short、char - assignmentTable.put(long.class, assignableSet(long.class, int.class, byte.class, short.class, char.class)); - - // float可以接受:float, long, int, byte, short, char - assignmentTable.put(float.class, - assignableSet(float.class, long.class, int.class, byte.class, short.class, char.class)); - - // double可以接受:double, float, long, int, byte, short, char - assignmentTable.put(double.class, - assignableSet(double.class, float.class, long.class, int.class, byte.class, short.class, char.class)); - - assertTrue(assignmentTable.size() == 8); - } - - private static Set> assignableSet(Class... types) { - Set> assignableSet = createHashSet(); - - for (Class type : types) { - assignableSet.add(getPrimitiveType(type)); - assignableSet.add(getWrapperTypeIfPrimitive(type)); - } - - return assignableSet; - } - - // ========================================================================== - // 定位class的位置。 - // ========================================================================== - - /** 在class loader中查找class的位置。 */ - public static String locateClass(Class clazz) { - return locateClass(clazz.getName(), clazz.getClassLoader()); - } - - /** 在class loader中查找class的位置。 */ - public static String locateClass(String className) { - return locateClass(className, null); - } - - /** 在class loader中查找class的位置。 */ - public static String locateClass(String className, ClassLoader loader) { - className = assertNotNull(trimToNull(className), "className"); - - if (loader == null) { - loader = Thread.currentThread().getContextClassLoader(); - } - - String classFile = className.replace('.', '/') + ".class"; - URL locationURL = loader.getResource(classFile); - String location = null; - - if (locationURL != null) { - location = locationURL.toExternalForm(); - - if (location.endsWith(classFile)) { - location = location.substring(0, location.length() - classFile.length()); - } - - location = location.replaceAll("^(jar|zip):|!/$", EMPTY_STRING); - } - - return location; - } - - /** Return the short string name of a Java class in uncapitalized JavaBeans - * property format. Strips the outer class name in case of an inner class. - * @param clazz the class - * @return the short name rendered in a standard JavaBeans property format - * @see java.beans.Introspector#decapitalize(String) - */ - public static String getShortNameAsProperty(Class clazz) { - String shortName = ClassUtil.getShortName(clazz); - int dotIndex = shortName.lastIndexOf('.'); - shortName = (dotIndex != -1 ? shortName.substring(dotIndex + 1) : shortName); - return Introspector.decapitalize(shortName); - } - /** - * Get the class name without the qualified package name. - * @param className the className to get the short name for - * @return the class name of the class without the package name - * @throws IllegalArgumentException if the className is empty - */ - public static String getShortName(String className) { - int lastDotIndex = className.lastIndexOf(PACKAGE_SEPARATOR); - int nameEndIndex = className.indexOf(CGLIB_CLASS_SEPARATOR); - if (nameEndIndex == -1) { - nameEndIndex = className.length(); - } - String shortName = className.substring(lastDotIndex + 1, nameEndIndex); - shortName = shortName.replace(INNER_CLASS_SEPARATOR, PACKAGE_SEPARATOR); - return shortName; - } - /** - * Get the class name without the qualified package name. - * @param clazz the class to get the short name for - * @return the class name of the class without the package name - */ - public static String getShortName(Class clazz) { - return getShortName(getQualifiedName(clazz)); - } - /** - * Return the qualified name of the given class: usually simply - * the class name, but component type class name + "[]" for arrays. - * @param clazz the class - * @return the qualified name of the class - */ - public static String getQualifiedName(Class clazz) { - Assert.assertNotNull(clazz, "Class must not be null"); - if (clazz.isArray()) { - return getQualifiedNameForArray(clazz); - } - else { - return clazz.getName(); - } - } - - /** - * Build a nice qualified name for an array: - * component type class name + "[]". - * @param clazz the array class - * @return a qualified name for the array class - */ - private static String getQualifiedNameForArray(Class clazz) { - StringBuilder result = new StringBuilder(); - while (clazz.isArray()) { - clazz = clazz.getComponentType(); - result.append(ARRAY_SUFFIX); - } - result.insert(0, clazz.getName()); - return result.toString(); - } - - /** - * Return the qualified name of the given method, consisting of - * fully qualified interface/class name + "." + method name. - * @param method the method - * @return the qualified name of the method - */ - public static String getQualifiedMethodName(Method method) { - Assert.assertNotNull(method, "Method must not be null"); - return method.getDeclaringClass().getName() + "." + method.getName(); - } - - /** - * Return all interfaces that the given instance implements as array, - * including ones implemented by superclasses. - * @param instance the instance to analyze for interfaces - * @return all interfaces that the given instance implements as array - */ - public static Class[] getAllInterfaces(Object instance) { - Assert.assertNotNull(instance, "Instance must not be null"); - return getAllInterfacesForClass(instance.getClass()); - } - - /** - * Return all interfaces that the given class implements as array, - * including ones implemented by superclasses. - *

If the class itself is an interface, it gets returned as sole interface. - * @param clazz the class to analyze for interfaces - * @return all interfaces that the given object implements as array - */ - public static Class[] getAllInterfacesForClass(Class clazz) { - return getAllInterfacesForClass(clazz, null); - } - - /** - * Return all interfaces that the given class implements as array, - * including ones implemented by superclasses. - *

If the class itself is an interface, it gets returned as sole interface. - * @param clazz the class to analyze for interfaces - * @param classLoader the ClassLoader that the interfaces need to be visible in - * (may be null when accepting all declared interfaces) - * @return all interfaces that the given object implements as array - */ - public static Class[] getAllInterfacesForClass(Class clazz, ClassLoader classLoader) { - Set ifcs = getAllInterfacesForClassAsSet(clazz, classLoader); - return ifcs.toArray(new Class[ifcs.size()]); - } - - /** - * Return all interfaces that the given instance implements as Set, - * including ones implemented by superclasses. - * @param instance the instance to analyze for interfaces - * @return all interfaces that the given instance implements as Set - */ - public static Set getAllInterfacesAsSet(Object instance) { - Assert.assertNotNull(instance, "Instance must not be null"); - return getAllInterfacesForClassAsSet(instance.getClass()); - } - - /** - * Return all interfaces that the given class implements as Set, - * including ones implemented by superclasses. - *

If the class itself is an interface, it gets returned as sole interface. - * @param clazz the class to analyze for interfaces - * @return all interfaces that the given object implements as Set - */ - public static Set getAllInterfacesForClassAsSet(Class clazz) { - return getAllInterfacesForClassAsSet(clazz, null); - } - - /** - * Return all interfaces that the given class implements as Set, - * including ones implemented by superclasses. - *

If the class itself is an interface, it gets returned as sole interface. - * @param clazz the class to analyze for interfaces - * @param classLoader the ClassLoader that the interfaces need to be visible in - * (may be null when accepting all declared interfaces) - * @return all interfaces that the given object implements as Set - */ - public static Set getAllInterfacesForClassAsSet(Class clazz, ClassLoader classLoader) { - Assert.assertNotNull(clazz, "Class must not be null"); - if (clazz.isInterface() && isVisible(clazz, classLoader)) { - return Collections.singleton(clazz); - } - Set interfaces = new LinkedHashSet(); - while (clazz != null) { - Class[] ifcs = clazz.getInterfaces(); - for (Class ifc : ifcs) { - interfaces.addAll(getAllInterfacesForClassAsSet(ifc, classLoader)); - } - clazz = clazz.getSuperclass(); - } - return interfaces; - } - /** - * Check whether the given class is visible in the given ClassLoader. - * @param clazz the class to check (typically an interface) - * @param classLoader the ClassLoader to check against (may be null, - * in which case this method will always return true) - */ - public static boolean isVisible(Class clazz, ClassLoader classLoader) { - if (classLoader == null) { - return true; - } - try { - Class actualClass = classLoader.loadClass(clazz.getName()); - return (clazz == actualClass); - // Else: different interface class found... - } - catch (ClassNotFoundException ex) { - // No interface class found... - return false; - } - } - - /** - * Determine the name of the class file, relative to the containing - * package: e.g. "String.class" - * @param clazz the class - * @return the file name of the ".class" file - */ - public static String getClassFileName(Class clazz) { - String className = clazz.getName(); - int lastDotIndex = className.lastIndexOf(PACKAGE_SEPARATOR); - return className.substring(lastDotIndex + 1) + CLASS_FILE_SUFFIX; - } -} diff --git a/src/main/java/com/zero/utils/CollectionFactory.java b/src/main/java/com/zero/utils/CollectionFactory.java deleted file mode 100644 index 85871eb..0000000 --- a/src/main/java/com/zero/utils/CollectionFactory.java +++ /dev/null @@ -1,324 +0,0 @@ -/** - * Copyright (c) 1997-2013, www.tinygroup.org (luo_guo@icloud.com). - * - * Licensed under the GPL, Version 3.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.gnu.org/licenses/gpl.html - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.zero.utils; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.IdentityHashMap; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; -import java.util.SortedSet; -import java.util.TreeMap; -import java.util.TreeSet; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.CopyOnWriteArraySet; - -/** - * Factory for collections, being aware of Java 5 and Java 6 collections. - * Mainly for internal use within the framework. - * - *

The goal of this class is to avoid runtime dependencies on a specific - * Java version, while nevertheless using the best collection implementation - * that is available at runtime. - * - * @author Juergen Hoeller - * @author Arjen Poutsma - * @since 1.1.1 - */ -public abstract class CollectionFactory { - - private static Class navigableSetClass = null; - - private static Class navigableMapClass = null; - - private static final Set approximableCollectionTypes = new HashSet(10); - - private static final Set approximableMapTypes = new HashSet(6); - - - static { - // Standard collection interfaces - approximableCollectionTypes.add(Collection.class); - approximableCollectionTypes.add(List.class); - approximableCollectionTypes.add(Set.class); - approximableCollectionTypes.add(SortedSet.class); - approximableMapTypes.add(Map.class); - approximableMapTypes.add(SortedMap.class); - - // New Java 6 collection interfaces - ClassLoader cl = CollectionFactory.class.getClassLoader(); - try { - navigableSetClass = cl.loadClass("java.util.NavigableSet"); - navigableMapClass = cl.loadClass("java.util.NavigableMap"); - approximableCollectionTypes.add(navigableSetClass); - approximableMapTypes.add(navigableMapClass); - } - catch (ClassNotFoundException ex) { - // not running on Java 6 or above... - } - - // Common concrete collection classes - approximableCollectionTypes.add(ArrayList.class); - approximableCollectionTypes.add(LinkedList.class); - approximableCollectionTypes.add(HashSet.class); - approximableCollectionTypes.add(LinkedHashSet.class); - approximableCollectionTypes.add(TreeSet.class); - approximableMapTypes.add(HashMap.class); - approximableMapTypes.add(LinkedHashMap.class); - approximableMapTypes.add(TreeMap.class); - } - - - /** - * Create a linked Set if possible: This implementation always - * creates a {@link java.util.LinkedHashSet}, since Spring 2.5 - * requires JDK 1.4 anyway. - * @param initialCapacity the initial capacity of the Set - * @return the new Set instance - * @deprecated as of Spring 2.5, for usage on JDK 1.4 or higher - */ - @Deprecated - public static Set createLinkedSetIfPossible(int initialCapacity) { - return new LinkedHashSet(initialCapacity); - } - - /** - * Create a copy-on-write Set (allowing for synchronization-less iteration) if possible: - * This implementation always creates a {@link java.util.concurrent.CopyOnWriteArraySet}, - * since Spring 3 requires JDK 1.5 anyway. - * @return the new Set instance - * @deprecated as of Spring 3.0, for usage on JDK 1.5 or higher - */ - @Deprecated - public static Set createCopyOnWriteSet() { - return new CopyOnWriteArraySet(); - } - - /** - * Create a linked Map if possible: This implementation always - * creates a {@link java.util.LinkedHashMap}, since Spring 2.5 - * requires JDK 1.4 anyway. - * @param initialCapacity the initial capacity of the Map - * @return the new Map instance - * @deprecated as of Spring 2.5, for usage on JDK 1.4 or higher - */ - @Deprecated - public static Map createLinkedMapIfPossible(int initialCapacity) { - return new LinkedHashMap(initialCapacity); - } - - - /** - * Create an identity Map if possible: This implementation always - * creates a {@link java.util.IdentityHashMap}, since Spring 2.5 - * requires JDK 1.4 anyway. - * @param initialCapacity the initial capacity of the Map - * @return the new Map instance - * @deprecated as of Spring 2.5, for usage on JDK 1.4 or higher - */ - @Deprecated - public static Map createIdentityMapIfPossible(int initialCapacity) { - return new IdentityHashMap(initialCapacity); - } - - /** - * Create a concurrent Map if possible: This implementation always - * creates a {@link java.util.concurrent.ConcurrentHashMap}, since Spring 3.0 - * requires JDK 1.5 anyway. - * @param initialCapacity the initial capacity of the Map - * @return the new Map instance - * @deprecated as of Spring 3.0, for usage on JDK 1.5 or higher - */ - @Deprecated - public static Map createConcurrentMapIfPossible(int initialCapacity) { - return new ConcurrentHashMap(initialCapacity); - } - - /** - * Create a concurrent Map with a dedicated {@link ConcurrentMap} interface: - * This implementation always creates a {@link java.util.concurrent.ConcurrentHashMap}, - * since Spring 3.0 requires JDK 1.5 anyway. - * @param initialCapacity the initial capacity of the Map - * @return the new ConcurrentMap instance - * @deprecated as of Spring 3.0, for usage on JDK 1.5 or higher - */ - @Deprecated - public static ConcurrentMap createConcurrentMap(int initialCapacity) { - return new JdkConcurrentHashMap(initialCapacity); - } - - /** - * Determine whether the given collection type is an approximable type, - * i.e. a type that {@link #createApproximateCollection} can approximate. - * @param collectionType the collection type to check - * @return true if the type is approximable, - * false if it is not - */ - public static boolean isApproximableCollectionType(Class collectionType) { - return (collectionType != null && approximableCollectionTypes.contains(collectionType)); - } - - /** - * Create the most approximate collection for the given collection. - *

Creates an ArrayList, TreeSet or linked Set for a List, SortedSet - * or Set, respectively. - * @param collection the original Collection object - * @param initialCapacity the initial capacity - * @return the new Collection instance - * @see java.util.ArrayList - * @see java.util.TreeSet - * @see java.util.LinkedHashSet - */ - @SuppressWarnings("unchecked") - public static Collection createApproximateCollection(Object collection, int initialCapacity) { - if (collection instanceof LinkedList) { - return new LinkedList(); - } - else if (collection instanceof List) { - return new ArrayList(initialCapacity); - } - else if (collection instanceof SortedSet) { - return new TreeSet(((SortedSet) collection).comparator()); - } - else { - return new LinkedHashSet(initialCapacity); - } - } - - /** - * Create the most appropriate collection for the given collection type. - *

Creates an ArrayList, TreeSet or linked Set for a List, SortedSet - * or Set, respectively. - * @param collectionType the desired type of the target Collection - * @param initialCapacity the initial capacity - * @return the new Collection instance - * @see java.util.ArrayList - * @see java.util.TreeSet - * @see java.util.LinkedHashSet - */ - public static Collection createCollection(Class collectionType, int initialCapacity) { - if (collectionType.isInterface()) { - if (List.class.equals(collectionType)) { - return new ArrayList(initialCapacity); - } - else if (SortedSet.class.equals(collectionType) || collectionType.equals(navigableSetClass)) { - return new TreeSet(); - } - else if (Set.class.equals(collectionType) || Collection.class.equals(collectionType)) { - return new LinkedHashSet(initialCapacity); - } - else { - throw new IllegalArgumentException("Unsupported Collection interface: " + collectionType.getName()); - } - } - else { - if (!Collection.class.isAssignableFrom(collectionType)) { - throw new IllegalArgumentException("Unsupported Collection type: " + collectionType.getName()); - } - try { - return (Collection) collectionType.newInstance(); - } - catch (Exception ex) { - throw new IllegalArgumentException("Could not instantiate Collection type: " + collectionType.getName()); - } - } - } - - /** - * Determine whether the given map type is an approximable type, - * i.e. a type that {@link #createApproximateMap} can approximate. - * @param mapType the map type to check - * @return true if the type is approximable, - * false if it is not - */ - public static boolean isApproximableMapType(Class mapType) { - return (mapType != null && approximableMapTypes.contains(mapType)); - } - - /** - * Create the most approximate map for the given map. - *

Creates a TreeMap or linked Map for a SortedMap or Map, respectively. - * @param map the original Map object - * @param initialCapacity the initial capacity - * @return the new Map instance - * @see java.util.TreeMap - * @see java.util.LinkedHashMap - */ - @SuppressWarnings("unchecked") - public static Map createApproximateMap(Object map, int initialCapacity) { - if (map instanceof SortedMap) { - return new TreeMap(((SortedMap) map).comparator()); - } - else { - return new LinkedHashMap(initialCapacity); - } - } - - /** - * Create the most approximate map for the given map. - *

Creates a TreeMap or linked Map for a SortedMap or Map, respectively. - * @param collectionType the desired type of the target Map - * @param initialCapacity the initial capacity - * @return the new Map instance - * @see java.util.TreeMap - * @see java.util.LinkedHashMap - */ - public static Map createMap(Class mapType, int initialCapacity) { - if (mapType.isInterface()) { - if (Map.class.equals(mapType)) { - return new LinkedHashMap(initialCapacity); - } - else if (SortedMap.class.equals(mapType) || mapType.equals(navigableMapClass)) { - return new TreeMap(); - } - else { - throw new IllegalArgumentException("Unsupported Map interface: " + mapType.getName()); - } - } - else { - if (!Map.class.isAssignableFrom(mapType)) { - throw new IllegalArgumentException("Unsupported Map type: " + mapType.getName()); - } - try { - return (Map) mapType.newInstance(); - } - catch (Exception ex) { - throw new IllegalArgumentException("Could not instantiate Map type: " + mapType.getName()); - } - } - } - - - /** - * ConcurrentMap adapter for the JDK ConcurrentHashMap class. - */ - @Deprecated - private static class JdkConcurrentHashMap extends ConcurrentHashMap implements ConcurrentMap { - - private JdkConcurrentHashMap(int initialCapacity) { - super(initialCapacity); - } - } - -} diff --git a/src/main/java/com/zero/utils/CollectionUtil.java b/src/main/java/com/zero/utils/CollectionUtil.java deleted file mode 100644 index 8cce738..0000000 --- a/src/main/java/com/zero/utils/CollectionUtil.java +++ /dev/null @@ -1,297 +0,0 @@ -/** - * Copyright (c) 1997-2013, www.tinygroup.org (luo_guo@icloud.com). - * - * Licensed under the GPL, Version 3.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.gnu.org/licenses/gpl.html - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.zero.utils; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; -import java.util.TreeSet; -import java.util.concurrent.ConcurrentHashMap; - -/** - * 方便创建容器对象的工具。 - * - * @author renhui - */ -public final class CollectionUtil { - /** 创建一个ArrayList。 */ - public static ArrayList createArrayList() { - return new ArrayList(); - } - - /** 创建一个ArrayList。 */ - public static ArrayList createArrayList(int initialCapacity) { - return new ArrayList(initialCapacity); - } - - /** 创建一个ArrayList。 */ - public static ArrayList createArrayList(Iterable c) { - ArrayList list; - - if (c instanceof Collection) { - list = new ArrayList((Collection) c); - } else { - list = new ArrayList(); - - iterableToCollection(c, list); - - list.trimToSize(); - } - - return list; - } - - /** 创建一个ArrayList。 */ - public static ArrayList createArrayList(V... args) { - if (args == null || args.length == 0) { - return new ArrayList(); - } else { - ArrayList list = new ArrayList(args.length); - - for (V v : args) { - list.add(v); - } - - return list; - } - } - - /** 创建一个LinkedList。 */ - public static LinkedList createLinkedList() { - return new LinkedList(); - } - - /** 创建一个LinkedList。 */ - public static LinkedList createLinkedList(Iterable c) { - LinkedList list = new LinkedList(); - - iterableToCollection(c, list); - - return list; - } - - /** 创建一个LinkedList。 */ - public static LinkedList createLinkedList(V... args) { - LinkedList list = new LinkedList(); - - if (args != null) { - for (V v : args) { - list.add(v); - } - } - - return list; - } - - /** - * 创建一个List。 - *

- * 和{@code createArrayList(args)}不同,本方法会返回一个不可变长度的列表,且性能高于 - * {@code createArrayList(args)}。 - *

- */ - public static List asList(T... args) { - if (args == null || args.length == 0) { - return Collections.emptyList(); - } else { - return Arrays.asList(args); - } - } - - /** 创建一个HashMap。 */ - public static HashMap createHashMap() { - return new HashMap(); - } - - /** 创建一个HashMap。 */ - public static HashMap createHashMap(int initialCapacity) { - return new HashMap(initialCapacity); - } - - /** 创建一个LinkedHashMap。 */ - public static LinkedHashMap createLinkedHashMap() { - return new LinkedHashMap(); - } - - /** 创建一个LinkedHashMap。 */ - public static LinkedHashMap createLinkedHashMap(int initialCapacity) { - return new LinkedHashMap(initialCapacity); - } - - /** 创建一个TreeMap。 */ - public static TreeMap createTreeMap() { - return new TreeMap(); - } - - /** 创建一个TreeMap。 */ - public static TreeMap createTreeMap(Comparator comparator) { - return new TreeMap(comparator); - } - - /** 创建一个ConcurrentHashMap。 */ - public static ConcurrentHashMap createConcurrentHashMap() { - return new ConcurrentHashMap(); - } - - /** 创建一个HashSet。 */ - public static HashSet createHashSet() { - return new HashSet(); - } - - /** 创建一个HashSet。 */ - public static HashSet createHashSet(V... args) { - if (args == null || args.length == 0) { - return new HashSet(); - } else { - HashSet set = new HashSet(args.length); - - for (V v : args) { - set.add(v); - } - - return set; - } - } - - /** 创建一个HashSet。 */ - public static HashSet createHashSet(Iterable c) { - HashSet set; - - if (c instanceof Collection) { - set = new HashSet((Collection) c); - } else { - set = new HashSet(); - iterableToCollection(c, set); - } - - return set; - } - - /** 创建一个LinkedHashSet。 */ - public static LinkedHashSet createLinkedHashSet() { - return new LinkedHashSet(); - } - - /** 创建一个LinkedHashSet。 */ - public static LinkedHashSet createLinkedHashSet(V... args) { - if (args == null || args.length == 0) { - return new LinkedHashSet(); - } else { - LinkedHashSet set = new LinkedHashSet(args.length); - - for (V v : args) { - set.add(v); - } - - return set; - } - } - - /** 创建一个LinkedHashSet。 */ - public static LinkedHashSet createLinkedHashSet(Iterable c) { - LinkedHashSet set; - - if (c instanceof Collection) { - set = new LinkedHashSet((Collection) c); - } else { - set = new LinkedHashSet(); - iterableToCollection(c, set); - } - - return set; - } - - /** 创建一个TreeSet。 */ - public static TreeSet createTreeSet() { - return new TreeSet(); - } - - /** 创建一个TreeSet。 */ - @SuppressWarnings("unchecked") - public static TreeSet createTreeSet(V... args) { - return (TreeSet) createTreeSet(null, args); - } - - /** 创建一个TreeSet。 */ - public static TreeSet createTreeSet(Iterable c) { - return createTreeSet(null, c); - } - - /** 创建一个TreeSet。 */ - public static TreeSet createTreeSet(Comparator comparator) { - return new TreeSet(comparator); - } - - /** 创建一个TreeSet。 */ - public static TreeSet createTreeSet(Comparator comparator, V... args) { - TreeSet set = new TreeSet(comparator); - - if (args != null) { - for (V v : args) { - set.add(v); - } - } - - return set; - } - - /** 创建一个TreeSet。 */ - public static TreeSet createTreeSet(Comparator comparator, Iterable c) { - TreeSet set = new TreeSet(comparator); - - iterableToCollection(c, set); - - return set; - } - - - private static void iterableToCollection(Iterable c, Collection list) { - for (T element : c) { - list.add(element); - } - } - /** - * Return true if the supplied Collection is null - * or empty. Otherwise, return false. - * @param collection the Collection to check - * @return whether the given Collection is empty - */ - public static boolean isEmpty(Collection collection) { - return (collection == null || collection.isEmpty()); - } - - /** - * Return true if the supplied Map is null - * or empty. Otherwise, return false. - * @param map the Map to check - * @return whether the given Map is empty - */ - public static boolean isEmpty(Map map) { - return (map == null || map.isEmpty()); - } - - -} diff --git a/src/main/java/com/zero/utils/DateUtils.java b/src/main/java/com/zero/utils/DateUtils.java deleted file mode 100644 index e45b5e3..0000000 --- a/src/main/java/com/zero/utils/DateUtils.java +++ /dev/null @@ -1,377 +0,0 @@ -package com.zero.utils; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; - -public class DateUtils { - - public static enum Type { - Year, Month, Week, Day, Hour, Minutes, Seconds; - } - - /** - * 获取当前时间
- * y 年 M 月 d 日 H 24小时制 h 12小时制 m 分 s 秒 - * - * @param format - * 日期格式 - * @return String - */ - public static String getCurrentDate(String format) { - SimpleDateFormat sdf = new SimpleDateFormat(format); - return sdf.format(new Date()); - } - - /** - * 获取制定日期的格式化字符串 - * - * @param date - * Date 日期 - * @param format - * String 格式 - * @return String - */ - public static String getFormatedDate(Date date, String format) { - SimpleDateFormat sdf = new SimpleDateFormat(format); - return sdf.format(date); - } - - /** - * 判断哪个日期在前 如果日期一在日期二之前,返回true,否则返回false - * - * @param date1 - * 日期一 - * @param date2 - * 日期二 - * @return boolean - */ - public static boolean isBefore(Date date1, Date date2) { - Calendar c1 = Calendar.getInstance(); - c1.setTime(date1); - - Calendar c2 = Calendar.getInstance(); - c2.setTime(date2); - - if (c1.before(c2)) - return true; - - return false; - } - - /** - * 将字符串转换成日期 - * - * @param date - * String 日期字符串 - * @return Date - * @throws ParseException - */ - public static Date parseDateFromString(String date) throws ParseException { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); - return sdf.parse(date); - } - - /** - * 获取指定日期当月的最后一天 - * - * @param date - * @return - */ - public static Date lastDayOfMonth(Date date) { - Calendar cal = Calendar.getInstance(); - cal.setTime(date); - cal.add(Calendar.MONTH, 1); - cal.set(Calendar.DAY_OF_MONTH, 1); - cal.add(Calendar.DAY_OF_MONTH, -1); - return cal.getTime(); - } - - /** - * 获取指定日期当月的第一天 - * - * @param date - * @return - */ - public static Date firstDayOfMonth(Date date) { - Calendar cal = Calendar.getInstance(); - cal.setTime(date); - cal.set(Calendar.DAY_OF_MONTH, 1); - return cal.getTime(); - } - - /** - * 是否是闰年 - * - * @param year - * 年份 - * @return boolean - */ - public static boolean isLeapYear(int year) { - GregorianCalendar calendar = new GregorianCalendar(); - return calendar.isLeapYear(year); - } - - /** - * 获取指定日期之前或者之后多少天的日期 - * - * @param day - * 指定的时间 - * @param offset - * 日期偏移量,正数表示延后,负数表示天前 - * @return Date - */ - public static Date getDateByOffset(Date day, int offset) { - Calendar c = Calendar.getInstance(); - c.setTime(day); - c.add(Calendar.DAY_OF_MONTH, offset); - return c.getTime(); - } - - /** - * 获取一天开始时间 如 2014-12-12 00:00:00 - * - * @return - */ - public static Date getDayStart() { - Calendar calendar = Calendar.getInstance(); - calendar.setTime(new Date()); - calendar.set(Calendar.HOUR_OF_DAY, 0); - calendar.set(Calendar.MINUTE, 0); - calendar.set(Calendar.SECOND, 0); - return calendar.getTime(); - } - - /** - * 获取一天结束时间 如 2014-12-12 23:59:59 - * - * @return - */ - public static Date getDayEnd() { - Calendar calendar = Calendar.getInstance(); - calendar.setTime(new Date()); - calendar.set(Calendar.HOUR_OF_DAY, 23); - calendar.set(Calendar.MINUTE, 59); - calendar.set(Calendar.SECOND, 59); - return calendar.getTime(); - } - - /** - * 时间分段 比如:2014-12-12 10:00:00 ~ 2014-12-12 14:00:00 分成两段就是 2014-12-12 - * 10:00:00 ~ 2014-12-12 12:00:00 和2014-12-12 12:00:00 ~ 2014-12-12 14:00:00 - * - * @param start - * 起始日期 - * @param end - * 结束日期 - * @param pieces - * 分成几段 - */ - public static Date[] getDatePieces(Date start, Date end, int pieces) { - - Long sl = start.getTime(); - Long el = end.getTime(); - - Long diff = el - sl; - - Long segment = diff / pieces; - - Date[] dateArray = new Date[pieces + 1]; - - for (int i = 1; i <= pieces + 1; i++) { - dateArray[i - 1] = new Date(sl + (i - 1) * segment); - } - - // 校正最后结束日期的误差,可能会出现偏差,比如14:00:00 ,会变成13:59:59之类的 - dateArray[pieces] = end; - - return dateArray; - } - - /** - * 获取某个日期的当月第一天 - * - * @return - */ - public static Date getFirstDayOfMonth(Date date) { - Calendar cal = Calendar.getInstance(); - cal.setTime(date); - cal.set(Calendar.DAY_OF_MONTH, 1); - return cal.getTime(); - } - - /** - * 获取某个日期的当月最后一天 - * - * @return - */ - public static Date getLastDayOfMonth(Date date) { - Calendar cal = Calendar.getInstance(); - cal.add(Calendar.MONTH, 1); - cal.set(Calendar.DAY_OF_MONTH, 0); - return cal.getTime(); - } - - /** - * 获取某个日期的当月第一天 - * - * @return - */ - public static Date getFirstDayOfMonth(int year, int month) { - Calendar cal = Calendar.getInstance(); - cal.set(Calendar.YEAR, year); - cal.set(Calendar.MONTH, month - 1); - cal.set(Calendar.DAY_OF_MONTH, 1); - return cal.getTime(); - } - - /** - * 获取某个日期的当月最后一天 - * - * @return - */ - public static Date getLastDayOfMonth(int year, int month) { - Calendar cal = Calendar.getInstance(); - cal.set(Calendar.YEAR, year); - cal.set(Calendar.MONTH, month); - cal.set(Calendar.DAY_OF_MONTH, 0); - return cal.getTime(); - } - - /** - * 获取两个日期的时间差,可以指定年,月,周,日,时,分,秒 - * @param date1 第一个日期 - * @param date2 第二个日期此日期必须在date1之后 - * @param type DateUtils.Type.X的枚举类型 - * @return long值 - * @throws Exception - */ - public static long getDiff(Date date1, Date date2, Type type) throws Exception { - - if (!isBefore(date1, date2)) - throw new Exception("第二个日期必须在第一个日期之后"); - - long d = Math.abs(date1.getTime() - date2.getTime()); - switch (type) { - case Year: { - Calendar cal1 = Calendar.getInstance(); - Calendar cal2 = Calendar.getInstance(); - - cal1.setTime(date1); - int year1 = cal1.get(Calendar.YEAR); - int month1 = cal1.get(Calendar.MONTH); - int day1 = cal1.get(Calendar.DAY_OF_MONTH); - int hour1 = cal1.get(Calendar.HOUR_OF_DAY); - int minute1 = cal1.get(Calendar.MINUTE); - int second1 = cal1.get(Calendar.SECOND); - - cal2.setTime(date2); - int year2 = cal2.get(Calendar.YEAR); - int month2 = cal2.get(Calendar.MONTH); - int day2 = cal2.get(Calendar.DAY_OF_MONTH); - int hour2 = cal2.get(Calendar.HOUR_OF_DAY); - int minute2 = cal2.get(Calendar.MINUTE); - int second2 = cal2.get(Calendar.SECOND); - - int yd = year2 - year1; - - if (month1 > month2) { - yd -= 1; - } else { - if (day1 > day2) { - yd -= 1; - } else { - if (hour1 > hour2) { - yd -= 1; - } else { - if (minute1 > minute2) { - yd -= 1; - } else { - if (second1 > second2) { - yd -= 1; - } - } - } - } - } - return (long)yd; - } - case Month: { - // 获取年份差 - long year = getDiff(date1, date2, Type.Year); - - Calendar cal1 = Calendar.getInstance(); - Calendar cal2 = Calendar.getInstance(); - - cal1.setTime(date1); - int month1 = cal1.get(Calendar.MONTH); - int day1 = cal1.get(Calendar.DAY_OF_MONTH); - int hour1 = cal1.get(Calendar.HOUR_OF_DAY); - int minute1 = cal1.get(Calendar.MINUTE); - int second1 = cal1.get(Calendar.SECOND); - - cal2.setTime(date2); - int month2 = cal2.get(Calendar.MONTH); - int day2 = cal2.get(Calendar.DAY_OF_MONTH); - int hour2 = cal2.get(Calendar.HOUR_OF_DAY); - int minute2 = cal2.get(Calendar.MINUTE); - int second2 = cal2.get(Calendar.SECOND); - - int md = (month2 + 12) - month1; - - if (day1 > day2) { - md -= 1; - } else { - if (hour1 > hour2) { - md -= 1; - } else { - if (minute1 > minute2) { - md -= 1; - } else { - if (second1 > second2) { - md -= 1; - } - } - } - } - return (long)md + year * 12; - } - case Week: { - return getDiff(date1, date2, Type.Day) / 7; - } - case Day: { - long d1 = date1.getTime(); - long d2 = date2.getTime(); - return (int) ((d2 - d1) / (24 * 60 * 60 * 1000)); - } - case Hour: { - long d1 = date1.getTime(); - long d2 = date2.getTime(); - return (int) ((d2 - d1) / (60 * 60 * 1000)); - } - case Minutes: { - long d1 = date1.getTime(); - long d2 = date2.getTime(); - return (int) ((d2 - d1) / (60 * 1000)); - } - case Seconds: { - long d1 = date1.getTime(); - long d2 = date2.getTime(); - return (int) ((d2 - d1) / 1000); - } - default: - throw new Exception("请指定要获取的时间差的类型:年,月,天,周,时,分,秒"); - } - } - - public static void main(String[] args) throws Exception { - Date d = new Date(); - Calendar cal = Calendar.getInstance(); - cal.setTime(d); - cal.add(Calendar.MONTH,1); - System.out.println(new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime())); - System.out.println(getDiff(d, cal.getTime(), DateUtils.Type.Week)); - } -} diff --git a/src/main/java/com/zero/utils/Enumerator.java b/src/main/java/com/zero/utils/Enumerator.java deleted file mode 100644 index bfa128a..0000000 --- a/src/main/java/com/zero/utils/Enumerator.java +++ /dev/null @@ -1,158 +0,0 @@ -/** - * Copyright (c) 1997-2013, www.tinygroup.org (luo_guo@icloud.com). - * - * Licensed under the GPL, Version 3.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.gnu.org/licenses/gpl.html - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.zero.utils; - - -import java.util.Collection; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.NoSuchElementException; - -public class Enumerator implements Enumeration { - - // ----------------------------------------------------------- Constructors - - /** - * Return an Enumeration over the values of the specified Collection. - * - * @param collection - * Collection whose values should be enumerated - */ - public Enumerator(Collection collection) { - - this(collection.iterator()); - - } - - /** - * Return an Enumeration over the values of the specified Collection. - * - * @param collection - * Collection whose values should be enumerated - * @param clone - * true to clone iterator - */ - public Enumerator(Collection collection, boolean clone) { - - this(collection.iterator(), clone); - - } - - /** - * Return an Enumeration over the values returned by the specified Iterator. - * - * @param iterator - * Iterator to be wrapped - */ - public Enumerator(Iterator iterator) { - - super(); - this.iterator = iterator; - - } - - /** - * Return an Enumeration over the values returned by the specified Iterator. - * - * @param iterator - * Iterator to be wrapped - * @param clone - * true to clone iterator - */ - @SuppressWarnings("unchecked") - public Enumerator(Iterator iterator, boolean clone) { - - super(); - if (!clone) { - this.iterator = iterator; - } else { - List list = new ArrayList(); - while (iterator.hasNext()) { - list.add(iterator.next()); - } - this.iterator = list.iterator(); - } - - } - - /** - * Return an Enumeration over the values of the specified Map. - * - * @param map - * Map whose values should be enumerated - */ - public Enumerator(Map map) { - - this(map.values().iterator()); - - } - - /** - * Return an Enumeration over the values of the specified Map. - * - * @param map - * Map whose values should be enumerated - * @param clone - * true to clone iterator - */ - public Enumerator(Map map, boolean clone) { - - this(map.values().iterator(), clone); - - } - - // ----------------------------------------------------- Instance Variables - - /** - * The Iterator over which the Enumeration - * represented by this class actually operates. - */ - private Iterator iterator = null; - - // --------------------------------------------------------- Public Methods - - /** - * Tests if this enumeration contains more elements. - * - * @return true if and only if this enumeration object - * contains at least one more element to provide, false - * otherwise - */ - public boolean hasMoreElements() { - - return (iterator.hasNext()); - - } - - /** - * Returns the next element of this enumeration if this enumeration has at - * least one more element to provide. - * - * @return the next element of this enumeration - * - * @exception NoSuchElementException - * if no more elements exist - */ - public Object nextElement() throws NoSuchElementException { - - return (iterator.next()); - - } - -} diff --git a/src/main/java/com/zero/utils/FileUtil.java b/src/main/java/com/zero/utils/FileUtil.java deleted file mode 100644 index 50b3d9b..0000000 --- a/src/main/java/com/zero/utils/FileUtil.java +++ /dev/null @@ -1,609 +0,0 @@ -/** - * Copyright (c) 1997-2013, www.tinygroup.org (luo_guo@icloud.com). - * - * Licensed under the GPL, Version 3.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.gnu.org/licenses/gpl.html - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.zero.utils; - - - -import static com.zero.utils.StringUtil.*; - -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.zero.utils.exceptions.IllegalPathException; - -/** - * 操作文件的工具类 - * - * @author renhui - * - */ -public class FileUtil { - - public static String readFileContent(File file, String encoding) - throws Exception { - FileInputStream fis = new FileInputStream(file); - return readStreamContent(fis, encoding); - } - - public static String readStreamContent(InputStream stream, String encoding) - throws Exception { - StringBuilder content = new StringBuilder(""); - byte[] bytearray = new byte[stream.available()]; - int bytetotal = stream.available(); - while (stream.read(bytearray, 0, bytetotal) != -1) { - String temp = new String(bytearray, 0, bytetotal, encoding); - content.append(temp); - } - return content.toString(); - } - - - // ========================================================================== - // 规格化路径。 - // ========================================================================== - - /** - * 规格化绝对路径。 - *

- * 该方法返回以“/”开始的绝对路径。转换规则如下: - *

- *
    - *
  1. 路径为空,则返回""
  2. - *
  3. 将所有backslash("\\")转化成slash("/")。
  4. - *
  5. 去除重复的"/"或"\\"。
  6. - *
  7. 去除".",如果发现"..",则向上朔一级目录。
  8. - *
  9. 保留路径末尾的"/"(如果有的话,除了空路径)。
  10. - *
  11. 对于绝对路径,如果".."上朔的路径超过了根目录,则看作非法路径,抛出异常。
  12. - *
- * - * @param path 要规格化的路径 - * @return 规格化后的路径 - * @throws IllegalPathException 如果路径非法 - */ - public static String normalizeAbsolutePath(String path) throws IllegalPathException { - return normalizePath(path, true, false, false); - } - - /** - * 规格化绝对路径。 - *

- * 该方法返回以“/”开始的绝对路径。转换规则如下: - *

- *
    - *
  1. 路径为空,则返回""
  2. - *
  3. 将所有backslash("\\")转化成slash("/")。
  4. - *
  5. 去除重复的"/"或"\\"。
  6. - *
  7. 去除".",如果发现"..",则向上朔一级目录。
  8. - *
  9. 保留路径末尾的"/"(如果有的话,除了空路径和强制指定removeTrailingSlash==true)。
  10. - *
  11. 对于绝对路径,如果".."上朔的路径超过了根目录,则看作非法路径,抛出异常。
  12. - *
- * - * @param path 要规格化的路径 - * @param removeTrailingSlash 是否强制移除末尾的"/" - * @return 规格化后的路径 - * @throws IllegalPathException 如果路径非法 - */ - public static String normalizeAbsolutePath(String path, boolean removeTrailingSlash) throws IllegalPathException { - return normalizePath(path, true, false, removeTrailingSlash); - } - - /** - * 规格化相对路径。 - *

- * 该方法返回不以“/”开始的相对路径。转换规则如下: - *

- *
    - *
  1. 路径为空,则返回""
  2. - *
  3. 将所有backslash("\\")转化成slash("/")。
  4. - *
  5. 去除重复的"/"或"\\"。
  6. - *
  7. 去除".",如果发现"..",则向上朔一级目录。
  8. - *
  9. 空相对路径返回""。
  10. - *
  11. 保留路径末尾的"/"(如果有的话,除了空路径)。
  12. - *
- * - * @param path 要规格化的路径 - * @return 规格化后的路径 - * @throws IllegalPathException 如果路径非法 - */ - public static String normalizeRelativePath(String path) throws IllegalPathException { - return normalizePath(path, false, true, false); - } - - /** - * 规格化相对路径。 - *

- * 该方法返回不以“/”开始的相对路径。转换规则如下: - *

- *
    - *
  1. 路径为空,则返回""
  2. - *
  3. 将所有backslash("\\")转化成slash("/")。
  4. - *
  5. 去除重复的"/"或"\\"。
  6. - *
  7. 去除".",如果发现"..",则向上朔一级目录。
  8. - *
  9. 空相对路径返回""。
  10. - *
  11. 保留路径末尾的"/"(如果有的话,除了空路径和强制指定removeTrailingSlash==true)。
  12. - *
- * - * @param path 要规格化的路径 - * @param removeTrailingSlash 是否强制移除末尾的"/" - * @return 规格化后的路径 - * @throws IllegalPathException 如果路径非法 - */ - public static String normalizeRelativePath(String path, boolean removeTrailingSlash) throws IllegalPathException { - return normalizePath(path, false, true, removeTrailingSlash); - } - - /** - * 规格化路径。规则如下: - *
    - *
  1. 路径为空,则返回""
  2. - *
  3. 将所有backslash("\\")转化成slash("/")。
  4. - *
  5. 去除重复的"/"或"\\"。
  6. - *
  7. 去除".",如果发现"..",则向上朔一级目录。
  8. - *
  9. 空绝对路径返回"/",空相对路径返回""。
  10. - *
  11. 保留路径末尾的"/"(如果有的话,除了空路径)。
  12. - *
  13. 对于绝对路径,如果".."上朔的路径超过了根目录,则看作非法路径,抛出异常。
  14. - *
- * - * @param path 要规格化的路径 - * @return 规格化后的路径 - * @throws IllegalPathException 如果路径非法 - */ - public static String normalizePath(String path) throws IllegalPathException { - return normalizePath(path, false, false, false); - } - - /** - * 规格化路径。规则如下: - *
    - *
  1. 路径为空,则返回""
  2. - *
  3. 将所有backslash("\\")转化成slash("/")。
  4. - *
  5. 去除重复的"/"或"\\"。
  6. - *
  7. 去除".",如果发现"..",则向上朔一级目录。
  8. - *
  9. 空绝对路径返回"/",空相对路径返回""。
  10. - *
  11. 保留路径末尾的"/"(如果有的话,除了空路径和强制指定removeTrailingSlash==true)。
  12. - *
  13. 对于绝对路径,如果".."上朔的路径超过了根目录,则看作非法路径,抛出异常。
  14. - *
- * - * @param path 要规格化的路径 - * @param removeTrailingSlash 是否强制移除末尾的"/" - * @return 规格化后的路径 - * @throws IllegalPathException 如果路径非法 - */ - public static String normalizePath(String path, boolean removeTrailingSlash) throws IllegalPathException { - return normalizePath(path, false, false, removeTrailingSlash); - } - - private static String normalizePath(String path, boolean forceAbsolute, boolean forceRelative, - boolean removeTrailingSlash) throws IllegalPathException { - char[] pathChars = trimToEmpty(path).toCharArray(); - int length = pathChars.length; - - // 检查绝对路径,以及path尾部的"/" - boolean startsWithSlash = false; - boolean endsWithSlash = false; - - if (length > 0) { - char firstChar = pathChars[0]; - char lastChar = pathChars[length - 1]; - - startsWithSlash = firstChar == '/' || firstChar == '\\'; - endsWithSlash = lastChar == '/' || lastChar == '\\'; - } - - StringBuilder buf = new StringBuilder(length); - boolean isAbsolutePath = forceAbsolute || !forceRelative && startsWithSlash; - int index = startsWithSlash ? 0 : -1; - int level = 0; - - if (isAbsolutePath) { - buf.append("/"); - } - - while (index < length) { - // 跳到第一个非slash字符,或末尾 - index = indexOfSlash(pathChars, index + 1, false); - - if (index == length) { - break; - } - - // 取得下一个slash index,或末尾 - int nextSlashIndex = indexOfSlash(pathChars, index, true); - - String element = new String(pathChars, index, nextSlashIndex - index); - index = nextSlashIndex; - - // 忽略"." - if (".".equals(element)) { - continue; - } - - // 回朔".." - if ("..".equals(element)) { - if (level == 0) { - // 如果是绝对路径,../试图越过最上层目录,这是不可能的, - // 抛出路径非法的异常。 - if (isAbsolutePath) { - throw new IllegalPathException(path); - } else { - buf.append("../"); - } - } else { - buf.setLength(pathChars[--level]); - } - - continue; - } - - // 添加到path - pathChars[level++] = (char) buf.length(); // 将已经读过的chars空间用于记录指定level的index - buf.append(element).append('/'); - } - - // 除去最后的"/" - if (buf.length() > 0) { - if (!endsWithSlash || removeTrailingSlash) { - buf.setLength(buf.length() - 1); - } - } - - return buf.toString(); - } - - private static int indexOfSlash(char[] chars, int beginIndex, boolean slash) { - int i = beginIndex; - - for (; i < chars.length; i++) { - char ch = chars[i]; - - if (slash) { - if (ch == '/' || ch == '\\') { - break; // if a slash - } - } else { - if (ch != '/' && ch != '\\') { - break; // if not a slash - } - } - } - - return i; - } - - // ========================================================================== - // 取得基于指定basedir规格化路径。 - // ========================================================================== - - /** - * 如果指定路径已经是绝对路径,则规格化后直接返回之,否则取得基于指定basedir的规格化路径。 - * - * @param basedir 根目录,如果path为相对路径,表示基于此目录 - * @param path 要检查的路径 - * @return 规格化的绝对路径 - * @throws IllegalPathException 如果路径非法 - */ - public static String getAbsolutePathBasedOn(String basedir, String path) throws IllegalPathException { - // 如果path为绝对路径,则规格化后返回 - boolean isAbsolutePath = false; - - path = trimToEmpty(path); - - if (path.length() > 0) { - char firstChar = path.charAt(0); - isAbsolutePath = firstChar == '/' || firstChar == '\\'; - } - - if (!isAbsolutePath) { - // 如果path为相对路径,将它和basedir合并。 - if (path.length() > 0) { - path = trimToEmpty(basedir) + "/" + path; - } else { - path = trimToEmpty(basedir); - } - } - - return normalizeAbsolutePath(path); - } - - /** - * 取得和系统相关的绝对路径。 - * - * @throws IllegalPathException 如果basedir不是绝对路径 - */ - public static String getSystemDependentAbsolutePathBasedOn(String basedir, String path) { - path = trimToEmpty(path); - - boolean endsWithSlash = path.endsWith("/") || path.endsWith("\\"); - - File pathFile = new File(path); - - if (pathFile.isAbsolute()) { - // 如果path已经是绝对路径了,则直接返回之。 - path = pathFile.getAbsolutePath(); - } else { - // 否则以basedir为基本路径。 - // 下面确保basedir本身为绝对路径。 - basedir = trimToEmpty(basedir); - - File baseFile = new File(basedir); - - if (baseFile.isAbsolute()) { - path = new File(baseFile, path).getAbsolutePath(); - } else { - throw new IllegalPathException("Basedir is not absolute path: " + basedir); - } - } - - if (endsWithSlash) { - path = path + '/'; - } - - return normalizePath(path); - } - - // ========================================================================== - // 取得相对于指定basedir相对路径。 - // ========================================================================== - - /** - * 取得相对于指定根目录的相对路径。 - * - * @param basedir 根目录 - * @param path 要计算的路径 - * @return 如果pathbasedir是兼容的,则返回相对于 - * basedir的相对路径,否则返回path本身。 - * @throws IllegalPathException 如果路径非法 - */ - public static String getRelativePath(String basedir, String path) throws IllegalPathException { - // 取得规格化的basedir,确保其为绝对路径 - basedir = normalizeAbsolutePath(basedir); - - // 取得规格化的path - path = getAbsolutePathBasedOn(basedir, path); - - // 保留path尾部的"/" - boolean endsWithSlash = path.endsWith("/"); - - // 按"/"分隔basedir和path - String[] baseParts = StringUtil.split(basedir, '/'); - String[] parts = StringUtil.split(path, '/'); - StringBuilder buf = new StringBuilder(); - int i = 0; - - while (i < baseParts.length && i < parts.length && baseParts[i].equals(parts[i])) { - i++; - } - - if (i < baseParts.length && i < parts.length) { - for (int j = i; j < baseParts.length; j++) { - buf.append("..").append('/'); - } - } - - for (; i < parts.length; i++) { - buf.append(parts[i]); - - if (i < parts.length - 1) { - buf.append('/'); - } - } - - if (endsWithSlash && buf.length() > 0 && buf.charAt(buf.length() - 1) != '/') { - buf.append('/'); - } - - return buf.toString(); - } - - // ========================================================================== - // 取得文件名后缀。 - // ========================================================================== - - /** - * 取得文件路径的后缀。 - *
    - *
  • 未指定文件名 - 返回null
  • - *
  • 文件名没有后缀 - 返回null
  • - *
- */ - public static String getExtension(String fileName) { - return getExtension(fileName, null, false); - } - - /** - * 取得文件路径的后缀。 - *
    - *
  • 未指定文件名 - 返回null
  • - *
  • 文件名没有后缀 - 返回null
  • - *
- */ - public static String getExtension(String fileName, boolean toLowerCase) { - return getExtension(fileName, null, toLowerCase); - } - - /** - * 取得文件路径的后缀。 - *
    - *
  • 未指定文件名 - 返回null
  • - *
  • 文件名没有后缀 - 返回指定字符串nullExt
  • - *
- */ - public static String getExtension(String fileName, String nullExt) { - return getExtension(fileName, nullExt, false); - } - - /** - * 取得文件路径的后缀。 - *
    - *
  • 未指定文件名 - 返回null
  • - *
  • 文件名没有后缀 - 返回指定字符串nullExt
  • - *
- */ - public static String getExtension(String fileName, String nullExt, boolean toLowerCase) { - fileName = trimToNull(fileName); - - if (fileName == null) { - return null; - } - - fileName = fileName.replace('\\', '/'); - fileName = fileName.substring(fileName.lastIndexOf("/") + 1); - - int index = fileName.lastIndexOf("."); - String ext = null; - - if (index >= 0) { - ext = trimToNull(fileName.substring(index + 1)); - } - - if (ext == null) { - return nullExt; - } else { - return toLowerCase ? ext.toLowerCase() : ext; - } - } - - /** - * 取得指定路径的名称和后缀。 - * - * @param path 路径 - * @return 路径和后缀 - */ - public static FileNameAndExtension getFileNameAndExtension(String path) { - return getFileNameAndExtension(path, false); - } - - /** - * 取得指定路径的名称和后缀。 - * - * @param path 路径 - * @return 路径和后缀 - */ - public static FileNameAndExtension getFileNameAndExtension(String path, boolean extensionToLowerCase) { - path = StringUtil.trimToEmpty(path); - - String fileName = path; - String extension = null; - - if (!StringUtil.isEmpty(path)) { - // 如果找到后缀,则index >= 0,且extension != null(除非name以.结尾) - int index = path.lastIndexOf('.'); - - if (index >= 0) { - extension = StringUtil.trimToNull(StringUtil.substring(path, index + 1)); - - if (!StringUtil.containsNone(extension, "/\\")) { - extension = null; - index = -1; - } - } - - if (index >= 0) { - fileName = StringUtil.substring(path, 0, index); - } - } - - return new FileNameAndExtension(fileName, extension, extensionToLowerCase); - } - - /** - * 规格化文件名后缀。 - *
    - *
  • 除去两边空白。
  • - *
  • 转成小写。
  • - *
  • 除去开头的“.”。
  • - *
  • 对空白的后缀,返回null
  • - *
- */ - public static String normalizeExtension(String ext) { - ext = trimToNull(ext); - - if (ext != null) { - ext = ext.toLowerCase(); - - if (ext.startsWith(".")) { - ext = trimToNull(ext.substring(1)); - } - } - - return ext; - } - - private static final Pattern schemePrefixPattern = Pattern.compile( - "(file:*[a-z]:)|(\\w+://.+?/)|((jar|zip):.+!/)|(\\w+:)", Pattern.CASE_INSENSITIVE); - - /** - * 根据指定url和相对路径,计算出相对路径所对应的完整url。类似于URI.resolve() - * 方法,然后后者不能正确处理jar类型的URL。 - */ - public static String resolve(String url, String relativePath) { - url = trimToEmpty(url); - - Matcher m = schemePrefixPattern.matcher(url); - int index = 0; - - if (m.find()) { - index = m.end(); - - if (url.charAt(index - 1) == '/') { - index--; - } - } - - return url.substring(0, index) + normalizeAbsolutePath(url.substring(index) + "/../" + relativePath); - } - - public static void delete(File file) { - if (file != null && file.exists()) { - if (file.isFile()) { - file.delete(); - } - else if (file.isDirectory()) { - File files[] = file.listFiles(); - for (int i=0; iMainly intended for usage within the framework, resolving method - * parameter types even when they are declared generically. - * - * @author Juergen Hoeller - * @author Rob Harrop - * @since 2.5.2 - * @see GenericCollectionTypeResolver - */ -public abstract class GenericTypeResolver { - - /** Cache from Class to TypeVariable Map */ - private static final Map>> typeVariableCache = - Collections.synchronizedMap(new WeakHashMap>>()); - - - /** - * Determine the target type for the given parameter specification. - * @param methodParam the method parameter specification - * @return the corresponding generic parameter type - */ - public static Type getTargetType(MethodParameter methodParam) { - Assert.assertNotNull(methodParam, "MethodParameter must not be null"); - if (methodParam.getConstructor() != null) { - return methodParam.getConstructor().getGenericParameterTypes()[methodParam.getParameterIndex()]; - } - else { - if (methodParam.getParameterIndex() >= 0) { - return methodParam.getMethod().getGenericParameterTypes()[methodParam.getParameterIndex()]; - } - else { - return methodParam.getMethod().getGenericReturnType(); - } - } - } - - /** - * Determine the target type for the given generic parameter type. - * @param methodParam the method parameter specification - * @param clazz the class to resolve type variables against - * @return the corresponding generic parameter or return type - */ - public static Class resolveParameterType(MethodParameter methodParam, Class clazz) { - Type genericType = getTargetType(methodParam); - Assert.assertNotNull(clazz, "Class must not be null"); - Map typeVariableMap = getTypeVariableMap(clazz); - Type rawType = getRawType(genericType, typeVariableMap); - Class result = (rawType instanceof Class ? (Class) rawType : methodParam.getParameterType()); - methodParam.setParameterType(result); - methodParam.typeVariableMap = typeVariableMap; - return result; - } - - /** - * Determine the target type for the generic return type of the given method. - * @param method the method to introspect - * @param clazz the class to resolve type variables against - * @return the corresponding generic parameter or return type - */ - public static Class resolveReturnType(Method method, Class clazz) { - Assert.assertNotNull(method, "Method must not be null"); - Type genericType = method.getGenericReturnType(); - Assert.assertNotNull(clazz, "Class must not be null"); - Map typeVariableMap = getTypeVariableMap(clazz); - Type rawType = getRawType(genericType, typeVariableMap); - return (rawType instanceof Class ? (Class) rawType : method.getReturnType()); - } - - /** - * Resolve the single type argument of the given generic interface against the given - * target method which is assumed to return the given interface or an implementation - * of it. - * @param method the target method to check the return type of - * @param genericIfc the generic interface or superclass to resolve the type argument from - * @return the resolved parameter type of the method return type, or null - * if not resolvable or if the single argument is of type {@link WildcardType}. - */ - public static Class resolveReturnTypeArgument(Method method, Class genericIfc) { - Assert.assertNotNull(method, "method must not be null"); - Type returnType = method.getReturnType(); - Type genericReturnType = method.getGenericReturnType(); - if (returnType.equals(genericIfc)) { - if (genericReturnType instanceof ParameterizedType) { - ParameterizedType targetType = (ParameterizedType) genericReturnType; - Type[] actualTypeArguments = targetType.getActualTypeArguments(); - Type typeArg = actualTypeArguments[0]; - if (!(typeArg instanceof WildcardType)) { - return (Class) typeArg; - } - } - else { - return null; - } - } - return GenericTypeResolver.resolveTypeArgument((Class) returnType, genericIfc); - } - - /** - * Resolve the single type argument of the given generic interface against - * the given target class which is assumed to implement the generic interface - * and possibly declare a concrete type for its type variable. - * @param clazz the target class to check against - * @param genericIfc the generic interface or superclass to resolve the type argument from - * @return the resolved type of the argument, or null if not resolvable - */ - public static Class resolveTypeArgument(Class clazz, Class genericIfc) { - Class[] typeArgs = resolveTypeArguments(clazz, genericIfc); - if (typeArgs == null) { - return null; - } - if (typeArgs.length != 1) { - throw new IllegalArgumentException("Expected 1 type argument on generic interface [" + - genericIfc.getName() + "] but found " + typeArgs.length); - } - return typeArgs[0]; - } - - /** - * Resolve the type arguments of the given generic interface against the given - * target class which is assumed to implement the generic interface and possibly - * declare concrete types for its type variables. - * @param clazz the target class to check against - * @param genericIfc the generic interface or superclass to resolve the type argument from - * @return the resolved type of each argument, with the array size matching the - * number of actual type arguments, or null if not resolvable - */ - public static Class[] resolveTypeArguments(Class clazz, Class genericIfc) { - return doResolveTypeArguments(clazz, clazz, genericIfc); - } - - private static Class[] doResolveTypeArguments(Class ownerClass, Class classToIntrospect, Class genericIfc) { - while (classToIntrospect != null) { - if (genericIfc.isInterface()) { - Type[] ifcs = classToIntrospect.getGenericInterfaces(); - for (Type ifc : ifcs) { - Class[] result = doResolveTypeArguments(ownerClass, ifc, genericIfc); - if (result != null) { - return result; - } - } - } - else { - Class[] result = doResolveTypeArguments( - ownerClass, classToIntrospect.getGenericSuperclass(), genericIfc); - if (result != null) { - return result; - } - } - classToIntrospect = classToIntrospect.getSuperclass(); - } - return null; - } - - private static Class[] doResolveTypeArguments(Class ownerClass, Type ifc, Class genericIfc) { - if (ifc instanceof ParameterizedType) { - ParameterizedType paramIfc = (ParameterizedType) ifc; - Type rawType = paramIfc.getRawType(); - if (genericIfc.equals(rawType)) { - Type[] typeArgs = paramIfc.getActualTypeArguments(); - Class[] result = new Class[typeArgs.length]; - for (int i = 0; i < typeArgs.length; i++) { - Type arg = typeArgs[i]; - result[i] = extractClass(ownerClass, arg); - } - return result; - } - else if (genericIfc.isAssignableFrom((Class) rawType)) { - return doResolveTypeArguments(ownerClass, (Class) rawType, genericIfc); - } - } - else if (ifc != null && genericIfc.isAssignableFrom((Class) ifc)) { - return doResolveTypeArguments(ownerClass, (Class) ifc, genericIfc); - } - return null; - } - - /** - * Extract a class instance from given Type. - */ - private static Class extractClass(Class ownerClass, Type arg) { - if (arg instanceof ParameterizedType) { - return extractClass(ownerClass, ((ParameterizedType) arg).getRawType()); - } - else if (arg instanceof GenericArrayType) { - GenericArrayType gat = (GenericArrayType) arg; - Type gt = gat.getGenericComponentType(); - Class componentClass = extractClass(ownerClass, gt); - return Array.newInstance(componentClass, 0).getClass(); - } - else if (arg instanceof TypeVariable) { - TypeVariable tv = (TypeVariable) arg; - arg = getTypeVariableMap(ownerClass).get(tv); - if (arg == null) { - arg = extractBoundForTypeVariable(tv); - } - else { - arg = extractClass(ownerClass, arg); - } - } - return (arg instanceof Class ? (Class) arg : Object.class); - } - - - /** - * Resolve the specified generic type against the given TypeVariable map. - * @param genericType the generic type to resolve - * @param typeVariableMap the TypeVariable Map to resolved against - * @return the type if it resolves to a Class, or Object.class otherwise - */ - public static Class resolveType(Type genericType, Map typeVariableMap) { - Type rawType = getRawType(genericType, typeVariableMap); - return (rawType instanceof Class ? (Class) rawType : Object.class); - } - - /** - * Determine the raw type for the given generic parameter type. - * @param genericType the generic type to resolve - * @param typeVariableMap the TypeVariable Map to resolved against - * @return the resolved raw type - */ - static Type getRawType(Type genericType, Map typeVariableMap) { - Type resolvedType = genericType; - if (genericType instanceof TypeVariable) { - TypeVariable tv = (TypeVariable) genericType; - resolvedType = typeVariableMap.get(tv); - if (resolvedType == null) { - resolvedType = extractBoundForTypeVariable(tv); - } - } - if (resolvedType instanceof ParameterizedType) { - return ((ParameterizedType) resolvedType).getRawType(); - } - else { - return resolvedType; - } - } - - /** - * Build a mapping of {@link TypeVariable#getName TypeVariable names} to concrete - * {@link Class} for the specified {@link Class}. Searches all super types, - * enclosing types and interfaces. - */ - public static Map getTypeVariableMap(Class clazz) { - Reference> ref = typeVariableCache.get(clazz); - Map typeVariableMap = (ref != null ? ref.get() : null); - - if (typeVariableMap == null) { - typeVariableMap = new HashMap(); - - // interfaces - extractTypeVariablesFromGenericInterfaces(clazz.getGenericInterfaces(), typeVariableMap); - - // super class - Type genericType = clazz.getGenericSuperclass(); - Class type = clazz.getSuperclass(); - while (type != null && !Object.class.equals(type)) { - if (genericType instanceof ParameterizedType) { - ParameterizedType pt = (ParameterizedType) genericType; - populateTypeMapFromParameterizedType(pt, typeVariableMap); - } - extractTypeVariablesFromGenericInterfaces(type.getGenericInterfaces(), typeVariableMap); - genericType = type.getGenericSuperclass(); - type = type.getSuperclass(); - } - - // enclosing class - type = clazz; - while (type.isMemberClass()) { - genericType = type.getGenericSuperclass(); - if (genericType instanceof ParameterizedType) { - ParameterizedType pt = (ParameterizedType) genericType; - populateTypeMapFromParameterizedType(pt, typeVariableMap); - } - type = type.getEnclosingClass(); - } - - typeVariableCache.put(clazz, new WeakReference>(typeVariableMap)); - } - - return typeVariableMap; - } - - /** - * Extracts the bound Type for a given {@link TypeVariable}. - */ - static Type extractBoundForTypeVariable(TypeVariable typeVariable) { - Type[] bounds = typeVariable.getBounds(); - if (bounds.length == 0) { - return Object.class; - } - Type bound = bounds[0]; - if (bound instanceof TypeVariable) { - bound = extractBoundForTypeVariable((TypeVariable) bound); - } - return bound; - } - - private static void extractTypeVariablesFromGenericInterfaces(Type[] genericInterfaces, Map typeVariableMap) { - for (Type genericInterface : genericInterfaces) { - if (genericInterface instanceof ParameterizedType) { - ParameterizedType pt = (ParameterizedType) genericInterface; - populateTypeMapFromParameterizedType(pt, typeVariableMap); - if (pt.getRawType() instanceof Class) { - extractTypeVariablesFromGenericInterfaces( - ((Class) pt.getRawType()).getGenericInterfaces(), typeVariableMap); - } - } - else if (genericInterface instanceof Class) { - extractTypeVariablesFromGenericInterfaces( - ((Class) genericInterface).getGenericInterfaces(), typeVariableMap); - } - } - } - - /** - * Read the {@link TypeVariable TypeVariables} from the supplied {@link ParameterizedType} - * and add mappings corresponding to the {@link TypeVariable#getName TypeVariable name} -> - * concrete type to the supplied {@link Map}. - *

Consider this case: - *