Этот набор инструментов изначально был моей собственной коллекцией, которую я использовал для личных нужд. Однако со временем у меня появилось всё больше идей, и в результате получился этот большой сборник. Надо сказать, что в нём действительно есть немало полезных вещей, поэтому я решил написать документацию.
В первую очередь, документация будет посвящена инструментам, которые я считаю наиболее важными, а другие инструменты, которые, на мой взгляд, не так интересны, будут описаны более кратко. Однако, следуя своим привычкам, я буду предоставлять достаточно полную информацию о javadoc, чтобы можно было получить доступ к деталям любого класса через javadoc или загрузив исходный код.
Временной диапазон проекта довольно широк, некоторые части были написаны несколько лет назад, а некоторые идеи возникли совсем недавно. Возможно, некоторые аспекты технологии недостаточно развиты, но я надеюсь на понимание.
Затем, если я посчитаю, что какой-то инструмент стоит упомянуть, я отмечу его знаком «*».
Наконец, моё описание может быть немного бессистемным и произвольным, поскольку я не знаю, как правильно представить проект, который содержит множество различных инструментов. Поэтому я просто написал документ в стиле полу-беседы.
Однако, если кто-то действительно захочет попробовать использовать этот проект, я уже загрузил его в репозиторий Maven:
Используйте последнюю версию из репозитория, адрес репозитория:
https://mvnrepository.com/artifact/io.github.ForteScarlet.plusutils/simple-plusutils
<dependency>
<groupId>io.github.ForteScarlet.plusutils</groupId>
<artifactId>simple-plusutils</artifactId>
<version>1.3.1</version>
</dependency>
Сгенерированный онлайн-Javadoc: javaDoc
Интерфейс StringAble определяет три интерфейса для получения строк в реализации класса.
Интерфейс MD5Able наследует интерфейс StringAble и предоставляет несколько методов default для получения соответствующей строки MD5 на основе получения строки (MD5 генерируется с использованием MD5Utils).
Класс CharSequenceUtils — это класс утилит для работы с CharSequence. Он предоставляет следующие методы:
/**
* Удаляет начальные и конечные пустые символы
*/
public static CharSequence trim(CharSequence s);
/**
* Определяет, является ли строка пустой или нулевой. В этом месте, если только пустые символы также будут рассматриваться как empty, то есть будет выполнена операция trim
* @param s
* @return
*/
public static boolean isEmpty(CharSequence s);
/**
* Перебирает все символы
* @param consumer Операция обхода
* @param s Каждый символ
*/
public static void foreach(CharConsumer consumer, CharSequence s);
/**
* Преобразует в массив char[]
*/
public static char[] charArray(CharSequence s);
/**
* Преобразовывает в StringBuilder
*/
public static StringBuilder toBuilder(CharSequence s);
/**
* Преобразовывает в StringBuilder
*/
public static StringBuilder toBuilder(int init, CharSequence s);
/**
* Преобразовывает в StringBuilder
*/
public static StringBuilder toBuilder(String init, CharSequence s);
/**
* Преобразование в StringBuilder
*/
public static StringBuilder toBuilder(CharSequence init, CharSequence s);
Класс ExString расширяет класс CharSequenceUtils и предоставляет, переопределяет некоторые методы, ориентированные на объекты String.
/**
* Определяет, пуста ли строка (включая все пустые символы)
*
* @param s
* @return
*/
public static boolean isEmpty(String s);
/**
* Определяет, не пуста ли строка (включая все пустые символы)
*
* @param s
* @return
*/
public static boolean isNotEmpty(String s);
/**
* Копирует строку n раз равной длины
* @param base Строка для копирования
*/
public static String repeat(String base, int times);
/**
* См. #repeat(String, int)
*/
public static String repeat(char base, int times);
/**
* См. #repeat(String, int)
*/
public static String repeat(int base, int times);
/**
* См. #repeat(String, int)
*/
public static String repeat(Object base, int times);
/**
* Получает все перестановки одного слова, количество обычно равно факториалу word.length
*
* @param word Слово для перестановки
* @return Результат перестановки
*/
public static String[] getPermutation(String word);
/**
* Рекурсивно получает все перестановки строки
*
* @param out StringBuilder для объединения
* @param in строка
* @param used Массив для отслеживания того, была ли уже добавлена строка
* @param s Каждая комбинация вывода
*/
private static void getPermutation(StringBuilder out, String in, boolean[] used, Consumer<String> s);
/**
* Получает все возможные комбинации элементов в списке
* <code>
abc:
- ab
- ac
- a
- b
- c
- bc
</code>
* @param list Список элементов
*/
public static <T> List<List<T>> getCombinations(List<T> list);
/**
* Получает все возможные комбинации элементов в массиве
* @param list Массив элементов
*/
public static <T> List<List<T>> getCombinations(T... list);
Класс ExMath — это класс математических утилит. Он предоставляет некоторые методы (похоже, сейчас есть только вещи, связанные с факториалом):
/**
* Вычисляет факториал числа, n!
* @param n n!
*/
public static long factorial(long n);
/**
* Вычисляет факториал числа, n! <br>
* Использует bigInteger для вычислений
``` **Перевод текста на русский язык:**
Теоретически можно вычислить факториал всех значений в диапазоне long.
* @param n n!
*/
public static BigInteger factorialBig(BigInteger n);
/**
* Вычисляет факториал числа, n! <br>
* Использует bigInteger для вычислений
* @param n n!
*/
public static BigInteger factorialBig(long n);
/**
* Вычисляет факториал числа, n!
* @param n n!
*/
public static long factorialParallel(long n);
/**
* Вычисляет факториал числа, n! <br>
* Использует bigInteger для вычислений, теоретически может вычислить факториалы всех значений в диапазоне long
* @param n n!
*/
public static BigInteger factorialBigParallel(BigInteger n);
/**
* Вычисляет факториал числа, n! <br>
* Использует bigInteger для вычислений
* @param n n!
*/
public static BigInteger factorialBigParallel(long n);
#### MD5Utils — класс инструментов MD5
> util class
Предоставляет два метода для шифрования строки в MD5, используя функцию шифрования из Java.
```java
public static String toMD5(String inStr);
public static String toMD5(byte[] byteArray);
class
Преобразует строку в объект потока Reader.
Reader reader = new StringListReader("string");
com.forte.utils.chinese
util class
Предлагает несколько методов для генерации случайных китайских или случайных имён. Однако случайные китайские имена могут содержать много редких иероглифов, что косвенно приводит к тому, что случайные китайские имена выглядят немного странно...
Кстати, фамилии взяты из «Байцзясин» (список ста фамилий).
/**
* Получить случайное имя
*
* @param charsetName кодировка символов
* @return
*/
public static String getName(String charsetName);
/**
* Получает несколько случайных фамилий
*
* @return
*/
public static String[] getFamilyName(int nums);
/**
* Получить одну случайную фамилию
*
* @return
*/
public static String getFamilyName();
/**
* Получить одно случайное имя
*
* @return
*/
public static String getName();
/**
* Получить один китайский символ
*
* @param encoding формат кодирования
* @return
*/
public static String getChinese(String encoding);
/**
* Получить один случайный китайский символ
*
* @return
*/
public static String getChinese();
/**
* Получить один случайный китайский символ
*
* @return
*/
public static String getChinese(int num);
/**
* Получить один случайный китайский символ
*
* @return
*/
public static String getChinese(int num, String encoding) ;
package com.forte.utils.chinese.chinesenumber
util classes
Это не отдельный инструмент, а набор инструментов, внешним интерфейсом которого является класс CNumerUtil.
У этого класса есть только два внешних метода:
/**
* Преобразование китайских цифр в настоящие цифры
* @param chinese китайские цифры
* @return
*/
public static <T extends Number> CNumber<T> toNumber(String chinese);
/**
* Анализирует возможные арифметические операторы в китайских символах и вычисляет результат <br>
* Если результат является логическим значением, то true:1, false:0 <br>
*
*/
public static CNumber toCalculation(String chinese) throws ScriptException;
Хотя у окна всего два метода, в целом функциональность очень мощная. Для метода toNumber, если вы не используете какие-либо странные формы написания китайских цифр или диалекты китайских чисел, точность преобразования обычно очень высока.
Что касается второго метода toCalculation, мои тестовые данные всё ещё относительно невелики. В общем, он также учитывает сложение, вычитание, умножение и деление, как и в JS (операторы вычислений аналогичны операторам JavaScript, а не реальным математическим операциям), и те же самые, пока они не слишком странные, все могут быть проанализированы.
com.forte.utils.collections
class
Эта карта изначально была разработана для обеспечения того, чтобы сохранённые значения имели определённый срок действия. Когда срок действия истекает, при следующем получении значение не будет доступно, что позволяет ему иметь «срок годности». Текущая реализация ленива и проверяет срок действия только при получении значения, но это имеет недостаток: если вы никогда больше не получите доступ к значению, оно не исчезнет из карты, что приведёт к ненужному использованию ресурсов.
Внутренняя карта использует ConcurrentHashMap для обеспечения определённой безопасности потоков.
Помимо интерфейса Map, предоставляются следующие методы:
/**
* Добавить один элемент, если срок действия уже истёк, не добавлять
*/
public R put(T t, R r, LocalDateTime expireDate);
/** Добавить один элемент и указать срок действия */
public R put(T t, R r, TemporalAmount amount);
/** Сохранить значение и указать срок действия */
public R put(T t , R r, long amountToAdd, TemporalUnit unit);
/** Срок действия истечёт через xx наносекунд */
public R putPlusNanos(T t , R r, long nanos);
/** Срок действия истечёт через xx секунд */
public R putPlusSeconds(T t , R r, long seconds);
/** Срок действия истечёт через xx минут */
public R putPlusMinutes(T t , R r, long minutes);
/** Срок действия истечёт через xx часов */
public R putPlusHours(T t , R r, long hours);
/** Срок действия истечёт через xx дней */
public R putPlusDays(T t , R r, long days);
/** Срок действия истечёт через xx месяцев */
public R putPlusMonth(T t , R r, long month);
/** Срок действия истечёт через xx лет, если вы сможете дождаться этого времени */
public R putPlusYear(T t , R r, long year);
class`
Как следует из названия, предоставляет итератор для массива.
В настоящее время не поддерживает базовые типы данных.
// Через конструктор
util class
Предоставляет некоторые вспомогательные операции над коллекциями, которые я когда-то хотел, но не нашёл в Collections. Например, сортировка карт.
/**
* Копирует объект через поток
* @param collection
``` **Maputer Map存值工具类**
> util class
Этот инструмент класса Maputer назван так потому, что он предназначен для работы с map. Название образовано от слов Map, put и er.
**Методы класса:**
* **public static <K, V> V put(Map<K, V> map, K key, Function<V, V> ifExist, Supplier<V> ifNull)** — добавляет значение в map. Если значение уже существует, то оно передаётся в функцию ifExist и возвращается её результат. Если значения нет, то используется функция ifNull для получения нового значения.
* **public synchronized static <K, V> void putSynchronized(Map<K, V> map, K key, Function<V, V> ifExist, Supplier<V> ifNull)** — аналогичен предыдущему методу, но синхронизирован.
* **public static <K, V> void peek(Map<K, V> map, K key, Consumer<V> ifExist, Supplier<V> ifNull)** — получает значение из map или добавляет его, если оно отсутствует. Значение передаётся функции ifExist, которая может его обработать. Новое значение получается с помощью функции ifNull.
* **public synchronized static <K, V> void peekSynchronized(Map<K, V> map, K key, Consumer<V> ifExist, Supplier<V> ifNull)** — аналогично предыдущему методу, но синхронизировано.
* **public static <E, K, V extends Collection<E>> void addAll(Map<K, V> map, K key, V collections)** — добавляет все элементы коллекции collections в map по ключу key. Если ключ не существует, он создаётся.
* **Другие методы**, описание которых в запросе отсутствует. **Текст запроса:**
public static <E, K, V extends Collection> void addAllSynchronized(Map<K, V> map, K key, V collections);
/**
/**
/**
/**
**Перевод текста на русский язык:**
общественный статический <E, K, V расширяет коллекцию> пустоту addAllSynchronized (карта<K, V> карта, ключ K, коллекции V);
/**
* Дано значение value типа Colletion<E>, представляющее собой набор map.
* Дан параметр типа E.
* Если значение value существует, добавить его. Если не существует, использовать заданный параметр для заполнения.
* @параметр карты набор карт
* @ключ параметра ключ
* @один параметр сохранить или добавить
*/
общественная статическая <E, K, V расширяет коллекцию<E>> пустота добавить (карта<K, V> карта, ключ K, один E, если null V);
/**
* Поточно-безопасный метод {@link #add}.
*/
публичный статический <E, K, V расширяет Collection<E>> void addSynchronized (Map<K, V> map, K ключ, E один, V если null);
/**
* Дано значение value типа Colletion<E>, представляющее собой набор map.
* Дан параметр типа E.
* Если значение value существует, добавить его.
* Если не существует, то использовать заданный метод для получения значения и заполнения.
* @параметр карты набор карт
* @ключ параметра ключ
* @один параметр сохранить или добавить
*/
общественный статический <E, K, V расширяет коллекцию<E>> пустота добавить (карта<K, V> карта, ключ K, один E, поставщик<V> если null);
/**
* Потокобезопасный метод {@link #add(Map, Object, Object, Supplier)}.
*/
общественный статический <E, K, V расширяет коллекцию<E>> пустота addSynchronized (Карта<K, V> Карта, Ключ K, Один E, Поставщик<V> Если Null);
/**
* @see #getTempFile(String, String, File, boolean)
*/
public static File getTempFile(String prefix, String suffix) throws IOException;
**О первом методе и его возвращаемом значении `FileNameJoiner`:**
Возвращаемое значение `FileNameJoiner` — это небольшой инструмент для объединения частей пути к файлу. В качестве разделителя в путях используется символ из класса `separator`, что обеспечивает совместимость с различными системами.
**Функция интерфейса расширения `*`**
В пакете `com.forte.utils.function` представлено множество расширений для функциональных интерфейсов Java. Поскольку все они являются функциями, я не буду подробно описывать методы, а сразу перейду к описанию классов.
ByteConsumer
ByteFunction
CharConsumer
CharFunction
ExConsumer
ExFunction
ExFunctionThrows
FunctionThrows
Это некоторые функции без базовых типов данных, трёхпараметровые функции (начинающиеся с Ex) и функции с Throws. Трёхпараметровые — это функции, у которых на один параметр больше, чем у функций с префиксом Bi.
Можно ли использовать функцию типа byte с функцией типа int? Да, но раз уж они написаны, то пусть будут.
**SerializableFunctions: Сериализуемые функции**
Если в классе есть поле, которое является функцией, и вы хотите, чтобы оно было сериализовано, вы можете либо использовать приведение типов для создания экземпляра, либо написать функцию, реализующую интерфейс Serializable.
Обратите внимание: если вы используете такую функцию, вам следует дополнительно рассмотреть вопрос о serialVersionUID. Все функции в Java имеют соответствующие им в `SerializableFunctions`.
Затем в классе `SerializableFunctions` я также предоставляю статический метод для получения универсального строкового представления класса (если он существует). Например, Map вернёт "<K,V>".
```java
/**
* Get the generic string of the Class ( if it exists )
* @param c class
* @return generic string
*/
public static String getGenericString(Class<?> c)
Инструменты для генерации случайных значений
MockUtil: Инструменты для генерации фиктивных данных
Этот инструмент в основном используется в другом моём проекте Mock.java
. Он предоставляет множество методов для генерации фиктивных данных. Из-за большого количества методов они здесь не перечислены. В целом, данные включают:
RandomUtil: Инструмент для генерации случайных значений
Как и предыдущий класс, большинство методов MockUtil
зависят от RandomUtil
. Используется для генерации различных случайных значений различными способами в соответствии с требованиями. Например, логическое значение, случайное целое или дробное число, случайный цвет, случайный элемент массива/набора и так далее. Опять же, они не перечисляются здесь по отдельности.
Отражение инструментов *
EnumUtils: Инструмент для работы с перечислениями
Честно говоря, потребность в динамическом создании экземпляров перечислений встречается не так часто, но я сталкивался с ней дважды. Поэтому я написал этот инструмент, который в основном предназначен для создания новых экземпляров объектов определённого типа перечисления.
/**
* 获取一个枚举的新实例对象
* @param enumType 枚举类型
* @param name 枚举名称
* @param constructorTypes 构造方法参数类型集
* @param args 构造对应的参数列表
* @return
* @throws NoSuchMethodException
* @throws IllegalAccessException
*/
public static <T extends Enum<T>> T newEnum(Class<T> enumType, String name, Class<?>[] constructorTypes, Object[] args) throws NoSuchMethodException, IllegalAccessException;
/**
* 获取一个枚举的新实例对象
* 默认尝试使用枚举的无参构造
* @param enumType 枚举类型
* @param name 枚举的name
* @return 枚举新实例对象
* @throws NoSuchMethodException
* @throws IllegalAccessException
*/
public static <T extends Enum<T>> T newEnum(Class<T> enumType, String name) throws NoSuchMethodException, IllegalAccessException;
/**
* 创建一个枚举新实例,会根据枚举构造参数数量尝找唯一对应的构造。
* 找不到或者有多个会抛出异常。
* @param enumType 枚举类型
* @param name 枚举名称
* @param args 枚举的构造参数
* @return
* @throws NoSuchMethodException
* @throws IllegalAccessException
*/
public static <T extends Enum<T>> T newEnum(Class<T> enumType, String name, Object... args) throws NoSuchMethodException, IllegalAccessException;
/**
* 获取枚举的全部实例
* 由于原生的values属于final字段无法修改,于是从此处提供一个方法获取values值
* 为了使得效果与原生values一致,会进行排序
* @param t 枚举类型
* @return 枚举全部实例
*/
public static <T extends Enum<T>> T[] values(Class<T> t, IntFunction<T[]> initArray);
/**
* 通过枚举的类型获取这个枚举类型的成员Map
* 会进行copy
* @param enumType 枚举类型
* @return 枚举内部全部成员对应键值对
*/
public static <T extends Enum<T>> Map<String, T> getEnumConstantDirectory(Class<T> enumType) throws IllegalAccessException ;
Прежде всего, поскольку это отражение, необходимо учитывать проблемы эффективности и безопасности перед использованием. Что касается эффективности, внутренние экземпляры не создаются каждый раз заново, некоторые необходимые ресурсы кэшируются, поэтому эффективность не должна быть слишком низкой. Лично я провёл тест, создав 1000_0000 экземпляров нового перечисления, и это заняло около 25648 мс. Однако вы вряд ли будете использовать столько перечислений, верно?
Во-вторых, после создания экземпляр перечисления можно получить через метод valueO
f. Но его нельзя получить через values()
, потому что эти два метода реализованы по-разному. Если вам нужны values()
, вы можете рассмотреть возможность использования инструментального класса values
.
Наконец, не жалуйтесь, почему некоторые классы используют внутренние классы, потому что я просто хочу, чтобы в инструменте был только один класс, а не пакет инструментов. 👌
FieldUtils & MethodUtils: инструменты отражения
Поскольку они зависят друг от друга, их следует рассматривать вместе. BiFunction<Method, Object[], Object>> defaultReturn);
/**
Где ExProxyHandler — это функциональный интерфейс, который определяется следующим образом:
/**
* Функциональный интерфейс с обработкой исключений, используемый для построения параметров динамического прокси.
*/
@FunctionalInterface
public interface ExProxyHandler<T, U, R> {
/**
* Функция интерфейса.
* @param t — первый параметр.
* @param u — второй параметр.
* @return — возвращаемое значение.
* @throws Throwable — любое исключение.
*/
R apply(T t, U u) throws Throwable;
}
### Регулярные инструменты
`com.forte.utils.regex`
#### RegexUtil — класс регулярных инструментов
> Класс util.
Говорит, что это класс регулярных инструментов, но на самом деле это просто класс, который позволяет разбивать строки, извлекать подстроки и получать объекты Pattern и Matcher, а также выполнять не совсем понятную функцию извлечения имён таблиц из запроса SELECT, которая не поддерживает JOIN.
```java
/**
* Простая и грубая реализация игнорирования регистра символов.
* @param str — регулярное выражение.
*/
public static String toIgnoreCaseRegex(String str);
/**
* Получает объект Pattern, соответствующий регулярному выражению.
*/
public static Pattern getPattern(String regex, int flags);
public static Pattern getPattern(String regex);
public static Matcher getMatcher(String source, String regex);
public static Matcher getMatcher(String source, String regex, int flags);
public static Matcher getMatcher(String source, Pattern pattern);
/**
* Разбивает строку на подстроки, соответствующие регулярному выражению.
*<code>
* String s = "abaacaaad";
* List<String> list = getSplit(s, "a+");
* list -> [a, aa, aaa]
*</code>
*/
public static List<String> getSplit(String source, Pattern pattern);
/**
* Создаёт поток строк, соответствующих регулярному выражению в строке.
*/
public static Stream<String> getSplitStream(String source, Pattern pattern);
/**
* Разделяет строку на список строк, соответствующих регулярному выражению.
*/
public static List<String> getSplit(String source, String regex);
/**
* Преобразует строку в поток строк, соответствующих регулярному выражению.
*/
public static Stream<String> getSplitStream(String source, String regex);
/**
* Извлекает строки из строки.
*/
public static String[] getSplitArray(String source, String regex);
/**
* Извлекает строки из строки с использованием объекта Pattern.
*/
public static String[] getMatcherArray(String source, Pattern pattern);
/**
* Извлекает имена таблиц из SQL-запроса SELECT.
* В настоящее время не поддерживается JOIN.
* @param selectSql
* @return
*/
public static List<String> getTableNameFromSql(String selectSql);
### Инструменты для создания синглтонов
`com.forte.utils.single`
#### SingleFactory — фабрика синглтонов
> Класс util.
Этот класс фабрики синглтонов был написан после того, как я увидел концепцию оптимистичных блокировок CAS и только что изучил связанные с этим знания о синглтонах. Сейчас, оглядываясь назад, я понимаю, что он не очень хорош, и его функциональность не полностью соответствует CAS. Однако он до сих пор не оптимизирован, поскольку его основная функция — хранить данные в Map. Для создания настоящего синглтона нужно приложить больше усилий.
```java
/** Фабрика */
public synchronized static SingleFactory build(Object obj);
/** Фабрика */
public synchronized static SingleFactory build();
/**
* Очищает все сохранённые данные.
*/
public void clear();
/**
* Получает экземпляр синглтона, если запись для этого класса не существует, возвращает null.
*/
public final <T> T get(Class<? extends T> clz);
/**
* Получает экземпляр синглтона или пытается создать новый экземпляр с помощью отражения, который будет записан.
* Если создание не удастся, будет выброшено соответствующее исключение.
* @param <T>
* @return
*/
public final <T> T getOrNew(Class<T> clz);
public final <T> T getOrNew(Class<? extends T> clz , Object... params);
/**
* Если существует, получает, иначе присваивает значение.
* @param clz
* @param t
* @param <T>
* @return
*/
public final <T> T getOrSet(Class<? extends T> clz, T t);
/**
* Если существует, получает, иначе присваивает значение без указания объекта класса.
* @param t
* @param <T>
* @return
*/
public final <T> T getOrSet(T t);
/**
* Если существует, получает, иначе присваивает значение с помощью поставщика.
* @param clz
* @param supplier
* @param <T>
* @return
*/
public final <T> T getOrSet(Class<? extends T> clz, Supplier<? extends T> supplier);
/**
* Если существует, получает, иначе присваивает значение через поставщика без указания класса объекта.
* @param supplier
* @param <T>
* @return
*/
public final <T> T getOrSet(Supplier<? extends T> supplier);
/**
* Переустанавливает экземпляр синглтона.
* @param clz
* @param t
* <T>
*/
public final <T> void reset(Class<? extends T> clz , T t);
/**
* Переустанавливает экземпляр синглтона без указания класса.
* @param t
* <T>
*/
public final <T> void reset(T t);
/**
* Переустанавливает экземпляр синглтона и получает экземпляр синглтона.
* @param clz
*/ **CharSequence prefix, CharSequence suffix);**
/**
* groupBy
*/
public <K> Map<? extends K, List<T>> groupBy(Function<? super T, ? extends K> classifier);
/**
* groupBy
*/
public <K, A, D> Map<? extends K, D> groupBy(Function<? super T, ? extends K> classifier, Collector<? super T, A, D> downstream);
/**
* groupBy
*/
public <K, A, D, M extends Map<K, D>> M groupBy(Function<? super T, ? extends K> classifier, Supplier<M> mapFactory, Collector<? super T, A, D> downstream) ;
/**
* groupByConcurrent
*/
public <K> Map<? extends K, List<T>> groupByConcurrent(Function<? super T, ? extends K> classifier);
/**
* groupByConcurrent
*/
public <K, A, D> Map<? extends K, D> groupByConcurrent(Function<? super T, ? extends K> classifier, Collector<? super T, A, D> downstream);
/**
* groupByConcurrent
*/
public <K, A, D, M extends ConcurrentMap<K, D>> M groupByConcurrent(Function<? super T, ? extends K> classifier, Supplier<M> mapFactory, Collector<? super T, A, D> downstream);
/**
* concat
*/
public ExStream<T> concat(Stream<T> concat);
public ExStream<T> concat(T t);
public ExStream<T> concat(T... t);
public ExStream<T> concat(Collection<T> collection);
### 线程工具
> com.forte.utils.thread
#### BaseLocalThreadPool 线程池工厂
> util class
Этот класс потоков и пулов потоков также является идеей, которая возникла у меня во время учёбы в школе, когда я увидел концепцию пула потоков. Я написал простой пул потоков на основе онлайн-руководств, а затем подумал о создании фабрики пулов потоков. Возможно, есть некоторые недостатки, но функциональность всё ещё может быть реализована.
Пул потоков использует встроенную структуру Java.
```java
/**
* 创建线程池的工厂, без имени, использует значения по умолчанию
* @return
*/
public static Executor getThreadPool();
/**
* Создание фабрики пула потоков
*
* @param poolName имя созданного пула потоков
* @return
*/
public static Executor getThreadPool(String poolName);
/**
* создание фабрики пула потоков, без имени, использование значений по умолчанию
*
* @return
*/
public static Executor getThreadPool(PoolConfig poolConfig);
/**
* создание фабрики пула потоков
*
* @param poolName имя созданного пула потоков
* @return
*/
public static Executor getThreadPool(String poolName, PoolConfig poolConfig);
/**
* удаление указанного пула потоков
*
* @param poolName
* @return
*/
public static boolean removeThreadPool(String poolName);
/**
* получение пула потоков в текущем потоке
*
* @return
*/
public static Executor getLocalThreadPool();
/**
* удалить пул потоков в текущем потоке
*/
public static boolean removeLocalThreadPool();
/**
* получение фабрики потоков
*
* @return
*/
public static ThreadFactory getFactory();
Здесь PoolConfig
— это класс, который объединяет параметры, необходимые для создания пула потоков.
/**
* Конфигурационный класс, предоставляющий несколько параметров
*/
public static class PoolConfig{
/**
* размер основного пула
*/
private int corePoolSize = 0;
/**
* максимальное количество потоков в пуле потоков, это также очень важный параметр, он указывает, сколько потоков может создать пул потоков максимум;
*/
private int maximumPoolSize = 500;
/**
* указывает, как долго поток будет оставаться активным, если у него нет задачи для выполнения.
* По умолчанию, только когда количество потоков в пуле больше, чем corePoolSize, keepAliveTime вступит в силу, пока количество потоков в пуле не станет меньше или равно corePoolSize. В это время, если время простоя потока достигает keepAliveTime, поток завершится, пока количество потоков в пуле не превысит corePoolSize.
* Однако, если вы вызываете метод allowCoreThreadTimeOut(boolean), keepAliveTime также вступит в силу, даже если количество потоков в пуле меньше или равно corePoolSize;
*/
private long keepAliveTime = 5;
/**
* unit: параметр keepAliveTime единица времени, имеет 7 значений, в классе TimeUnit есть 7 статических свойств:
* TimeUnit.DAYS; //дни
* TimeUnit.HOURS; //часы
* TimeUnit.MINUTES; //минуты
* ```
В этом тексте описывается код на языке Java, связанный с разработкой и тестированием программного обеспечения. Текст содержит описание методов и классов, которые используются для работы с потоками и пулами потоков. **Например, сегодня 2019-01-10, beforeDays(3, false)**
* *это значит:*
[2019-01-09, 2019-01-08, 2019-01-07]
**@param days** *отодвинуть на сколько дней*
**@param fromNow** *включать ли сегодняшний день*
**@return**
public static List beforeDaysToString(int days, boolean fromNow);
**Массив дней, сдвинутых назад на n дней.**
Например, сегодня 2019-01-10, beforeDays(3, false)
*это значит:*
[2019-01-09, 2019-01-08, 2019-01-07]
beforeDaysToString(1, false, String[]::new)
**@param days** *отодвинуть на сколько дней*
**@param fromNow** *включать ли сегодняшний день*
public static String[] beforeDaysToString(int days, boolean fromNow, IntFunction<String[]> generator);
**Сдвиг назад на n лет, например, «последние 5 лет», «последние 6 лет».**
**@param years**
**@param fromNow**
**@return**
public static List beforeYears(int years, boolean fromNow);
**Преобразование DayOfWeek в строку на китайском языке, обозначающую неделю.**
public static String toChineseWeekDay(DayOfWeek dayOfWeek);
**Копирование поля {@link #DAY_OF_WEEK_CHINESE_MAP}.**
public static Map<Integer, String> getDayOfWeekChineseMap();
**Получение массива строк на китайском языке с названиями дней недели.**
public static String[] getDayOfWeekChineseStr();
**Получение всех месяцев года.**
public static List getAllYearMonth(Year year);
**Получение всех месяцев года в виде строки.**
public static List getAllYearMonthToString(Year year);
**Секундомер**
> util class
Иногда вы хотите рассчитать время выполнения метода до и после, но считаете, что писать дважды System.currentTimeMillis() и затем выполнять вычитание слишком хлопотно? Этот класс инструментов упрощает процесс измерения времени и автоматически вычисляет разницу. Кроме того, значения времени до и после в разных потоках независимы друг от друга (контролируется через ThreadLocal).
**Запись времени.**
/** * 记录一个时间 */ public static long record();
**Получить последнее записанное время.**
/** * 获取上次计时时间 */ public static long getLastTime();
**Получить последнее записано время и очистить его.**
/** * 获取上次计时时间并清除 */ public static long getLastTimeAndRemove();
**Вернуть разницу между текущим и последним временем.**
Если последнего времени нет, то используется текущее время для выполнения пользовательской обработки.
/**
* 返回当前与上次的时间差
* 如果上次没有时间差,则根据 текущему времени сделать пользовательскую обработку
*/
public static long difference(Function<Long, Long> orElse);
**Возвращает разницу между текущим временем и последним.**
Если предыдущего времени не было, то по умолчанию возвращается -1.
/**
* 返回当前与上次的时间差
* если предыдущего времени не было, то по умолчанию возвращает -1
*/
public static long difference();
**Возвратить разницу между текущим и предыдущим временем или выбросить исключение.**
/**
* 返回当前与上次的时间差
* Если предыдущего времени не было, то выбрасывает исключение
*/
public static long differenceOrThrow() ;
Обычно этот инструмент используется следующим образом:
```java
Stopwatch.difference();
run();
long d2 = Stopwatch.difference();
// это значение d2 уже содержит разницу во времени
System.out.println(d2);
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )