All Downloads are FREE. Search and download functionalities are using the official Maven repository.

shz.core.ToSet Maven / Gradle / Ivy

There is a newer version: 10.3.1
Show newest version
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 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