Browse Source

add Intern

Looly 5 years ago
parent
commit
667dbc2be7

+ 2 - 1
CHANGELOG.md

@@ -3,7 +3,7 @@
 
 
 -------------------------------------------------------------------------------------------------------------
 -------------------------------------------------------------------------------------------------------------
 
 
-# 5.4.3 (2020-09-15)
+# 5.4.3 (2020-09-16)
 
 
 ### 新特性
 ### 新特性
 * 【core   】     使用静态的of方法来new对象(pr#177@Gitee)
 * 【core   】     使用静态的of方法来new对象(pr#177@Gitee)
@@ -15,6 +15,7 @@
 * 【core   】     增加Generator
 * 【core   】     增加Generator
 * 【db     】     Column增加是否主键、保留位数等字段
 * 【db     】     Column增加是否主键、保留位数等字段
 * 【cache  】     Cache接口增加get重载(issue#1080@Github)
 * 【cache  】     Cache接口增加get重载(issue#1080@Github)
+* 【core   】     增加Interner和InternUtil(issue#I1TU1Y@Gitee)
 
 
 ### Bug修复
 ### Bug修复
 * 【core   】     修复Dict.of错误(issue#I1UUO5@Gitee)
 * 【core   】     修复Dict.of错误(issue#I1UUO5@Gitee)

+ 40 - 0
hutool-core/src/main/java/cn/hutool/core/lang/intern/InternUtil.java

@@ -0,0 +1,40 @@
+package cn.hutool.core.lang.intern;
+
+/**
+ * 规范化对象生成工具
+ *
+ * @author looly
+ * @since 5.4.3
+ */
+public class InternUtil {
+
+	/**
+	 * 创建WeakHshMap实现的字符串规范化器
+	 *
+	 * @param <T> 规范对象的类型
+	 * @return {@link Interner}
+	 */
+	public static <T> Interner<T> createWeakInterner(){
+		return new WeakInterner<>();
+	}
+
+	/**
+	 * 创建JDK默认实现的字符串规范化器
+	 *
+	 * @return {@link Interner}
+	 * @see String#intern()
+	 */
+	public static Interner<String> createJdkInterner(){
+		return new JdkStringInterner();
+	}
+
+	/**
+	 * 创建字符串规范化器
+	 *
+	 * @param isWeak 是否创建使用WeakHashMap实现的Interner
+	 * @return {@link Interner}
+	 */
+	public static Interner<String> createStringInterner(boolean isWeak){
+		return isWeak ? createWeakInterner() : createJdkInterner();
+	}
+}

+ 21 - 0
hutool-core/src/main/java/cn/hutool/core/lang/intern/Interner.java

@@ -0,0 +1,21 @@
+package cn.hutool.core.lang.intern;
+
+/**
+ * 规范化表示形式封装<br>
+ * 所谓规范化,即当两个对象equals时,规范化的对象则可以实现==<br>
+ * 此包中的相关封装类似于 {@link String#intern()}
+ *
+ * @param <T> 规范化的对象类型
+ * @author looly
+ * @since 5.4.3
+ */
+public interface Interner<T> {
+
+	/**
+	 * 返回指定对象对应的规范化对象,sample对象可能有多个,但是这些对象如果都equals,则返回的是同一个对象
+	 *
+	 * @param sample 对象
+	 * @return 样例对象
+	 */
+	T intern(T sample);
+}

+ 17 - 0
hutool-core/src/main/java/cn/hutool/core/lang/intern/JdkStringInterner.java

@@ -0,0 +1,17 @@
+package cn.hutool.core.lang.intern;
+
+/**
+ * JDK中默认的字符串规范化实现
+ *
+ * @author looly
+ * @since 5.4.3
+ */
+public class JdkStringInterner implements Interner<String>{
+	@Override
+	public String intern(String sample) {
+		if(null == sample){
+			return null;
+		}
+		return sample.intern();
+	}
+}

+ 22 - 0
hutool-core/src/main/java/cn/hutool/core/lang/intern/WeakInterner.java

@@ -0,0 +1,22 @@
+package cn.hutool.core.lang.intern;
+
+import cn.hutool.core.lang.SimpleCache;
+
+/**
+ * 使用WeakHashMap(线程安全)存储对象的规范化对象,注意此对象需单例使用!<br>
+ *
+ * @author looly
+ * @since 5.4.3
+ */
+public class WeakInterner<T> implements Interner<T>{
+
+	private final SimpleCache<T, T> cache = new SimpleCache<>();
+
+	@Override
+	public T intern(T sample) {
+		if(null == sample){
+			return null;
+		}
+		return cache.get(sample, ()->sample);
+	}
+}

+ 8 - 0
hutool-core/src/main/java/cn/hutool/core/lang/intern/package-info.java

@@ -0,0 +1,8 @@
+/**
+ * 规范化表示形式封装<br>
+ * 所谓规范化,即当两个对象equals时,规范化的对象则可以实现==<br>
+ * 此包中的相关封装类似于 String#intern()
+ *
+ * @author looly
+ */
+package cn.hutool.core.lang.intern;

+ 24 - 0
hutool-core/src/test/java/cn/hutool/core/lang/intern/InternUtilTest.java

@@ -0,0 +1,24 @@
+package cn.hutool.core.lang.intern;
+
+import cn.hutool.core.util.RandomUtil;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class InternUtilTest {
+
+	/**
+	 * 检查规范字符串是否相同
+	 */
+	@SuppressWarnings("StringOperationCanBeSimplified")
+	@Test
+	public void weakTest(){
+		final Interner<String> interner = InternUtil.createWeakInterner();
+		String a1 = RandomUtil.randomString(RandomUtil.randomInt(100));
+		String a2 = new String(a1);
+
+		Assert.assertNotSame(a1, a2);
+
+		Assert.assertSame(interner.intern(a1), interner.intern(a2));
+	}
+
+}