shz.ToMap Maven / Gradle / Ivy
package shz;
import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Stream;
@SuppressWarnings("unchecked")
public final class ToMap {
private final Map map;
private ToMap(int initialCapacity, int idx, boolean dummy) {
map = dummy ? new LinkedHashMap<>(reduce(initialCapacity, idx), 1.0f)
: new HashMap<>(reduce(initialCapacity, idx), 1.0f);
}
private static final int MAX = 1 << 30;
static int reduce(int cap, int idx) {
if (idx <= 0 || cap == 1) return (int) Math.ceil(cap / 0.75f);
int n = cap - 1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
n = n >= MAX ? MAX : n + 1;
while (idx-- > 0) {
if (n < 2) break;
n >>>= 1;
}
return (int) Math.ceil(n / 0.75f);
}
public static ToMap get(int initialCapacity, int idx, boolean dummy) {
return new ToMap<>(initialCapacity, idx, dummy);
}
public static ToMap get(int initialCapacity, int idx) {
return new ToMap<>(initialCapacity, idx, false);
}
public static ToMap get(int initialCapacity) {
return new ToMap<>(initialCapacity, 0, false);
}
public T build() {
return (T) map;
}
public ToMap put(Map extends K, ? extends V> m) {
map.putAll(m);
return this;
}
public ToMap put(KK k, VV v) {
map.put(k, v);
return this;
}
public static > Collector collector(
Function super E, ? extends K> keyMapper, Function super E, ? extends V> valueMapper,
BinaryOperator mergeFunction, Supplier mapSupplier) {
return Collector.of(
mapSupplier,
//替换默认merge方法
(map, element) -> merge(keyMapper.apply(element), valueMapper.apply(element), map, mergeFunction),
(m1, m2) -> {
for (Map.Entry e : m2.entrySet()) merge(e.getKey(), e.getValue(), m1, mergeFunction);
return m1;
}
);
}
private static > void merge(K key, V value, M map, BinaryOperator mergeFunction) {
V oldValue;
if ((oldValue = map.get(key)) == null) {
//原key的值为null则使用新值(包括null)
map.put(key, value);
return;
}
//原key的值不为null则使用具体的取值策略
map.put(key, mergeFunction.apply(oldValue, value));
}
/**
* 大致确定元素个数时的收集器
*
* @param keyMapper 键映射器
* @param valueMapper 值映射器
* @param initialCapacity 大致确定的初始容量
* @param idx 初始容量衰减次数
* @param dummy 是否排序的
*/
public static Collector> collector(
Function super E, ? extends K> keyMapper, Function super E, ? extends V> valueMapper, int initialCapacity, int idx, boolean dummy) {
return collector(keyMapper, valueMapper,
//原key的值不为null时的取值策略,默认策略为抛出异常,这里选择若新值不为null则替换原来的值
(oldValue, newValue) -> newValue == null ? oldValue : newValue,
//提供初始化容量的HashMap(若dummy为true则为LinkedHashMap)
() -> get(initialCapacity, idx, dummy).build()
);
}
public static Collector> collector(
Function super E, ? extends K> keyMapper, Function super E, ? extends V> valueMapper, int initialCapacity, int idx) {
return collector(keyMapper, valueMapper, initialCapacity, idx, false);
}
public static Collector> collector(
Function super E, ? extends K> keyMapper, Function super E, ? extends V> valueMapper, int initialCapacity) {
return collector(keyMapper, valueMapper, initialCapacity, 0, false);
}
/**
* 大致确定元素个数时的流收集
*/
public static Map explicitCollect(
Stream stream, Function super E, ? extends K> keyMapper, Function super E, ? extends V> valueMapper, int initialCapacity, int idx, boolean dummy) {
Map map = stream.collect(collector(keyMapper, valueMapper, initialCapacity, idx, dummy));
return map.isEmpty() ? Collections.emptyMap() : map;
}
public static Map explicitCollect(
Stream stream, Function super E, ? extends K> keyMapper, Function super E, ? extends V> valueMapper, int initialCapacity) {
return explicitCollect(stream, keyMapper, valueMapper, initialCapacity, 0, false);
}
/**
* 无法确定元素个数时的收集器
*/
public static Collector> collector(Function super E, ? extends K> keyMapper, Function super E, ? extends V> valueMapper, boolean dummy) {
return collector(keyMapper, valueMapper, (t, u) -> u == null ? t : u, dummy ? LinkedHashMap::new : HashMap::new);
}
public static Collector> collector(Function super E, ? extends K> keyMapper, Function super E, ? extends V> valueMapper) {
return collector(keyMapper, valueMapper, false);
}
/**
* 无法确定元素个数时的流收集
*
* @param extra 申请额外空间
*/
public static Map collect(Stream stream, Function super E, ? extends K> keyMapper, Function super E, ? extends V> valueMapper, boolean dummy, int extra) {
int size = Math.max(extra, 0);
Map map = stream.collect(collector(keyMapper, valueMapper, dummy));
if (map.isEmpty()) return size == 0 ? Collections.emptyMap() : get(size, 0, dummy).build();
if (size == 0) return map;
//原来的初始容量
int oldCap = reduce(map.size(), 0);
//申请额外空间后计算需扩容一次达到指定容量的初始容量
int newCap = reduce(size + map.size(), 1);
//如果添加额外元素最多导致扩容一次则直接返回
// 考虑到申请额外空间不一定会真正的去执行,因此这一次的扩容留给具体执行的方法(不一定会扩容)
if (oldCap >= newCap) return map;
//下面代码基本不会执行,除非申请额外空间非常大(即需要扩容两次以上)
//初始容量避免添加额外元素时导致频繁扩容
newCap = reduce(size + map.size(), 0);
Map result = dummy ? new LinkedHashMap<>(newCap, 1.0f) : new HashMap<>(newCap, 1.0f);
result.putAll(map);
return result;
}
public static Map collect(Stream stream, Function super E, ? extends K> keyMapper, Function super E, ? extends V> valueMapper, boolean dummy) {
return collect(stream, keyMapper, valueMapper, dummy, 0);
}
public static Map collect(Stream stream, Function super E, ? extends K> keyMapper, Function super E, ? extends V> valueMapper, int extra) {
return collect(stream, keyMapper, valueMapper, false, extra);
}
/**
* 如果流中具有重复的key又不想抛异常则使用该方法,否则使用对应的Collectors.toMap()即可
*/
public static Map collect(Stream stream, Function super E, ? extends K> keyMapper, Function super E, ? extends V> valueMapper) {
return collect(stream, keyMapper, valueMapper, false, 0);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy