From b73d7b2e68c8856a4e9a833263e373eacfba454f Mon Sep 17 00:00:00 2001 From: Looly Date: Sun, 16 Apr 2023 10:47:18 +0800 Subject: [PATCH] fix code --- .../dromara/hutool/core/map/TripleTable.java | 284 ++++++++++++++++++ .../hutool/core/reflect/ClassDescUtil.java | 61 ++-- 2 files changed, 313 insertions(+), 32 deletions(-) create mode 100644 hutool-core/src/main/java/org/dromara/hutool/core/map/TripleTable.java diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/map/TripleTable.java b/hutool-core/src/main/java/org/dromara/hutool/core/map/TripleTable.java new file mode 100644 index 000000000..d647da3da --- /dev/null +++ b/hutool-core/src/main/java/org/dromara/hutool/core/map/TripleTable.java @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2023 looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.core.map; + +import org.dromara.hutool.core.lang.Assert; +import org.dromara.hutool.core.lang.tuple.Triple; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * 三值表结构,可重复
+ * 用于提供三种值相互查找操作
+ * 查找方式为indexOf方式遍历查找,数据越多越慢。 + * + * @param 左值类型 + * @param 中值类型 + * @param 右值类型 + * @author looly + * @since 6.0.0 + */ +public class TripleTable implements Serializable { + private static final long serialVersionUID = 1L; + + private final List lList; + private final List mList; + private final List rList; + + /** + * 构造 + * + * @param triples 三元组列表 + */ + public TripleTable(final List> triples) { + this(Assert.notNull(triples).size()); + for (final Triple triple : triples) { + put(triple.getLeft(), triple.getMiddle(), triple.getRight()); + } + } + + /** + * 构造 + * + * @param size 初始容量 + */ + public TripleTable(final int size) { + this(new ArrayList<>(size), new ArrayList<>(size), new ArrayList<>(size)); + } + + /** + * @param lList 左列表 + * @param mList 中列表 + * @param rList 右列表 + */ + public TripleTable(final List lList, final List mList, final List rList) { + Assert.notNull(lList); + Assert.notNull(mList); + Assert.notNull(rList); + final int size = lList.size(); + if (size != mList.size() || size != rList.size()) { + throw new IllegalArgumentException("List size must be equals!"); + } + + this.lList = lList; + this.mList = mList; + this.rList = rList; + } + + // region ----- getLeft + + /** + * 通过中间值,查找左边值
+ * 如果有多个重复值,只返回找到的第一个值 + * + * @param mValue 中间值 + * @return 左边值,未找到返回{@code null} + */ + public L getLeftByMiddle(final M mValue) { + final int index = this.mList.indexOf(mValue); + if (index > -1) { + return this.lList.get(index); + } + return null; + } + + /** + * 通过右值,查找左边值
+ * 如果有多个重复值,只返回找到的第一个值 + * + * @param rValue 右值 + * @return 左边值,未找到返回{@code null} + */ + public L getLeftByRight(final R rValue) { + final int index = this.rList.indexOf(rValue); + if (index > -1) { + return this.lList.get(index); + } + return null; + } + // endregion + + // region ----- getMiddle + + /** + * 通过左值,查找中值
+ * 如果有多个重复值,只返回找到的第一个值 + * + * @param lValue 左值 + * @return 中值,未找到返回{@code null} + */ + public M getMiddleByLeft(final L lValue) { + final int index = this.lList.indexOf(lValue); + if (index > -1) { + return this.mList.get(index); + } + return null; + } + + /** + * 通过右值,查找中值
+ * 如果有多个重复值,只返回找到的第一个值 + * + * @param rValue 右值 + * @return 中值,未找到返回{@code null} + */ + public M getMiddleByRight(final R rValue) { + final int index = this.rList.indexOf(rValue); + if (index > -1) { + return this.mList.get(index); + } + return null; + } + // endregion + + // region ----- getRight + + /** + * 通过左值,查找右值
+ * 如果有多个重复值,只返回找到的第一个值 + * + * @param lValue 左值 + * @return 右值,未找到返回{@code null} + */ + public R getRightByLeft(final L lValue) { + final int index = this.lList.indexOf(lValue); + if (index > -1) { + return this.rList.get(index); + } + return null; + } + + /** + * 通过中间值,查找右值
+ * 如果有多个重复值,只返回找到的第一个值 + * + * @param mValue 中间值 + * @return 右值,未找到返回{@code null} + */ + public R getRightByMiddle(final M mValue) { + final int index = this.mList.indexOf(mValue); + if (index > -1) { + return this.rList.get(index); + } + return null; + } + // endregion + + // region ----- getBy + + /** + * 通过左值查找三元组(所有值) + * + * @param lValue 左值 + * @return 三元组(所有值) + */ + public Triple getByLeft(final L lValue) { + final int index = this.lList.indexOf(lValue); + if (index > -1) { + return new Triple<>( + lList.get(index), + mList.get(index), + rList.get(index) + ); + } + return null; + } + + /** + * 通过中值查找三元组(所有值) + * + * @param mValue 中值 + * @return 三元组(所有值) + */ + public Triple getByMiddle(final M mValue) { + final int index = this.mList.indexOf(mValue); + if (index > -1) { + return new Triple<>( + lList.get(index), + mList.get(index), + rList.get(index) + ); + } + return null; + } + + /** + * 通过右值查找三元组(所有值) + * + * @param rValue 右值 + * @return 三元组(所有值) + */ + public Triple getByRight(final R rValue) { + final int index = this.rList.indexOf(rValue); + if (index > -1) { + return new Triple<>( + lList.get(index), + mList.get(index), + rList.get(index) + ); + } + return null; + } + // endregion + + /** + * 长度 + * + * @return this + */ + public int size() { + return this.lList.size(); + } + + /** + * 加入值 + * + * @param lValue 左值 + * @param mValue 中值 + * @param rValue 右值 + * @return this + */ + public TripleTable put(final L lValue, final M mValue, final R rValue) { + this.lList.add(lValue); + this.mList.add(mValue); + this.rList.add(rValue); + return this; + } + + /** + * 清空 + * + * @return this + */ + public TripleTable clear() { + this.lList.clear(); + this.mList.clear(); + this.rList.clear(); + return this; + } + + /** + * 移除值 + * + * @param index 序号 + * @return this + */ + public TripleTable remove(final int index) { + this.lList.remove(index); + this.mList.remove(index); + this.rList.remove(index); + return this; + } +} diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/ClassDescUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/ClassDescUtil.java index ebce586fe..473114ff4 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/ClassDescUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/ClassDescUtil.java @@ -14,7 +14,7 @@ package org.dromara.hutool.core.reflect; import org.dromara.hutool.core.exceptions.UtilException; import org.dromara.hutool.core.lang.Assert; -import org.dromara.hutool.core.map.BiMap; +import org.dromara.hutool.core.map.TripleTable; import org.dromara.hutool.core.text.StrTrimer; import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.util.CharUtil; @@ -24,7 +24,6 @@ import java.lang.reflect.Method; import java.net.URL; import java.security.CodeSource; import java.security.ProtectionDomain; -import java.util.HashMap; /** * 类描述工具类
@@ -48,6 +47,8 @@ import java.util.HashMap; * @since 6.0.0 */ public class ClassDescUtil { + + // region ----- const /** * void(V). */ @@ -92,32 +93,28 @@ public class ClassDescUtil { * short(S). */ public static final char JVM_SHORT = 'S'; + // endregion /** - * 原始类型名和其class对应表,例如:int.class 《=》 int + * 9种原始类型对应表
+ *
+	 *     左:原始类型
+	 *     中:原始类型描述符
+	 *     右:原始类型名称
+	 * 
*/ - private static final BiMap, Character> PRIMITIVE_CLASS_DESC_MAP = new BiMap<>(new HashMap<>(9, 1)); - private static final BiMap, String> PRIMITIVE_CLASS_NAME_MAP = new BiMap<>(new HashMap<>(9, 1)); + private static final TripleTable, Character, String> PRIMITIVE_TABLE = new TripleTable<>(9); static { - PRIMITIVE_CLASS_DESC_MAP.put(void.class, JVM_VOID); - PRIMITIVE_CLASS_NAME_MAP.put(void.class, "void"); - PRIMITIVE_CLASS_DESC_MAP.put(boolean.class, JVM_BOOLEAN); - PRIMITIVE_CLASS_NAME_MAP.put(boolean.class, "boolean"); - PRIMITIVE_CLASS_DESC_MAP.put(byte.class, JVM_BYTE); - PRIMITIVE_CLASS_NAME_MAP.put(byte.class, "byte"); - PRIMITIVE_CLASS_DESC_MAP.put(char.class, JVM_CHAR); - PRIMITIVE_CLASS_NAME_MAP.put(char.class, "char"); - PRIMITIVE_CLASS_DESC_MAP.put(double.class, JVM_DOUBLE); - PRIMITIVE_CLASS_NAME_MAP.put(double.class, "double"); - PRIMITIVE_CLASS_DESC_MAP.put(float.class, JVM_FLOAT); - PRIMITIVE_CLASS_NAME_MAP.put(float.class, "float"); - PRIMITIVE_CLASS_DESC_MAP.put(int.class, JVM_INT); - PRIMITIVE_CLASS_NAME_MAP.put(int.class, "int"); - PRIMITIVE_CLASS_DESC_MAP.put(long.class, JVM_LONG); - PRIMITIVE_CLASS_NAME_MAP.put(long.class, "long"); - PRIMITIVE_CLASS_DESC_MAP.put(short.class, JVM_SHORT); - PRIMITIVE_CLASS_NAME_MAP.put(short.class, "short"); + PRIMITIVE_TABLE.put(void.class, JVM_VOID, "void"); + PRIMITIVE_TABLE.put(boolean.class, JVM_BOOLEAN, "boolean"); + PRIMITIVE_TABLE.put(byte.class, JVM_BYTE, "byte"); + PRIMITIVE_TABLE.put(char.class, JVM_CHAR, "char"); + PRIMITIVE_TABLE.put(double.class, JVM_DOUBLE, "double"); + PRIMITIVE_TABLE.put(float.class, JVM_FLOAT, "float"); + PRIMITIVE_TABLE.put(int.class, JVM_INT, "int"); + PRIMITIVE_TABLE.put(long.class, JVM_LONG, "long"); + PRIMITIVE_TABLE.put(short.class, JVM_SHORT, "short"); } /** @@ -151,7 +148,7 @@ public class ClassDescUtil { public static Class descToClass(String desc, final boolean isInitialized, final ClassLoader cl) throws UtilException { Assert.notNull(desc, "Name must not be null"); final char firstChar = desc.charAt(0); - final Class clazz = PRIMITIVE_CLASS_DESC_MAP.getKey(firstChar); + final Class clazz = PRIMITIVE_TABLE.getLeftByMiddle(firstChar); if (null != clazz) { return clazz; } @@ -188,7 +185,7 @@ public class ClassDescUtil { } if (c.isPrimitive()) { - final Character desc = PRIMITIVE_CLASS_DESC_MAP.get(c); + final Character desc = PRIMITIVE_TABLE.getMiddleByLeft(c); if (null != desc) { ret.append(desc.charValue()); } @@ -331,10 +328,10 @@ public class ClassDescUtil { sb.append('['); } - final Class clazz = PRIMITIVE_CLASS_NAME_MAP.getKey(name); + final Class clazz = PRIMITIVE_TABLE.getLeftByRight(name); if (null != clazz) { // 原始类型数组,根据name获取其描述 - sb.append(PRIMITIVE_CLASS_DESC_MAP.get(clazz).charValue()); + sb.append(PRIMITIVE_TABLE.getMiddleByLeft(clazz).charValue()); } else { // 对象数组必须转换为desc形式 // "java.lang.Object" ==> "Ljava.lang.Object;" @@ -342,7 +339,7 @@ public class ClassDescUtil { } name = sb.toString(); } else { - final Class clazz = PRIMITIVE_CLASS_NAME_MAP.getKey(name); + final Class clazz = PRIMITIVE_TABLE.getLeftByRight(name); if (null != clazz) { return clazz; } @@ -373,10 +370,10 @@ public class ClassDescUtil { sb.append('['); } - final Class clazz = PRIMITIVE_CLASS_NAME_MAP.getKey(name); + final Class clazz = PRIMITIVE_TABLE.getLeftByRight(name); if (null != clazz) { // 原始类型数组,根据name获取其描述 - sb.append(PRIMITIVE_CLASS_DESC_MAP.get(clazz).charValue()); + sb.append(PRIMITIVE_TABLE.getMiddleByLeft(clazz).charValue()); } else { // "java.lang.Object" ==> "Ljava.lang.Object;" sb.append('L').append(name.replace(CharUtil.DOT, CharUtil.SLASH)).append(';'); @@ -400,9 +397,9 @@ public class ClassDescUtil { int c = desc.lastIndexOf('[') + 1; if (desc.length() == c + 1) { final char descChar = desc.charAt(c); - final Class clazz = PRIMITIVE_CLASS_DESC_MAP.getKey(descChar); + final Class clazz = PRIMITIVE_TABLE.getLeftByMiddle(descChar); if (null != clazz) { - sb.append(PRIMITIVE_CLASS_NAME_MAP.get(clazz)); + sb.append(PRIMITIVE_TABLE.getRightByLeft(clazz)); } else { throw new UtilException("Unsupported primitive desc: {}", desc); }