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: 2024.0.2
Show newest version
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> supplier) {
        set = supplier.get();
    }

    public static  ToSet get(Supplier> 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 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);
    }

    @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> 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