Fs.java
package space.sunqian.common;
import space.sunqian.annotations.Immutable;
import space.sunqian.annotations.Nonnull;
import space.sunqian.annotations.Nullable;
import space.sunqian.annotations.RetainedParam;
import space.sunqian.common.base.exception.AwaitingException;
import space.sunqian.common.base.exception.UnknownArrayTypeException;
import space.sunqian.common.base.function.callable.BooleanCallable;
import space.sunqian.common.base.function.callable.VoidCallable;
import space.sunqian.common.base.option.Option;
import space.sunqian.common.base.process.ProcessKit;
import space.sunqian.common.base.thread.ThreadKit;
import space.sunqian.common.base.value.Ret;
import space.sunqian.common.collect.ArrayKit;
import space.sunqian.common.collect.ListKit;
import space.sunqian.common.collect.MapKit;
import space.sunqian.common.collect.SetKit;
import space.sunqian.common.collect.StreamKit;
import space.sunqian.common.io.IORuntimeException;
import space.sunqian.common.object.convert.ConvertOption;
import space.sunqian.common.object.convert.DataMapper;
import space.sunqian.common.object.convert.ObjectConvertException;
import space.sunqian.common.object.convert.ObjectConverter;
import space.sunqian.common.object.convert.UnsupportedObjectConvertException;
import space.sunqian.common.object.data.ObjectSchema;
import space.sunqian.common.reflect.TypeRef;
import java.lang.reflect.Type;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.RandomAccess;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;
/**
* The core utility class of this library, provides support methods for {@link Object}, such as {@code equals} and
* {@code hashCode}. And many methods to improve language convenience, such as {@code nonnull}, {@code uncheck}. And
* shortcuts to other commonly used methods in this lib, such as {@link #list(Object[])},
* {@link #copyProperties(Object, Object, Option[])}, {@link #convert(Object, Class, Option[])}, etc.
*
* @author sunqian
*/
public class Fs {
/**
* Name of this lib.
*/
public static final @Nonnull String LIB_NAME = "fs";
/**
* Version of this lib.
*/
public static final @Nonnull String LIB_VERSION = "0.0.0";
/**
* String value for {@code null}.
*/
public static final @Nonnull String NULL_STRING = Objects.toString(null);
/**
* Casts and returns the given object as the specified type {@code T}. This method is equivalent to:
* <pre>{@code
* return (T) obj;
* }</pre>
*
* @param obj the given object
* @param <T> the specified type
* @return the given object as the specified type {@code T}
*/
@SuppressWarnings("noinspection unchecked")
public static <T> T as(@Nullable Object obj) {
return (T) obj;
}
/**
* Directly returns the given object itself. The given object is annotated by {@link Nullable}, but the return value
* is annotated by {@link Nonnull}. This method is used to suppress some IDE or compilation warnings.
*
* @param obj the given object
* @param <T> the type of the given object
* @return the given object itself
*/
@SuppressWarnings("ConstantConditions")
public static <T> @Nonnull T asNonnull(@Nullable T obj) {
return obj;
}
/**
* Returns the default value if the given object is {@code null}, or the given object itself if it is not
* {@code null}. This method is equivalent to:
* <pre>{@code
* return obj == null ? defaultValue : obj;
* }</pre>
* <p>
* Note this method does not guarantee that the returned value must be {@code nonnull}.
*
* @param obj the given object
* @param defaultValue the default value
* @param <T> the type of the returned value
* @return the default value if the given object is {@code null}, or the given object itself if it is not
* {@code null}
*/
public static <T> T nonnull(@Nullable T obj, T defaultValue) {
return obj == null ? defaultValue : obj;
}
/**
* Returns the value computed from the specified supplier if the given object is {@code null}, or the given object
* itself if it is not {@code null}. This method is equivalent to:
* <pre>{@code
* return obj == null ? supplier.get() : obj;
* }</pre>
* <p>
* Note this method does not guarantee that the returned value must be {@code nonnull}.
*
* @param obj the given object
* @param supplier the specified supplier
* @param <T> the type of the returned value
* @return the value computed from the specified supplier if the given object is {@code null}, or the given object
* itself if it is not {@code null}
*/
public static <T> T nonnull(@Nullable T obj, Supplier<? extends T> supplier) {
return obj == null ? supplier.get() : obj;
}
/**
* Runs the given action and wraps any exception into an unchecked exception, the unchecked exception is generated
* by the given unchecked exception generator. The logic as follows:
* <pre>{@code
* try {
* action.call();
* } catch (Exception e) {
* throw unchecked.apply(e);
* }
* }</pre>
*
* @param action the given action
* @param unchecked the given unchecked exception generator
*/
public static void uncheck(
@Nonnull VoidCallable action,
@Nonnull Function<? super @Nonnull Exception, ? extends @Nonnull RuntimeException> unchecked
) {
try {
action.call();
} catch (Exception e) {
throw unchecked.apply(e);
}
}
/**
* Runs the given action and wraps any exception into an unchecked exception, the unchecked exception is generated
* by the given unchecked exception generator. The logic as follows:
* <pre>{@code
* try {
* return action.call();
* } catch (Exception e) {
* throw unchecked.apply(e);
* }
* }</pre>
*
* @param action the given action
* @param unchecked the given unchecked exception generator
* @param <T> the type of the result
* @return the result of the given action
*/
public static <T> T uncheck(
@Nonnull Callable<T> action,
@Nonnull Function<? super @Nonnull Exception, ? extends @Nonnull RuntimeException> unchecked
) {
try {
return action.call();
} catch (Exception e) {
throw unchecked.apply(e);
}
}
/**
* Runs the given action and ignores any exception thrown by the action. The logic as follows:
* <pre>{@code
* try {
* action.call();
* } catch (Exception ignored) {
* }
* }</pre>
*
* @param action the given action
*/
public static void uncheck(@Nonnull VoidCallable action) {
try {
action.call();
} catch (Exception ignored) {
}
}
/**
* Calls the given action and returns the result. If any exception is thrown, returns the default value. The logic
* as follows:
* <pre>{@code
* try {
* return action.call();
* } catch (Exception e) {
* return defaultValue;
* }
* }</pre>
*
* @param action the given action
* @param defaultValue the default value
* @param <T> the type of the result
* @return the result of the given action, or the default value if any exception is thrown
*/
public static <T> T call(@Nonnull Callable<T> action, T defaultValue) {
try {
return action.call();
} catch (Exception e) {
return defaultValue;
}
}
/**
* Calls the given action and returns the result wrapped by {@link Ret}. The logic as follows:
* <pre>{@code
* try {
* T ret = action.call();
* return Ret.of(ret);
* } catch (Throwable e) {
* return Ret.of(e);
* }
* }</pre>
*
* @param action the given action
* @param <T> the type of the result
* @return the result of the given action wrapped by {@link Ret}
*/
public static <T> Ret<T> call(@Nonnull Callable<T> action) {
try {
T ret = action.call();
return Ret.of(ret);
} catch (Throwable e) {
return Ret.of(e);
}
}
/**
* Executes the given task until it returns {@code true} or throws an exception. The original exception will be
* wrapped by {@link AwaitingException} then thrown, using {@link AwaitingException#getCause()} can get the original
* exception. The logic of this method is as follows:
* <pre>{@code
* try {
* while (true) {
* if (task.call()) {
* return;
* }
* }
* } catch (Exception e) {
* throw new AwaitingException(e);
* }
* }</pre>
* <p>
* Note this method may cause high CPU usage. When the task determines to return {@code false}, consider adding some
* measures (such as sleep the current thread in a very short time) to avoid it.
*
* @param task the given task to be executed
* @throws AwaitingException if an error occurs while awaiting
*/
public static void until(@Nonnull BooleanCallable task) throws AwaitingException {
try {
while (true) {
if (task.call()) {
return;
}
}
} catch (Exception e) {
throw new AwaitingException(e);
}
}
/**
* Returns whether the given objects are equal. If the given objects are arrays, uses {@code Arrays.equals} or
* {@link Arrays#deepEquals(Object[], Object[])} if necessary.
* <p>
* This method is equivalent to ({@link #equalsWith(Object, Object, boolean, boolean)}):
* {@code equalsWith(a, b, true, true)}.
*
* @param a the given object a
* @param b the given object b
* @return whether the given objects are equal
*/
public static boolean equals(@Nullable Object a, @Nullable Object b) {
return equalsWith(a, b, true, true);
}
/**
* Returns whether the given objects are equal each other by {@link #equals(Object, Object)}.
*
* @param objects the given objects
* @return whether the given objects are equal
*/
public static boolean equalsAll(@Nullable Object @Nonnull ... objects) {
for (int i = 0; i < objects.length - 1; i++) {
if (!equals(objects[i], objects[i + 1])) {
return false;
}
}
return true;
}
/**
* Returns whether the given objects are equal. This method follows the following logic:
* <ul>
* <li>
* If {@code a == b}, returns {@code true};
* </li>
* <li>
* If the {@code arrayEquals} is {@code true}:
* <ul>
* <li>
* If the {@code deep} is {@code true}, uses {@link Arrays#deepEquals(Object[], Object[])} for
* them. Otherwise, uses {@code Arrays.equals}.
* </li>
* </ul>
* </li>
* <li>
* Returns {@link Objects#equals(Object, Object)} otherwise.
* </li>
* </ul>
*
* @param a the given object a
* @param b the given object b
* @param arrayEquals the arrayEquals option
* @param deep the deep option
* @return whether the given objects are equal
*/
public static boolean equalsWith(@Nullable Object a, @Nullable Object b, boolean arrayEquals, boolean deep) {
if (a == b) {
return true;
}
if (a == null || b == null) {
return false;
}
if (!arrayEquals) {
return Objects.equals(a, b);
}
Class<?> typeA = a.getClass();
Class<?> typeB = b.getClass();
if (typeA.isArray() && Objects.equals(typeA, typeB)) {
return equalsArray(a, b, deep);
}
return Objects.equals(a, b);
}
private static boolean equalsArray(@Nonnull Object a, @Nonnull Object b, boolean deep) {
if (a instanceof Object[]) {
return deep ? Arrays.deepEquals((Object[]) a, (Object[]) b) : Arrays.equals((Object[]) a, (Object[]) b);
} else if (a instanceof boolean[]) {
return Arrays.equals((boolean[]) a, (boolean[]) b);
} else if (a instanceof byte[]) {
return Arrays.equals((byte[]) a, (byte[]) b);
} else if (a instanceof short[]) {
return Arrays.equals((short[]) a, (short[]) b);
} else if (a instanceof char[]) {
return Arrays.equals((char[]) a, (char[]) b);
} else if (a instanceof int[]) {
return Arrays.equals((int[]) a, (int[]) b);
} else if (a instanceof long[]) {
return Arrays.equals((long[]) a, (long[]) b);
} else if (a instanceof float[]) {
return Arrays.equals((float[]) a, (float[]) b);
} else if (a instanceof double[]) {
return Arrays.equals((double[]) a, (double[]) b);
}
throw new UnknownArrayTypeException(a.getClass());
}
/**
* Returns the hashcode of the given object. If the given object is array, uses {@code Arrays.hashCode} or
* {@link Arrays#deepHashCode(Object[])} if necessary.
* <p>
* This method is equivalent to ({@link #hashWith(Object, boolean, boolean)}): {@code hashWith(obj, true, true)}.
*
* @param obj the given object
* @return the hashcode of the given object
*/
public static int hashCode(@Nullable Object obj) {
return hashWith(obj, true, true);
}
/**
* Returns the hashcode of the given objects via {@link Arrays#deepHashCode(Object[])}.
*
* @param objs the given objects
* @return the hashcode of the given objects via {@link Arrays#deepHashCode(Object[])}
*/
public static int hashAll(@Nullable Object @Nonnull ... objs) {
return Arrays.deepHashCode(objs);
}
/**
* Returns the hashcode of the given object. This method follows the following logic:
* <ul>
* <li>
* If the given object is not an array, returns {@link Objects#hashCode(Object)}.
* </li>
* <li>
* If the {@code arrayHash} is {@code true}:
* <ul>
* <li>
* If the {@code deep} is {@code true}, uses {@link Arrays#deepHashCode(Object[])} for them.
* Otherwise, uses {@code Arrays.hashCode}.
* </li>
* </ul>
* </li>
* <li>
* Returns {@link Objects#hashCode(Object)} otherwise.
* </li>
* </ul>
*
* @param obj the given object
* @param arrayHash the arrayHash option
* @param deep the deep option
* @return the hashcode of the given object
*/
public static int hashWith(@Nullable Object obj, boolean arrayHash, boolean deep) {
if (obj == null || !arrayHash) {
return Objects.hashCode(obj);
}
Class<?> cls = obj.getClass();
if (cls.isArray()) {
return hashArray(obj, deep);
}
return obj.hashCode();
}
private static int hashArray(@Nonnull Object obj, boolean deep) {
if (obj instanceof Object[]) {
return deep ? Arrays.deepHashCode((Object[]) obj) : Arrays.hashCode((Object[]) obj);
}
if (obj instanceof boolean[]) {
return Arrays.hashCode((boolean[]) obj);
}
if (obj instanceof byte[]) {
return Arrays.hashCode((byte[]) obj);
}
if (obj instanceof short[]) {
return Arrays.hashCode((short[]) obj);
}
if (obj instanceof char[]) {
return Arrays.hashCode((char[]) obj);
}
if (obj instanceof int[]) {
return Arrays.hashCode((int[]) obj);
}
if (obj instanceof long[]) {
return Arrays.hashCode((long[]) obj);
}
if (obj instanceof float[]) {
return Arrays.hashCode((float[]) obj);
}
if (obj instanceof double[]) {
return Arrays.hashCode((double[]) obj);
}
throw new UnknownArrayTypeException(obj.getClass());
}
/**
* Returns the identity hashcode of the given object, this method is equivalent to
* {@link System#identityHashCode(Object)}.
*
* @param obj the given object
* @return the identity hashcode of the given object
*/
public static int hashId(@Nullable Object obj) {
return System.identityHashCode(obj);
}
//---------------- Copy Properties Begin ----------------//
/**
* Copy properties from the given source object to the given destination object. The object can be a {@link Map} or
* a non-map object which can be parsed to {@link ObjectSchema}.
* <p>
* The options parameter can be empty, in which case the default behavior will be used, or built-in options in
* {@link ConvertOption} or other custom options for custom implementations.
* <p>
* This method is a shortcut to the {@link DataMapper#copyProperties(Object, Object, Option[])}.
*
* @param src the given source object
* @param dst the given destination object
* @param options the options for copying properties
* @throws ObjectConvertException if an error occurs during copying properties
* @see DataMapper
*/
public static void copyProperties(
@Nonnull Object src, @Nonnull Object dst, @Nonnull Option<?, ?> @Nonnull ... options
) throws ObjectConvertException {
DataMapper.defaultMapper().copyProperties(src, dst, options);
}
/**
* Copy properties from the given source object to the given destination object. The object can be a {@link Map} or
* a non-map object which can be parsed to {@link ObjectSchema}.
* <p>
* The options parameter can be empty, in which case the default behavior will be used, or built-in options in
* {@link ConvertOption} or other custom options for custom implementations.
* <p>
* This method is a shortcut to the {@link DataMapper#copyProperties(Object, Object, ObjectConverter, Option[])}.
*
* @param src the given source object
* @param dst the given destination object
* @param converter the converter for converting values of the properties if needed
* @param options the options for copying properties
* @throws ObjectConvertException if an error occurs during copying properties
* @see DataMapper
*/
public static void copyProperties(
@Nonnull Object src,
@Nonnull Object dst,
@Nonnull ObjectConverter converter,
@Nonnull Option<?, ?> @Nonnull ... options
) throws ObjectConvertException {
DataMapper.defaultMapper().copyProperties(src, dst, converter, options);
}
/**
* Copy properties from the given source object to the given destination object. The object can be a {@link Map} or
* a non-map object which can be parsed to {@link ObjectSchema}.
* <p>
* The options parameter can be empty, in which case the default behavior will be used, or built-in options in
* {@link ConvertOption} or other custom options for custom implementations.
* <p>
* This method is a shortcut to the {@link DataMapper#copyProperties(Object, Type, Object, Type, Option[])}.
*
* @param src the given source object
* @param srcType specifies the type of the given source object
* @param dst the given destination object
* @param dstType specifies the type of the given destination object
* @param options the options for copying properties
* @throws ObjectConvertException if an error occurs during copying properties
* @see DataMapper
*/
public static void copyProperties(
@Nonnull Object src,
@Nonnull Type srcType,
@Nonnull Object dst,
@Nonnull Type dstType,
@Nonnull Option<?, ?> @Nonnull ... options
) throws ObjectConvertException {
DataMapper.defaultMapper().copyProperties(
src,
srcType,
dst,
dstType,
options
);
}
/**
* Copy properties from the given source object to the given destination object. The object can be a {@link Map} or
* a non-map object which can be parsed to {@link ObjectSchema}.
* <p>
* The options parameter can be empty, in which case the default behavior will be used, or built-in options in
* {@link ConvertOption} or other custom options for custom implementations.
* <p>
* This method is a shortcut to the
* {@link DataMapper#copyProperties(Object, Type, Object, Type, ObjectConverter, Option[])}.
*
* @param src the given source object
* @param srcType specifies the type of the given source object
* @param dst the given destination object
* @param dstType specifies the type of the given destination object
* @param converter the converter for converting values of the properties if needed
* @param options the options for copying properties
* @throws ObjectConvertException if an error occurs during copying properties
* @see DataMapper
*/
public static void copyProperties(
@Nonnull Object src,
@Nonnull Type srcType,
@Nonnull Object dst,
@Nonnull Type dstType,
@Nonnull ObjectConverter converter,
@Nonnull Option<?, ?> @Nonnull ... options
) throws ObjectConvertException {
DataMapper.defaultMapper().copyProperties(
src,
srcType,
dst,
dstType,
converter,
options
);
}
//---------------- Copy Properties End ----------------//
//---------------- Object Conversion Begin ----------------//
/**
* Converts the given source object from the specified type to the target type.
* <p>
* The options parameter can be empty, in which case the default behavior will be used, or built-in options in
* {@link ConvertOption} or other custom options for custom implementations.
* <p>
* This method is a shortcut to the {@link ObjectConverter#convert(Object, Class, Option[])}.
*
* @param src the given source object
* @param target the specified type of the target object
* @param options the other conversion options
* @param <T> the target type
* @return the converted object, {@code null} is permitted
* @throws UnsupportedObjectConvertException if the conversion from the specified type to the target type is not
* supported
* @throws ObjectConvertException if the conversion failed
* @see ObjectConverter
*/
public static <T> T convert(
@Nullable Object src,
@Nonnull Class<? extends T> target,
@Nonnull Option<?, ?> @Nonnull ... options
) throws UnsupportedObjectConvertException, ObjectConvertException {
return ObjectConverter.defaultConverter().convert(src, target, options);
}
/**
* Converts the given source object from the specified type to the target type.
* <p>
* The options parameter can be empty, in which case the default behavior will be used, or built-in options in
* {@link ConvertOption} or other custom options for custom implementations.
* <p>
* This method is a shortcut to the {@link ObjectConverter#convert(Object, TypeRef, Option[])}.
*
* @param src the given source object
* @param target the specified type ref of the target object
* @param options the other conversion options
* @param <T> the target type
* @return the converted object, {@code null} is permitted
* @throws UnsupportedObjectConvertException if the conversion from the specified type to the target type is not
* supported
* @throws ObjectConvertException if the conversion failed
* @see ObjectConverter
*/
public static <T> T convert(
@Nullable Object src,
@Nonnull TypeRef<? extends T> target,
@Nonnull Option<?, ?> @Nonnull ... options
) throws UnsupportedObjectConvertException, ObjectConvertException {
return ObjectConverter.defaultConverter().convert(src, target, options);
}
/**
* Converts the given source object from the specified type to the target type.
* <p>
* The options parameter can be empty, in which case the default behavior will be used, or built-in options in
* {@link ConvertOption} or other custom options for custom implementations.
* <p>
* This method is a shortcut to the {@link ObjectConverter#convert(Object, Type, Class, Option[])}.
*
* @param src the given source object
* @param srcType the specified type of the given source object
* @param target the specified type of the target object
* @param options the other conversion options
* @param <T> the target type
* @return the converted object, {@code null} is permitted
* @throws UnsupportedObjectConvertException if the conversion from the specified type to the target type is not
* supported
* @throws ObjectConvertException if the conversion failed
* @see ObjectConverter
*/
public static <T> T convert(
@Nullable Object src,
@Nonnull Type srcType,
@Nonnull Class<? extends T> target,
@Nonnull Option<?, ?> @Nonnull ... options
) throws UnsupportedObjectConvertException, ObjectConvertException {
return ObjectConverter.defaultConverter().convert(src, srcType, target, options);
}
/**
* Converts the given source object from the specified type to the target type.
* <p>
* The options parameter can be empty, in which case the default behavior will be used, or built-in options in
* {@link ConvertOption} or other custom options for custom implementations.
* <p>
* This method is a shortcut to the {@link ObjectConverter#convert(Object, Type, TypeRef, Option[])}.
*
* @param src the given source object
* @param srcType the specified type of the given source object
* @param target the specified type ref of the target object
* @param options the other conversion options
* @param <T> the target type
* @return the converted object, {@code null} is permitted
* @throws UnsupportedObjectConvertException if the conversion from the specified type to the target type is not
* supported
* @throws ObjectConvertException if the conversion failed
* @see ObjectConverter
*/
public static <T> T convert(
@Nullable Object src,
@Nonnull Type srcType,
@Nonnull TypeRef<? extends T> target,
@Nonnull Option<?, ?> @Nonnull ... options
) throws UnsupportedObjectConvertException, ObjectConvertException {
return ObjectConverter.defaultConverter().convert(src, srcType, target, options);
}
//---------------- Object Conversion End ----------------//
//---------------- Collection Begin ----------------//
/**
* Directly returns the given variable arguments as an array.
* <p>
* This method is a shortcut to the {@link ArrayKit#array(Object[])}.
*
* @param elements the given variable arguments
* @param <T> the component type
* @return the given variable arguments as an array
* @see ArrayKit
*/
@SafeVarargs
public static <T> T @Nonnull [] array(T @Nonnull @RetainedParam ... elements) {
return ArrayKit.array(elements);
}
/**
* Returns an immutable list backed by the given array. The returned list is immutable but the backing array is not,
* changes to the backing array "write through" to the returned list. The returned list is serializable and
* implements {@link RandomAccess}.
* <p>
* This method is a shortcut to the {@link ListKit#list(Object[])}.
*
* @param array the given array
* @param <T> the component type
* @return an immutable list backed by the given array
* @see ListKit
*/
@SafeVarargs
public static <T> @Nonnull @Immutable List<T> list(T @Nonnull @RetainedParam ... array) {
return ListKit.list(array);
}
/**
* Returns a new {@link ArrayList} initialing with the given array.
* <p>
* This method is a shortcut to the {@link ListKit#arrayList(Object[])}.
*
* @param array the given array
* @param <T> the component type
* @return a new {@link ArrayList} initialing with the given array
* @see ListKit
*/
@SafeVarargs
public static <T> @Nonnull ArrayList<T> arrayList(T @Nonnull ... array) {
return ListKit.arrayList(array);
}
/**
* Returns a new {@link LinkedList} initialing with the given array.
* <p>
* This method is a shortcut to the {@link ListKit#linkedList(Object[])}.
*
* @param array the given array
* @param <T> the component type
* @return a new {@link LinkedList} initialing with the given array
* @see ListKit
*/
@SafeVarargs
public static <T> @Nonnull LinkedList<T> linkedList(T @Nonnull ... array) {
return ListKit.linkedList(array);
}
/**
* Returns a new immutable set of which content is added from the given array. The content of the set is added in
* array order, and the duplicate elements will be ignored. The behavior of this method is equivalent to:
* <pre>{@code
* return Collections.unmodifiableSet(linkedHashSet(array));
* }</pre>
* <p>
* This method is a shortcut to the {@link SetKit#set(Object[])}.
*
* @param array the given array
* @param <T> the component type
* @return a new immutable set of which content is added from the given array
* @see SetKit
*/
@SafeVarargs
public static <T> @Nonnull @Immutable Set<T> set(T @Nonnull ... array) {
return SetKit.set(array);
}
/**
* Returns a new {@link HashSet} initialing with the given array.
* <p>
* This method is a shortcut to the {@link SetKit#hashSet(Object[])}.
*
* @param array the given array
* @param <T> the component type
* @return a new {@link HashSet} initialing with the given array
* @see SetKit
*/
@SafeVarargs
public static <T> @Nonnull HashSet<T> hashSet(T @Nonnull ... array) {
return SetKit.hashSet(array);
}
/**
* Returns a new {@link LinkedHashSet} initialing with the given array.
* <p>
* This method is a shortcut to the {@link SetKit#linkedHashSet(Object[])}.
*
* @param array the given array
* @param <T> the component type
* @return a new {@link LinkedHashSet} initialing with the given array
* @see SetKit
*/
@SafeVarargs
public static <T> @Nonnull LinkedHashSet<T> linkedHashSet(T @Nonnull ... array) {
return SetKit.linkedHashSet(array);
}
/**
* Returns a new immutable map of which content is added from the given array.
* <p>
* Every two elements of the array form a key-value pair, that means, the {@code array[0]} and {@code array[1]} will
* be the first key-value pair, the {@code array[2]} and {@code array[3]} will be the second key-value pair, and so
* on. If the length of the array is odd and the last key cannot match the value, then the last pair will be the
* key-{@code null} pair to put.
* <p>
* The behavior of this method is equivalent to:
* <pre>{@code
* return Collections.unmodifiableMap(linkedHashMap(array));
* }</pre>
* <p>
* This method is a shortcut to the {@link MapKit#map(Object[])}.
*
* @param array the given array
* @param <K> the key type
* @param <V> the value type
* @return a new {@link HashMap} initialing with the given array
* @see MapKit
*/
public static <K, V> @Nonnull @Immutable Map<K, V> map(Object @Nonnull ... array) {
return MapKit.map(array);
}
/**
* Returns a new {@link HashMap} initialing with the given array.
* <p>
* Every two elements of the array form a key-value pair, that means, the {@code array[0]} and {@code array[1]} will
* be the first key-value pair, the {@code array[2]} and {@code array[3]} will be the second key-value pair, and so
* on. If the length of the array is odd and the last key cannot match the value, then the last pair will be the
* key-{@code null} pair to put.
* <p>
* This method is a shortcut to the {@link MapKit#hashMap(Object[])}.
*
* @param array the given array
* @param <K> the key type
* @param <V> the value type
* @return a new {@link HashMap} initialing with the given array
* @see MapKit
*/
public static <K, V> @Nonnull HashMap<K, V> hashMap(Object @Nonnull ... array) {
return MapKit.hashMap(array);
}
/**
* Returns a new {@link LinkedHashMap} initialing with the given array
* <p>
* Every two elements of the array form a key-value pair, that means, the {@code array[0]} and {@code array[1]} will
* be the first key-value pair, the {@code array[2]} and {@code array[3]} will be the second key-value pair, and so
* on. If the length of the array is odd and the last key cannot match the value, then the last pair will be the
* key-{@code null} pair to put.
* <p>
* This method is a shortcut to the {@link MapKit#linkedHashMap(Object[])}.
*
* @param array the given array
* @param <K> the key type
* @param <V> the value type
* @return a new {@link HashMap} initialing with the given array
* @see MapKit
*/
public static <K, V> @Nonnull LinkedHashMap<K, V> linkedHashMap(Object @Nonnull ... array) {
return MapKit.linkedHashMap(array);
}
/**
* Returns a {@link Stream} from the given elements.
* <p>
* This method is a shortcut to the {@link StreamKit#stream(Object[])}.
*
* @param elements the given elements
* @param <T> the component type
* @return a {@link Stream} from the given elements
* @see StreamKit
*/
@SafeVarargs
public static <T> @Nonnull Stream<T> stream(T @Nonnull ... elements) {
return StreamKit.stream(elements);
}
/**
* Returns a {@link Stream} from the given elements.
* <p>
* This method is a shortcut to the {@link StreamKit#stream(Iterable)}.
*
* @param elements the given elements
* @param <T> the component type
* @return a {@link Stream} from the given elements
* @see StreamKit
*/
public static <T> @Nonnull Stream<T> stream(@Nonnull Iterable<T> elements) {
return StreamKit.stream(elements);
}
//---------------- Collection End ----------------//
//---------------- Thread Begin ----------------//
/**
* Sleeps the current thread for the specified milliseconds.
* <p>
* This method is a shortcut to the {@link ThreadKit#sleep(long)}.
*
* @param millis the specified milliseconds
* @throws AwaitingException if the current thread is interrupted or an error occurs while sleeping
* @see ThreadKit
*/
public static void sleep(long millis) throws AwaitingException {
ThreadKit.sleep(millis);
}
/**
* Sleeps the current thread for the specified duration.
* <p>
* This method is a shortcut to the {@link ThreadKit#sleep(Duration)}.
*
* @param duration the specified duration
* @throws AwaitingException if the current thread is interrupted or an error occurs while sleeping
* @see ThreadKit
*/
public static void sleep(@Nonnull Duration duration) throws AwaitingException {
ThreadKit.sleep(duration);
}
//---------------- Thread End ----------------//
//---------------- Process Begin ----------------//
/**
* Starts a new process with the specified command, returns the process.
* <p>
* This method is a shortcut to the {@link ProcessKit#start(String)}.
*
* @param command the specified command
* @return the process
* @throws IORuntimeException if any error occurs
* @see ProcessKit
*/
public static @Nonnull Process process(@Nonnull String command) throws IORuntimeException {
return ProcessKit.start(command);
}
/**
* Starts a new process with the specified command and arguments, returns the process.
* <p>
* This method is a shortcut to the {@link ProcessKit#start(String...)}.
*
* @param command the specified command and arguments
* @return the process
* @throws IORuntimeException if any error occurs
* @see ProcessKit
*/
public static @Nonnull Process process(@Nonnull String @Nonnull ... command) throws IORuntimeException {
return ProcessKit.start(command);
}
//---------------- Process End ----------------//
private Fs() {
}
}