shz.core.ToSet Maven / Gradle / Ivy
package shz.core;
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Stream;
@SuppressWarnings("unchecked")
public final class ToSet {
private final Set set;
private ToSet(int initialCapacity, int idx, boolean dummy) {
if (initialCapacity <= 0) set = dummy ? new LinkedHashSet<>() : new HashSet<>();
else set = dummy ? new LinkedHashSet<>(ToMap.reduce(initialCapacity, idx), 1.0f)
: new HashSet<>(ToMap.reduce(initialCapacity, idx), 1.0f);
}
public static ToSet get(int initialCapacity, int idx, boolean dummy) {
return new ToSet<>(initialCapacity, idx, dummy);
}
public static ToSet get(int initialCapacity, int idx) {
return new ToSet<>(initialCapacity, idx, false);
}
public static ToSet get(int initialCapacity) {
return new ToSet<>(initialCapacity, 0, false);
}
public static ToSet get() {
return new ToSet<>(0, 0, false);
}
public T build() {
return (T) set;
}
public ToSet add(Collection extends E> c) {
set.addAll(c);
return this;
}
public ToSet add(EE e) {
set.add(e);
return this;
}
public static > Collector collector(Supplier supplier) {
return Collector.of(
supplier,
Set::add,
(left, right) -> {
left.addAll(right);
return left;
},
Collector.Characteristics.UNORDERED
);
}
/**
* 大致确定元素个数时的收集器
*
* @param initialCapacity 大致确定的初始容量
* @param idx 初始容量衰减次数
* @param dummy 是否排序的
*/
public static > Collector collector(int initialCapacity, int idx, boolean dummy) {
//提供初始化容量的HashSet(若dummy为true则为LinkedHashSet)
return collector(() -> get(initialCapacity, idx, dummy).build());
}
public static Collector> collector(int initialCapacity, int idx) {
return collector(initialCapacity, idx, false);
}
public static Collector> collector(int initialCapacity) {
return collector(initialCapacity, 0, false);
}
/**
* 大致确定元素个数时的流收集
*/
public static Set explicitCollect(Stream stream, int initialCapacity, int idx, boolean dummy) {
Set set = stream.collect(collector(initialCapacity, idx, dummy));
return set.isEmpty() ? Collections.emptySet() : set;
}
public static Set explicitCollect(Stream stream, int initialCapacity) {
return explicitCollect(stream, initialCapacity, 0, false);
}
/**
* 无法确定元素个数时的收集器
*/
public static Collector> collector(boolean dummy) {
return collector(dummy ? LinkedHashSet::new : HashSet::new);
}
public static Collector> collector() {
return collector(false);
}
/**
* 无法确定元素个数时的流收集
*
* @param dummy 是否排序的
* @param extra 申请额外空间
*/
public static Set collect(Stream stream, boolean dummy, int extra) {
int size = Math.max(extra, 0);
Set set = stream.collect(collector(dummy));
if (set.isEmpty()) return size == 0 ? Collections.emptySet() : get(size, 0, dummy).build();
if (size == 0) return set;
//原来的初始容量
int oldCap = ToMap.reduce(set.size(), 0);
//申请额外空间后计算需扩容一次达到指定容量的初始容量
int newCap = ToMap.reduce(size + set.size(), 1);
//如果添加额外元素最多导致扩容一次则直接返回
// 考虑到申请额外空间不一定会真正的去执行,因此这一次的扩容留给具体执行的方法(不一定会扩容)
if (oldCap >= newCap) return set;
//下面代码基本不会执行,除非申请额外空间非常大(即需要扩容两次以上)
//初始容量避免添加额外元素时导致频繁扩容
newCap = ToMap.reduce(size + set.size(), 0);
Set result = dummy ? new LinkedHashSet<>(newCap, 1.0f) : new HashSet<>(newCap, 1.0f);
result.addAll(set);
return result;
}
public static Set collect(Stream stream, boolean dummy) {
return collect(stream, dummy, 0);
}
public static Set collect(Stream stream, int extra) {
return collect(stream, false, extra);
}
/**
* 如果不使用LinkedHashSet收集,则完全可以使用原生的Collectors.toSet()
*/
public static Set collect(Stream stream) {
return collect(stream, false, 0);
}
public static Set asSet(E... es) {
if (es == null || es.length == 0) return Collections.emptySet();
if (es.length == 1) return Collections.singleton(es[0]);
return Arrays.stream(es).collect(collector(es.length));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy