shz.core.ToSet Maven / Gradle / Ivy
package shz.core;
import shz.core.function.ActionRunner;
import java.lang.reflect.Array;
import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;
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(Supplier extends Set> supplier) {
set = supplier.get();
}
public static ToSet get(Supplier extends Set> supplier) {
return new ToSet<>(supplier);
}
public static ToSet get(int initialCapacity, int idx, boolean dummy) {
return get(() -> {
if (initialCapacity <= 0) return dummy ? new LinkedHashSet<>() : new HashSet<>();
return 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) {
return get(initialCapacity, idx, false);
}
public static ToSet get(int initialCapacity) {
return get(initialCapacity, 0, false);
}
public static ToSet get() {
return get(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 extends E> 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 extends E> 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 extends E> 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 extends E> stream, boolean dummy) {
return collect(stream, dummy, 0);
}
public static Set collect(Stream extends E> stream, int extra) {
return collect(stream, false, extra);
}
/**
* 如果不使用LinkedHashSet收集,则完全可以使用原生的Collectors.toSet()
*/
public static Set collect(Stream extends E> stream) {
return collect(stream, false, 0);
}
@SafeVarargs
public static Set asSet(E... es) {
if (es == null || es.length == 0) return Collections.emptySet();
return Arrays.stream(es).collect(collector(es.length));
}
public static Set asSet(Object obj) {
if (obj == null) return Collections.emptySet();
if (obj instanceof Set) return (Set) obj;
if (obj instanceof Collection) {
Collection collections = (Collection) obj;
if (collections.isEmpty()) return Collections.emptySet();
return explicitCollect(collections.stream(), collections.size());
}
if (obj instanceof CharSequence) return (Set) asSet(obj.toString().split(","));
if (obj.getClass().isArray()) {
int len;
if ((len = Array.getLength(obj)) == 0) return Collections.emptySet();
Set result = new HashSet<>(len);
for (int i = 0; i < len; ++i) result.add((E) Array.get(obj, i));
return result;
}
return get().add(obj).build();
}
public static Set collect(ActionRunner runner, Supplier extends Set> supplier) {
Set set = supplier.get();
runner.accept(set::add);
return set;
}
public static Set collect(ActionRunner runner, boolean concurrent) {
return collect(runner, concurrent ? CopyOnWriteArraySet::new : HashSet::new);
}
public static Set collect(ActionRunner runner) {
return collect(runner, false);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy