, Hash32 {
+
+ @Override
+ public long hash64(String key) {
+ byte[] bKey = md5(key);
+ return ((long) (bKey[3] & 0xFF) << 24)
+ | ((long) (bKey[2] & 0xFF) << 16)
+ | ((long) (bKey[1] & 0xFF) << 8)
+ | (bKey[0] & 0xFF);
+ }
+
+ @Override
+ public int hash32(String key) {
+ return (int) (hash64(key) & 0xffffffffL);
+ }
+
+ @Override
+ public Number hash(String key) {
+ return hash64(key);
+ }
+
+ /**
+ * 计算MD5值,使用UTF-8编码
+ *
+ * @param key 被计算的键
+ * @return MD5值
+ */
+ private static byte[] md5(String key) {
+ final MessageDigest md5;
+ try {
+ md5 = MessageDigest.getInstance("MD5");
+ } catch (NoSuchAlgorithmException e) {
+ throw new UtilException("MD5 algorithm not suooport!", e);
+ }
+ return md5.digest(StrUtil.utf8Bytes(key));
+ }
+}
diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/reflect/MethodHandleUtil.java b/hutool-core/src/main/java/cn/hutool/core/lang/reflect/MethodHandleUtil.java
index 781208744..fbfa2ded3 100755
--- a/hutool-core/src/main/java/cn/hutool/core/lang/reflect/MethodHandleUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/lang/reflect/MethodHandleUtil.java
@@ -12,6 +12,7 @@ import java.lang.reflect.Method;
/**
* 方法句柄{@link MethodHandle}封装工具类
+ * 方法句柄是一个有类型的,可以直接执行的指向底层方法、构造器、field等的引用,可以简单理解为函数指针,它是一种更加底层的查找、调整和调用方法的机制。
* 参考:
*
* - https://stackoverflow.com/questions/22614746/how-do-i-invoke-java-8-default-methods-reflectively
@@ -113,7 +114,7 @@ public class MethodHandleUtil {
}
/**
- * 执行接口或对象中的方法
+ * 执行接口或对象中的特殊方法(private、static等)
*
*
* interface Duck {
@@ -159,7 +160,7 @@ public class MethodHandleUtil {
}
/**
- * 执行接口或对象中的方法
+ * 执行接口或对象中的特殊方法(private、static等)
*
*
* interface Duck {
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 66c79de78..4584943a5 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
@@ -1,6 +1,7 @@
package cn.hutool.core.map;
import java.util.Map;
+import java.util.function.BiFunction;
/**
* 自定义键的Map,默认HashMap实现
@@ -67,6 +68,31 @@ public abstract class CustomKeyMap extends MapWrapper {
return super.replace((K) customKey(key), value);
}
+ //---------------------------------------------------------------------------- Override default methods start
+ @Override
+ public V getOrDefault(Object key, V defaultValue) {
+ return super.getOrDefault(customKey(key), defaultValue);
+ }
+
+ @Override
+ public V computeIfPresent(K key, BiFunction super K, ? super V, ? extends V> remappingFunction) {
+ //noinspection unchecked
+ return super.computeIfPresent((K) customKey(key), remappingFunction);
+ }
+
+ @Override
+ public V compute(K key, BiFunction super K, ? super V, ? extends V> remappingFunction) {
+ //noinspection unchecked
+ return super.compute((K) customKey(key), remappingFunction);
+ }
+
+ @Override
+ public V merge(K key, V value, BiFunction super V, ? super V, ? extends V> remappingFunction) {
+ //noinspection unchecked
+ return super.merge((K) customKey(key), value, remappingFunction);
+ }
+ //---------------------------------------------------------------------------- Override default methods end
+
/**
* 自定义键
*
diff --git a/hutool-core/src/main/java/cn/hutool/core/map/MapWrapper.java b/hutool-core/src/main/java/cn/hutool/core/map/MapWrapper.java
index f1e40316a..000b15ea6 100644
--- a/hutool-core/src/main/java/cn/hutool/core/map/MapWrapper.java
+++ b/hutool-core/src/main/java/cn/hutool/core/map/MapWrapper.java
@@ -16,7 +16,6 @@ import java.util.function.Function;
* @param 键类型
* @param 值类型
* @author looly
- * @author looly
* @since 4.3.3
*/
public class MapWrapper implements Map, Iterable>, Serializable, Cloneable {
@@ -179,6 +178,7 @@ public class MapWrapper implements Map, Iterable>, S
return raw.computeIfAbsent(key, mappingFunction);
}
+ // 重写默认方法的意义在于,如果被包装的Map自定义了这些默认方法,包装类就可以保持这些行为的一致性
//---------------------------------------------------------------------------- Override default methods start
@Override
public V getOrDefault(Object key, V defaultValue) {
diff --git a/hutool-core/src/main/java/cn/hutool/core/stream/CollectorUtil.java b/hutool-core/src/main/java/cn/hutool/core/stream/CollectorUtil.java
index 58b03d2ba..55e96877c 100644
--- a/hutool-core/src/main/java/cn/hutool/core/stream/CollectorUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/stream/CollectorUtil.java
@@ -1,10 +1,17 @@
package cn.hutool.core.stream;
+import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.StrUtil;
import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Map;
import java.util.StringJoiner;
+import java.util.function.BiConsumer;
+import java.util.function.BinaryOperator;
import java.util.function.Function;
+import java.util.function.Supplier;
import java.util.stream.Collector;
/**
@@ -61,4 +68,70 @@ public class CollectorUtil {
Collections.emptySet()
);
}
+
+
+ /**
+ * 提供对null值友好的groupingBy操作的{@link Collector}实现,可指定map类型
+ *
+ * @param classifier 分组依据
+ * @param mapFactory 提供的map
+ * @param downstream 下游操作
+ * @param 实体类型
+ * @param 实体中的分组依据对应类型,也是Map中key的类型
+ * @param 下游操作对应返回类型,也是Map中value的类型
+ * @param 下游操作在进行中间操作时对应类型
+ * @param 最后返回结果Map类型
+ * @return {@link Collector}
+ */
+ public static > Collector groupingBy(Function super T, ? extends K> classifier,
+ Supplier mapFactory,
+ Collector super T, A, D> downstream) {
+ Supplier downstreamSupplier = downstream.supplier();
+ BiConsumer downstreamAccumulator = downstream.accumulator();
+ BiConsumer