From 899f1384f6b3bcd62b626e4fdc46289b3d94dc43 Mon Sep 17 00:00:00 2001
From: Looly
Date: Sat, 5 Mar 2022 22:47:07 +0800
Subject: [PATCH 01/13] add test
---
.../hutool/crypto/test/symmetric/TEATest.java | 39 +++++++++++++++++++
1 file changed, 39 insertions(+)
create mode 100644 hutool-crypto/src/test/java/cn/hutool/crypto/test/symmetric/TEATest.java
diff --git a/hutool-crypto/src/test/java/cn/hutool/crypto/test/symmetric/TEATest.java b/hutool-crypto/src/test/java/cn/hutool/crypto/test/symmetric/TEATest.java
new file mode 100644
index 000000000..8a9d008d6
--- /dev/null
+++ b/hutool-crypto/src/test/java/cn/hutool/crypto/test/symmetric/TEATest.java
@@ -0,0 +1,39 @@
+package cn.hutool.crypto.test.symmetric;
+
+import cn.hutool.crypto.symmetric.SymmetricCrypto;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * TEA(Tiny Encryption Algorithm)和 XTEA算法单元测试
+ */
+public class TEATest {
+
+ @Test
+ public void teaTest(){
+ String data = "测试的加密数据 by Hutool";
+
+ // 密钥必须为128bit
+ final SymmetricCrypto tea = new SymmetricCrypto("TEA", "MyPassword123456".getBytes());
+ final byte[] encrypt = tea.encrypt(data);
+
+ // 解密
+ final String decryptStr = tea.decryptStr(encrypt);
+
+ Assert.assertEquals(data, decryptStr);
+ }
+
+ @Test
+ public void xteaTest(){
+ String data = "测试的加密数据 by Hutool";
+
+ // 密钥必须为128bit
+ final SymmetricCrypto tea = new SymmetricCrypto("XTEA", "MyPassword123456".getBytes());
+ final byte[] encrypt = tea.encrypt(data);
+
+ // 解密
+ final String decryptStr = tea.decryptStr(encrypt);
+
+ Assert.assertEquals(data, decryptStr);
+ }
+}
From 115871a355b1c7b212fe52b6c80d127dba14d263 Mon Sep 17 00:00:00 2001
From: VampireAchao
Date: Sat, 5 Mar 2022 23:43:27 +0800
Subject: [PATCH 02/13] =?UTF-8?q?=E4=BF=AE=E5=A4=8DAnnotationProxy#annotat?=
=?UTF-8?q?ionType=E8=8E=B7=E5=8F=96=E4=B8=8D=E5=88=B0=E6=B3=A8=E8=A7=A3?=
=?UTF-8?q?=E7=B1=BB=E5=9E=8B=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../main/java/cn/hutool/core/annotation/AnnotationProxy.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationProxy.java b/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationProxy.java
index a61ff6668..bcf2ba4b5 100644
--- a/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationProxy.java
+++ b/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationProxy.java
@@ -39,7 +39,7 @@ public class AnnotationProxy implements Annotation, Invoca
@Override
public Class extends Annotation> annotationType() {
- return null;
+ return type;
}
@Override
From 580e2e9fbe1d3cc43bdc7f6ebaa0f28c96344a05 Mon Sep 17 00:00:00 2001
From: Looly
Date: Sat, 5 Mar 2022 23:49:27 +0800
Subject: [PATCH 03/13] add XXTEA
---
CHANGELOG.md | 3 +-
.../cn/hutool/crypto/symmetric/XXTEA.java | 157 ++++++++++++++++++
.../hutool/crypto/test/symmetric/TEATest.java | 19 ++-
3 files changed, 176 insertions(+), 3 deletions(-)
create mode 100644 hutool-crypto/src/main/java/cn/hutool/crypto/symmetric/XXTEA.java
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fcd3d51bd..74943728c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,12 +2,13 @@
# 🚀Changelog
-------------------------------------------------------------------------------------------------------------
-# 5.7.23 (2022-03-04)
+# 5.7.23 (2022-03-05)
### 🐣新特性
* 【http 】 HttpRequest.form采用TableMap方式(issue#I4W427@Gitee)
* 【core 】 AnnotationUtil增加getAnnotationAlias方法(pr#554@Gitee)
* 【core 】 FileUtil.extName增加对tar.gz特殊处理(issue#I4W5FS@Gitee)
+* 【crypto 】 增加XXTEA实现(issue#I4WH2X@Gitee)
### 🐞Bug修复
* 【core 】 修复ObjectUtil.hasNull传入null返回true的问题(pr#555@Gitee)
diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/symmetric/XXTEA.java b/hutool-crypto/src/main/java/cn/hutool/crypto/symmetric/XXTEA.java
new file mode 100644
index 000000000..4f948cd4f
--- /dev/null
+++ b/hutool-crypto/src/main/java/cn/hutool/crypto/symmetric/XXTEA.java
@@ -0,0 +1,157 @@
+package cn.hutool.crypto.symmetric;
+
+import cn.hutool.core.io.IoUtil;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+
+/**
+ * XXTEA(Corrected Block Tiny Encryption Algorithm)算法实现
+ * 来自:https://github.com/xxtea/xxtea-java
+ *
+ * @author Ma Bingyao
+ */
+public class XXTEA implements SymmetricEncryptor, SymmetricDecryptor, Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private static final int DELTA = 0x9E3779B9;
+
+ private final byte[] key;
+
+ /**
+ * 构造
+ *
+ * @param key 密钥,16位
+ */
+ public XXTEA(byte[] key) {
+ this.key = key;
+ }
+
+ @Override
+ public byte[] encrypt(byte[] data) {
+ if (data.length == 0) {
+ return data;
+ }
+ return toByteArray(encrypt(
+ toIntArray(data, true),
+ toIntArray(fixKey(key), false)), false);
+ }
+
+ @Override
+ public void encrypt(InputStream data, OutputStream out, boolean isClose) {
+ IoUtil.write(out, isClose, encrypt(IoUtil.readBytes(data)));
+ }
+
+ @Override
+ public byte[] decrypt(byte[] data) {
+ if (data.length == 0) {
+ return data;
+ }
+ return toByteArray(decrypt(
+ toIntArray(data, false),
+ toIntArray(fixKey(key), false)), true);
+ }
+
+ @Override
+ public void decrypt(InputStream data, OutputStream out, boolean isClose) {
+ IoUtil.write(out, isClose, decrypt(IoUtil.readBytes(data)));
+ }
+
+ //region Private Method
+ private static int[] encrypt(int[] v, int[] k) {
+ int n = v.length - 1;
+
+ if (n < 1) {
+ return v;
+ }
+ int p, q = 6 + 52 / (n + 1);
+ int z = v[n], y, sum = 0, e;
+
+ while (q-- > 0) {
+ sum = sum + DELTA;
+ e = sum >>> 2 & 3;
+ for (p = 0; p < n; p++) {
+ y = v[p + 1];
+ z = v[p] += mx(sum, y, z, p, e, k);
+ }
+ y = v[0];
+ z = v[n] += mx(sum, y, z, p, e, k);
+ }
+ return v;
+ }
+
+ private static int[] decrypt(int[] v, int[] k) {
+ int n = v.length - 1;
+
+ if (n < 1) {
+ return v;
+ }
+ int p, q = 6 + 52 / (n + 1);
+ int z, y = v[0], sum = q * DELTA, e;
+
+ while (sum != 0) {
+ e = sum >>> 2 & 3;
+ for (p = n; p > 0; p--) {
+ z = v[p - 1];
+ y = v[p] -= mx(sum, y, z, p, e, k);
+ }
+ z = v[n];
+ y = v[0] -= mx(sum, y, z, p, e, k);
+ sum = sum - DELTA;
+ }
+ return v;
+ }
+
+ private static int mx(int sum, int y, int z, int p, int e, int[] k) {
+ return (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
+ }
+
+ private static byte[] fixKey(byte[] key) {
+ if (key.length == 16) {
+ return key;
+ }
+ byte[] fixedkey = new byte[16];
+ System.arraycopy(key, 0, fixedkey, 0, Math.min(key.length, 16));
+ return fixedkey;
+ }
+
+ private static int[] toIntArray(byte[] data, boolean includeLength) {
+ int n = (((data.length & 3) == 0)
+ ? (data.length >>> 2)
+ : ((data.length >>> 2) + 1));
+ int[] result;
+
+ if (includeLength) {
+ result = new int[n + 1];
+ result[n] = data.length;
+ } else {
+ result = new int[n];
+ }
+ n = data.length;
+ for (int i = 0; i < n; ++i) {
+ result[i >>> 2] |= (0x000000ff & data[i]) << ((i & 3) << 3);
+ }
+ return result;
+ }
+
+ private static byte[] toByteArray(int[] data, boolean includeLength) {
+ int n = data.length << 2;
+
+ if (includeLength) {
+ int m = data[data.length - 1];
+ n -= 4;
+ if ((m < n - 3) || (m > n)) {
+ return null;
+ }
+ n = m;
+ }
+ byte[] result = new byte[n];
+
+ for (int i = 0; i < n; ++i) {
+ result[i] = (byte) (data[i >>> 2] >>> ((i & 3) << 3));
+ }
+ return result;
+ }
+ //endregion
+}
diff --git a/hutool-crypto/src/test/java/cn/hutool/crypto/test/symmetric/TEATest.java b/hutool-crypto/src/test/java/cn/hutool/crypto/test/symmetric/TEATest.java
index 8a9d008d6..53916926a 100644
--- a/hutool-crypto/src/test/java/cn/hutool/crypto/test/symmetric/TEATest.java
+++ b/hutool-crypto/src/test/java/cn/hutool/crypto/test/symmetric/TEATest.java
@@ -1,6 +1,7 @@
package cn.hutool.crypto.test.symmetric;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
+import cn.hutool.crypto.symmetric.XXTEA;
import org.junit.Assert;
import org.junit.Test;
@@ -10,7 +11,7 @@ import org.junit.Test;
public class TEATest {
@Test
- public void teaTest(){
+ public void teaTest() {
String data = "测试的加密数据 by Hutool";
// 密钥必须为128bit
@@ -24,7 +25,7 @@ public class TEATest {
}
@Test
- public void xteaTest(){
+ public void xteaTest() {
String data = "测试的加密数据 by Hutool";
// 密钥必须为128bit
@@ -36,4 +37,18 @@ public class TEATest {
Assert.assertEquals(data, decryptStr);
}
+
+ @Test
+ public void xxteaTest() {
+ String data = "测试的加密数据 by Hutool";
+
+ // 密钥必须为128bit
+ final XXTEA tea = new XXTEA("MyPassword123456".getBytes());
+ final byte[] encrypt = tea.encrypt(data);
+
+ // 解密
+ final String decryptStr = tea.decryptStr(encrypt);
+
+ Assert.assertEquals(data, decryptStr);
+ }
}
From 4b22f7cc74c1ba6155228e745bd79c9a46b1eb9f Mon Sep 17 00:00:00 2001
From: Looly
Date: Sun, 6 Mar 2022 19:22:29 +0800
Subject: [PATCH 04/13] fix code
---
.../java/cn/hutool/script/ScriptRuntimeException.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/hutool-script/src/main/java/cn/hutool/script/ScriptRuntimeException.java b/hutool-script/src/main/java/cn/hutool/script/ScriptRuntimeException.java
index c609ebbf7..48b62e085 100644
--- a/hutool-script/src/main/java/cn/hutool/script/ScriptRuntimeException.java
+++ b/hutool-script/src/main/java/cn/hutool/script/ScriptRuntimeException.java
@@ -42,11 +42,11 @@ public class ScriptRuntimeException extends RuntimeException {
}
/**
- * Creates a ScriptException with message, filename and linenumber to be used in error messages.
+ * Creates a {@code ScriptException} with message, filename and linenumber to be used in error messages.
*
* @param message The string to use in the message
- * @param fileName The file or resource name describing the location of a script error causing the ScriptException to be thrown.
- * @param lineNumber A line number describing the location of a script error causing the ScriptException to be thrown.
+ * @param fileName The file or resource name describing the location of a script error causing the {@code ScriptException} to be thrown.
+ * @param lineNumber A line number describing the location of a script error causing the {@code ScriptException} to be thrown.
*/
public ScriptRuntimeException(String message, String fileName, int lineNumber) {
super(message);
@@ -55,7 +55,7 @@ public class ScriptRuntimeException extends RuntimeException {
}
/**
- * ScriptException constructor specifying message, filename, line number and column number.
+ * {@code ScriptException} constructor specifying message, filename, line number and column number.
*
* @param message The message.
* @param fileName The filename
From 1e113ef83f071485ec24fa5c0bff920f566e29bb Mon Sep 17 00:00:00 2001
From: Looly
Date: Sun, 6 Mar 2022 21:01:08 +0800
Subject: [PATCH 05/13] fix code
---
.../java/cn/hutool/core/bean/BeanUtil.java | 4 +-
.../hutool/core/map/CamelCaseLinkedMap.java | 20 +---------
.../java/cn/hutool/core/map/CamelCaseMap.java | 38 ++++++++++---------
.../core/map/CaseInsensitiveLinkedMap.java | 16 +-------
.../hutool/core/map/CaseInsensitiveMap.java | 31 ++++++++-------
.../core/map/CaseInsensitiveTreeMap.java | 18 +--------
.../java/cn/hutool/core/map/CustomKeyMap.java | 6 +--
.../hutool/core/map/FixedLinkedHashMap.java | 3 +-
.../java/cn/hutool/core/map/FuncKeyMap.java | 9 +++--
.../java/cn/hutool/core/map/MapBuilder.java | 13 ++++++-
.../java/cn/hutool/core/map/MapWrapper.java | 5 ---
.../cn/hutool/core/bean/BeanUtilTest.java | 16 ++++----
12 files changed, 75 insertions(+), 104 deletions(-)
diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/BeanUtil.java b/hutool-core/src/main/java/cn/hutool/core/bean/BeanUtil.java
index b66b15f0d..84e7c5917 100644
--- a/hutool-core/src/main/java/cn/hutool/core/bean/BeanUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/bean/BeanUtil.java
@@ -225,8 +225,8 @@ public class BeanUtil {
*/
private static Map internalGetPropertyDescriptorMap(Class> clazz, boolean ignoreCase) throws BeanException {
final PropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(clazz);
- final Map map = ignoreCase ? new CaseInsensitiveMap<>(propertyDescriptors.length, 1)
- : new HashMap<>((int) (propertyDescriptors.length), 1);
+ final Map map = ignoreCase ? new CaseInsensitiveMap<>(propertyDescriptors.length, 1f)
+ : new HashMap<>(propertyDescriptors.length, 1);
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
map.put(propertyDescriptor.getName(), propertyDescriptor);
diff --git a/hutool-core/src/main/java/cn/hutool/core/map/CamelCaseLinkedMap.java b/hutool-core/src/main/java/cn/hutool/core/map/CamelCaseLinkedMap.java
index fbd2b776c..639bfbfcc 100644
--- a/hutool-core/src/main/java/cn/hutool/core/map/CamelCaseLinkedMap.java
+++ b/hutool-core/src/main/java/cn/hutool/core/map/CamelCaseLinkedMap.java
@@ -1,7 +1,5 @@
package cn.hutool.core.map;
-import cn.hutool.core.util.StrUtil;
-
import java.util.LinkedHashMap;
import java.util.Map;
@@ -15,7 +13,7 @@ import java.util.Map;
* @param 值类型
* @since 4.0.7
*/
-public class CamelCaseLinkedMap extends CustomKeyMap {
+public class CamelCaseLinkedMap extends CamelCaseMap {
private static final long serialVersionUID = 4043263744224569870L;
// ------------------------------------------------------------------------- Constructor start
@@ -48,7 +46,7 @@ public class CamelCaseLinkedMap extends CustomKeyMap {
* 构造
*
* @param loadFactor 加载因子
- * @param m Map
+ * @param m Map,数据会被默认拷贝到一个新的LinkedHashMap中
*/
public CamelCaseLinkedMap(float loadFactor, Map extends K, ? extends V> m) {
this(m.size(), loadFactor);
@@ -65,18 +63,4 @@ public class CamelCaseLinkedMap extends CustomKeyMap {
super(new LinkedHashMap<>(initialCapacity, loadFactor));
}
// ------------------------------------------------------------------------- Constructor end
-
- /**
- * 将Key转为驼峰风格,如果key为字符串的话
- *
- * @param key KEY
- * @return 驼峰Key
- */
- @Override
- protected Object customKey(Object key) {
- if (key instanceof CharSequence) {
- key = StrUtil.toCamelCase(key.toString());
- }
- return key;
- }
}
diff --git a/hutool-core/src/main/java/cn/hutool/core/map/CamelCaseMap.java b/hutool-core/src/main/java/cn/hutool/core/map/CamelCaseMap.java
index ea1642d14..4759b7202 100644
--- a/hutool-core/src/main/java/cn/hutool/core/map/CamelCaseMap.java
+++ b/hutool-core/src/main/java/cn/hutool/core/map/CamelCaseMap.java
@@ -1,24 +1,24 @@
package cn.hutool.core.map;
+import cn.hutool.core.util.StrUtil;
+
import java.util.HashMap;
import java.util.Map;
-import cn.hutool.core.util.StrUtil;
-
/**
* 驼峰Key风格的Map
* 对KEY转换为驼峰,get("int_value")和get("intValue")获得的值相同,put进入的值也会被覆盖
*
- * @author Looly
- *
* @param 键类型
* @param 值类型
+ * @author Looly
* @since 4.0.7
*/
-public class CamelCaseMap extends CustomKeyMap {
+public class CamelCaseMap extends FuncKeyMap {
private static final long serialVersionUID = 4043263744224569870L;
// ------------------------------------------------------------------------- Constructor start
+
/**
* 构造
*/
@@ -48,7 +48,7 @@ public class CamelCaseMap extends CustomKeyMap {
* 构造
*
* @param loadFactor 加载因子
- * @param m Map
+ * @param m 初始Map,数据会被默认拷贝到一个新的HashMap中
*/
public CamelCaseMap(float loadFactor, Map extends K, ? extends V> m) {
this(m.size(), loadFactor);
@@ -59,24 +59,26 @@ public class CamelCaseMap extends CustomKeyMap {
* 构造
*
* @param initialCapacity 初始大小
- * @param loadFactor 加载因子
+ * @param loadFactor 加载因子
*/
public CamelCaseMap(int initialCapacity, float loadFactor) {
- super(new HashMap<>(initialCapacity, loadFactor));
+ this(MapBuilder.create(new HashMap<>(initialCapacity, loadFactor)));
}
- // ------------------------------------------------------------------------- Constructor end
/**
- * 将Key转为驼峰风格,如果key为字符串的话
+ * 构造
+ * 注意此构造将传入的Map作为被包装的Map,针对任何修改,传入的Map都会被同样修改。
*
- * @param key KEY
- * @return 驼峰Key
+ * @param emptyMapBuilder Map构造器,必须构造空的Map
*/
- @Override
- protected Object customKey(Object key) {
- if (key instanceof CharSequence) {
- key = StrUtil.toCamelCase(key.toString());
- }
- return key;
+ CamelCaseMap(MapBuilder emptyMapBuilder) {
+ super(emptyMapBuilder.build(), (key) -> {
+ if (key instanceof CharSequence) {
+ key = StrUtil.toCamelCase(key.toString());
+ }
+ //noinspection unchecked
+ return (K) key;
+ });
}
+ // ------------------------------------------------------------------------- Constructor end
}
diff --git a/hutool-core/src/main/java/cn/hutool/core/map/CaseInsensitiveLinkedMap.java b/hutool-core/src/main/java/cn/hutool/core/map/CaseInsensitiveLinkedMap.java
index 51cdd2561..5be588ef3 100644
--- a/hutool-core/src/main/java/cn/hutool/core/map/CaseInsensitiveLinkedMap.java
+++ b/hutool-core/src/main/java/cn/hutool/core/map/CaseInsensitiveLinkedMap.java
@@ -13,7 +13,7 @@ import java.util.Map;
* @param 值类型
* @since 3.3.1
*/
-public class CaseInsensitiveLinkedMap extends CustomKeyMap {
+public class CaseInsensitiveLinkedMap extends CaseInsensitiveMap {
private static final long serialVersionUID = 4043263744224569870L;
// ------------------------------------------------------------------------- Constructor start
@@ -64,18 +64,4 @@ public class CaseInsensitiveLinkedMap extends CustomKeyMap {
super(new LinkedHashMap<>(initialCapacity, loadFactor));
}
// ------------------------------------------------------------------------- Constructor end
-
- /**
- * 将Key转为小写
- *
- * @param key KEY
- * @return 小写KEY
- */
- @Override
- protected Object customKey(Object key) {
- if (key instanceof CharSequence) {
- key = key.toString().toLowerCase();
- }
- return key;
- }
}
diff --git a/hutool-core/src/main/java/cn/hutool/core/map/CaseInsensitiveMap.java b/hutool-core/src/main/java/cn/hutool/core/map/CaseInsensitiveMap.java
index 0c892b268..40f805ad0 100644
--- a/hutool-core/src/main/java/cn/hutool/core/map/CaseInsensitiveMap.java
+++ b/hutool-core/src/main/java/cn/hutool/core/map/CaseInsensitiveMap.java
@@ -13,7 +13,7 @@ import java.util.Map;
* @param 值类型
* @since 3.0.2
*/
-public class CaseInsensitiveMap extends CustomKeyMap {
+public class CaseInsensitiveMap extends FuncKeyMap {
private static final long serialVersionUID = 4043263744224569870L;
//------------------------------------------------------------------------- Constructor start
@@ -34,9 +34,10 @@ public class CaseInsensitiveMap extends CustomKeyMap {
}
/**
- * 构造
+ * 构造
+ * 注意此构造将传入的Map作为被包装的Map,针对任何修改,传入的Map都会被同样修改。
*
- * @param m Map
+ * @param m 被包装的自定义Map创建器
*/
public CaseInsensitiveMap(Map extends K, ? extends V> m) {
this(DEFAULT_LOAD_FACTOR, m);
@@ -61,21 +62,23 @@ public class CaseInsensitiveMap extends CustomKeyMap {
* @param loadFactor 加载因子
*/
public CaseInsensitiveMap(int initialCapacity, float loadFactor) {
- super(new HashMap<>(initialCapacity, loadFactor));
+ this(MapBuilder.create(new HashMap<>(initialCapacity, loadFactor)));
}
- //------------------------------------------------------------------------- Constructor end
/**
- * 将Key转为小写
+ * 构造
+ * 注意此构造将传入的Map作为被包装的Map,针对任何修改,传入的Map都会被同样修改。
*
- * @param key KEY
- * @return 小写KEY
+ * @param emptyMapBuilder 被包装的自定义Map创建器
*/
- @Override
- protected Object customKey(Object key) {
- if (key instanceof CharSequence) {
- key = key.toString().toLowerCase();
- }
- return key;
+ CaseInsensitiveMap(MapBuilder emptyMapBuilder) {
+ super(emptyMapBuilder.build(), (key)->{
+ if (key instanceof CharSequence) {
+ key = key.toString().toLowerCase();
+ }
+ //noinspection unchecked
+ return (K) key;
+ });
}
+ //------------------------------------------------------------------------- Constructor end
}
diff --git a/hutool-core/src/main/java/cn/hutool/core/map/CaseInsensitiveTreeMap.java b/hutool-core/src/main/java/cn/hutool/core/map/CaseInsensitiveTreeMap.java
index 7f8b065f6..69f3ec538 100755
--- a/hutool-core/src/main/java/cn/hutool/core/map/CaseInsensitiveTreeMap.java
+++ b/hutool-core/src/main/java/cn/hutool/core/map/CaseInsensitiveTreeMap.java
@@ -15,7 +15,7 @@ import java.util.TreeMap;
* @param 值类型
* @since 3.3.1
*/
-public class CaseInsensitiveTreeMap extends CustomKeyMap {
+public class CaseInsensitiveTreeMap extends CaseInsensitiveMap {
private static final long serialVersionUID = 4043263744224569870L;
// ------------------------------------------------------------------------- Constructor start
@@ -40,7 +40,7 @@ public class CaseInsensitiveTreeMap extends CustomKeyMap {
/**
* 构造
*
- * @param m Map
+ * @param m Map,初始Map,键值对会被复制到新的TreeMap中
* @since 3.1.2
*/
public CaseInsensitiveTreeMap(SortedMap extends K, ? extends V> m) {
@@ -56,18 +56,4 @@ public class CaseInsensitiveTreeMap extends CustomKeyMap {
super(new TreeMap<>(comparator));
}
// ------------------------------------------------------------------------- Constructor end
-
- /**
- * 将Key转为小写
- *
- * @param key KEY
- * @return 小写KEY
- */
- @Override
- protected Object customKey(Object key) {
- if (key instanceof CharSequence) {
- key = key.toString().toLowerCase();
- }
- return key;
- }
}
diff --git a/hutool-core/src/main/java/cn/hutool/core/map/CustomKeyMap.java b/hutool-core/src/main/java/cn/hutool/core/map/CustomKeyMap.java
index 4584943a5..04ed9d371 100644
--- a/hutool-core/src/main/java/cn/hutool/core/map/CustomKeyMap.java
+++ b/hutool-core/src/main/java/cn/hutool/core/map/CustomKeyMap.java
@@ -18,11 +18,11 @@ public abstract class CustomKeyMap extends MapWrapper {
* 构造
* 通过传入一个Map从而确定Map的类型,子类需创建一个空的Map,而非传入一个已有Map,否则值可能会被修改
*
- * @param m Map 被包装的Map
+ * @param emptyMap Map 被包装的Map,必须为空Map,否则自定义key会无效
* @since 3.1.2
*/
- public CustomKeyMap(Map m) {
- super(m);
+ public CustomKeyMap(Map emptyMap) {
+ super(emptyMap);
}
@Override
diff --git a/hutool-core/src/main/java/cn/hutool/core/map/FixedLinkedHashMap.java b/hutool-core/src/main/java/cn/hutool/core/map/FixedLinkedHashMap.java
index 1559fde7a..5ddaaa6f9 100644
--- a/hutool-core/src/main/java/cn/hutool/core/map/FixedLinkedHashMap.java
+++ b/hutool-core/src/main/java/cn/hutool/core/map/FixedLinkedHashMap.java
@@ -3,7 +3,8 @@ package cn.hutool.core.map;
import java.util.LinkedHashMap;
/**
- * 固定大小的{@link LinkedHashMap} 实现
+ * 固定大小的{@link LinkedHashMap} 实现
+ * 注意此类非线程安全,由于{@link #get(Object)}操作会修改链表的顺序结构,因此也不可以使用读写锁。
*
* @author looly
*
diff --git a/hutool-core/src/main/java/cn/hutool/core/map/FuncKeyMap.java b/hutool-core/src/main/java/cn/hutool/core/map/FuncKeyMap.java
index e5ca6a719..0cc468d61 100644
--- a/hutool-core/src/main/java/cn/hutool/core/map/FuncKeyMap.java
+++ b/hutool-core/src/main/java/cn/hutool/core/map/FuncKeyMap.java
@@ -19,13 +19,14 @@ public class FuncKeyMap extends CustomKeyMap {
// ------------------------------------------------------------------------- Constructor start
/**
- * 构造
+ * 构造
+ * 注意提供的Map中不能有键值对,否则可能导致自定义key失效
*
- * @param m Map
+ * @param emptyMap Map,提供的空map
* @param keyFunc 自定义KEY的函数
*/
- public FuncKeyMap(Map m, Function
*
- * @param lhs this object
+ * @param lhs {@code this} object
* @param rhs the other object
* @return the pair
*/
@@ -82,15 +82,15 @@ public class EqualsBuilder implements Builder {
/**
*
- * Returns true if the registry contains the given object pair.
+ * Returns {@code true} if the registry contains the given object pair.
* Used by the reflection methods to avoid infinite loops.
* Objects might be swapped therefore a check is needed if the object pair
* is registered in given or swapped order.
*
*
- * @param lhs this object to lookup in registry
+ * @param lhs {@code this} object to lookup in registry
* @param rhs the other object to lookup on registry
- * @return boolean true if the registry contains the given object.
+ * @return boolean {@code true} if the registry contains the given object.
* @since 3.0
*/
static boolean isRegistered(final Object lhs, final Object rhs) {
@@ -108,7 +108,7 @@ public class EqualsBuilder implements Builder {
* Used by the reflection methods to avoid infinite loops.
*
*
- * @param lhs this object to register
+ * @param lhs {@code this} object to register
* @param rhs the other object to register
*/
static void register(final Object lhs, final Object rhs) {
@@ -131,7 +131,7 @@ public class EqualsBuilder implements Builder {
*
* Used by the reflection methods to avoid infinite loops.
*
- * @param lhs this object to unregister
+ * @param lhs {@code this} object to unregister
* @param rhs the other object to unregister
* @since 3.0
*/
@@ -170,7 +170,7 @@ public class EqualsBuilder implements Builder {
* @param lhs 此对象
* @param rhs 另一个对象
* @param excludeFields 排除的字段集合,如果有不参与计算equals的字段加入此集合即可
- * @return 两个对象是否equals,是返回true
+ * @return 两个对象是否equals,是返回{@code true}
*/
public static boolean reflectionEquals(final Object lhs, final Object rhs, final Collection excludeFields) {
return reflectionEquals(lhs, rhs, ArrayUtil.toArray(excludeFields, String.class));
@@ -182,62 +182,62 @@ public class EqualsBuilder implements Builder {
* @param lhs 此对象
* @param rhs 另一个对象
* @param excludeFields 排除的字段集合,如果有不参与计算equals的字段加入此集合即可
- * @return 两个对象是否equals,是返回true
+ * @return 两个对象是否equals,是返回{@code true}
*/
public static boolean reflectionEquals(final Object lhs, final Object rhs, final String... excludeFields) {
return reflectionEquals(lhs, rhs, false, null, excludeFields);
}
/**
- *
This method uses reflection to determine if the two Objects
+ *
This method uses reflection to determine if the two {@code Object}s
* are equal.
*
- *
It uses AccessibleObject.setAccessible to gain access to private
+ *
It uses {@code AccessibleObject.setAccessible} to gain access to private
* fields. This means that it will throw a security exception if run under
* a security manager, if the permissions are not set up correctly. It is also
* not as efficient as testing explicitly. Non-primitive fields are compared using
- * equals().
+ * {@code equals()}.
*
- *
If the TestTransients parameter is set to true, transient
+ *
If the TestTransients parameter is set to {@code true}, transient
* members will be tested, otherwise they are ignored, as they are likely
- * derived fields, and not part of the value of the Object.
+ * derived fields, and not part of the value of the {@code Object}.
*
*
Static fields will not be tested. Superclass fields will be included.
*
- * @param lhs this object
+ * @param lhs {@code this} object
* @param rhs the other object
* @param testTransients whether to include transient fields
- * @return true if the two Objects have tested equals.
+ * @return {@code true} if the two Objects have tested equals.
*/
public static boolean reflectionEquals(final Object lhs, final Object rhs, final boolean testTransients) {
return reflectionEquals(lhs, rhs, testTransients, null);
}
/**
- *
This method uses reflection to determine if the two Objects
+ *
This method uses reflection to determine if the two {@code Object}s
* are equal.
*
- *
It uses AccessibleObject.setAccessible to gain access to private
+ *
It uses {@code AccessibleObject.setAccessible} to gain access to private
* fields. This means that it will throw a security exception if run under
* a security manager, if the permissions are not set up correctly. It is also
* not as efficient as testing explicitly. Non-primitive fields are compared using
- * equals().
+ * {@code equals()}.
*
- *
If the testTransients parameter is set to true, transient
+ *
If the testTransients parameter is set to {@code true}, transient
* members will be tested, otherwise they are ignored, as they are likely
- * derived fields, and not part of the value of the Object.
+ * derived fields, and not part of the value of the {@code Object}.
*
*
Static fields will not be included. Superclass fields will be appended
* up to and including the specified superclass. A null superclass is treated
* as java.lang.Object.
*
- * @param lhs this object
+ * @param lhs {@code this} object
* @param rhs the other object
* @param testTransients whether to include transient fields
* @param reflectUpToClass the superclass to reflect up to (inclusive),
- * may be null
+ * may be {@code null}
* @param excludeFields array of field names to exclude from testing
- * @return true if the two Objects have tested equals.
+ * @return {@code true} if the two Objects have tested equals.
* @since 2.0
*/
public static boolean reflectionEquals(final Object lhs, final Object rhs, final boolean testTransients, final Class> reflectUpToClass,
@@ -343,9 +343,9 @@ public class EqualsBuilder implements Builder {
//-------------------------------------------------------------------------
/**
- *
Adds the result of super.equals() to this builder.
+ *
Adds the result of {@code super.equals()} to this builder.
*
- * @param superEquals the result of calling super.equals()
+ * @param superEquals the result of calling {@code super.equals()}
* @return EqualsBuilder - used to chain calls.
* @since 2.0
*/
@@ -360,8 +360,8 @@ public class EqualsBuilder implements Builder {
//-------------------------------------------------------------------------
/**
- *
Test if two Objects are equal using their
- * equals method.
+ *
Test if two {@code Object}s are equal using their
+ * {@code equals} method.
*
* @param lhs the left hand object
* @param rhs the right hand object
@@ -388,11 +388,11 @@ public class EqualsBuilder implements Builder {
/**
*
- * Test if two long s are equal.
+ * Test if two {@code long} s are equal.
*
*
- * @param lhs the left hand long
- * @param rhs the right hand long
+ * @param lhs the left hand {@code long}
+ * @param rhs the right hand {@code long}
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(final long lhs, final long rhs) {
@@ -404,10 +404,10 @@ public class EqualsBuilder implements Builder {
}
/**
- *
Test if two ints are equal.
+ *
Test if two {@code int}s are equal.
*
- * @param lhs the left hand int
- * @param rhs the right hand int
+ * @param lhs the left hand {@code int}
+ * @param rhs the right hand {@code int}
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(final int lhs, final int rhs) {
@@ -419,10 +419,10 @@ public class EqualsBuilder implements Builder {
}
/**
- *
Test if two shorts are equal.
+ *
Test if two {@code short}s are equal.
*
- * @param lhs the left hand short
- * @param rhs the right hand short
+ * @param lhs the left hand {@code short}
+ * @param rhs the right hand {@code short}
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(final short lhs, final short rhs) {
@@ -434,10 +434,10 @@ public class EqualsBuilder implements Builder {
}
/**
- *
Test if two chars are equal.
+ *
Test if two {@code char}s are equal.
*
- * @param lhs the left hand char
- * @param rhs the right hand char
+ * @param lhs the left hand {@code char}
+ * @param rhs the right hand {@code char}
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(final char lhs, final char rhs) {
@@ -449,10 +449,10 @@ public class EqualsBuilder implements Builder {
}
/**
- *
Test if two bytes are equal.
+ *
Test if two {@code byte}s are equal.
*
- * @param lhs the left hand byte
- * @param rhs the right hand byte
+ * @param lhs the left hand {@code byte}
+ * @param rhs the right hand {@code byte}
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(final byte lhs, final byte rhs) {
@@ -464,16 +464,16 @@ public class EqualsBuilder implements Builder {
}
/**
- *
Test if two doubles are equal by testing that the
- * pattern of bits returned by doubleToLong are equal.
+ *
Test if two {@code double}s are equal by testing that the
+ * pattern of bits returned by {@code doubleToLong} are equal.
*
- *
This handles NaNs, Infinities, and -0.0.
+ *
This handles NaNs, Infinities, and {@code -0.0}.
*
*
It is compatible with the hash code generated by
- * HashCodeBuilder.
+ * {@code HashCodeBuilder}.
*
- * @param lhs the left hand double
- * @param rhs the right hand double
+ * @param lhs the left hand {@code double}
+ * @param rhs the right hand {@code double}
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(final double lhs, final double rhs) {
@@ -484,16 +484,16 @@ public class EqualsBuilder implements Builder {
}
/**
- *
Test if two floats are equal byt testing that the
+ *
Test if two {@code float}s are equal byt testing that the
* pattern of bits returned by doubleToLong are equal.
*
- *
This handles NaNs, Infinities, and -0.0.
+ *
This handles NaNs, Infinities, and {@code -0.0}.
*
*
It is compatible with the hash code generated by
- * HashCodeBuilder.
+ * {@code HashCodeBuilder}.
*
- * @param lhs the left hand float
- * @param rhs the right hand float
+ * @param lhs the left hand {@code float}
+ * @param rhs the right hand {@code float}
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(final float lhs, final float rhs) {
@@ -504,10 +504,10 @@ public class EqualsBuilder implements Builder {
}
/**
- *
Test if two booleanss are equal.
+ *
Test if two {@code booleans}s are equal.
*
- * @param lhs the left hand boolean
- * @param rhs the right hand boolean
+ * @param lhs the left hand {@code boolean}
+ * @param rhs the right hand {@code boolean}
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(final boolean lhs, final boolean rhs) {
@@ -519,7 +519,7 @@ public class EqualsBuilder implements Builder {
}
/**
- *
Returns true if the fields that have been checked
+ *
Returns {@code true} if the fields that have been checked
* are all equal.
*
* @return boolean
@@ -529,11 +529,11 @@ public class EqualsBuilder implements Builder {
}
/**
- *
Returns true if the fields that have been checked
+ *
Returns {@code true} if the fields that have been checked
* are all equal.