diff --git a/build.gradle.kts b/build.gradle.kts index 2dfdc98..82e232e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -16,7 +16,7 @@ * ProjectName mingli-utils * ModuleName mingli-utils * CurrentFile build.gradle.kts - * LastUpdate 2025-09-09 08:37:33 + * LastUpdate 2025-09-10 11:08:55 * UpdateUser MingLiPro */ @@ -25,6 +25,7 @@ import java.time.format.DateTimeFormatter plugins { idea + java id("java-library") id("maven-publish") } @@ -61,11 +62,6 @@ dependencies { } -sourceSets.main.configure { - java.setSrcDirs(files("src")) - resources.setSrcDirs(files("resources")) -} - tasks.withType { options.encoding = "UTF-8" } diff --git a/gradle.properties b/gradle.properties index 23127a7..3be2629 100644 --- a/gradle.properties +++ b/gradle.properties @@ -22,4 +22,4 @@ JDKVERSIONS=1.8 GROUPSID=com.mingliqiye.utils ARTIFACTID=mingli-utils -VERSIONS=3.0.1 +VERSIONS=3.0.3 diff --git a/src/com/mingliqiye/utils/json/JsonApi.java b/src/com/mingliqiye/utils/json/JsonApi.java deleted file mode 100644 index 809e8c1..0000000 --- a/src/com/mingliqiye/utils/json/JsonApi.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2025 mingliqiye - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ProjectName mingli-utils - * ModuleName mingli-utils.main - * CurrentFile JsonApi.java - * LastUpdate 2025-09-09 09:22:02 - * UpdateUser MingLiPro - */ - -package com.mingliqiye.utils.json; - -import java.util.List; -import java.util.Map; - -/** - * JSON处理接口,提供JSON字符串与Java对象之间的相互转换功能 - */ -public interface JsonApi { - /** - * 将JSON字符串解析为指定类型的对象 - * - * @param json 待解析的JSON字符串 - * @param clazz 目标对象的Class类型 - * @param 泛型参数,表示目标对象的类型 - * @return 解析后的对象实例 - */ - T parse(String json, Class clazz); - - /** - * 将JSON字符串解析为指定泛型类型对象 - * - * @param json 待解析的JSON字符串 - * @param type 目标对象的Type类型(支持泛型) - * @param 泛型参数,表示目标对象的类型 - * @return 解析后的对象实例 - */ - T parse(String json, JsonTypeReference type); - - /** - * 将对象格式化为JSON字符串 - * - * @param object 待格式化的对象 - * @return 格式化后的JSON字符串 - */ - String format(Object object); - - /** - * 将字节数组形式的JSON解析为指定类型的对象 - * - * @param json 待解析的JSON字节数组 - * @param clazz 目标对象的Class类型 - * @param 泛型参数,表示目标对象的类型 - * @return 解析后的对象实例 - */ - default T parse(byte[] json, Class clazz) { - return parse(new String(json), clazz); - } - - /** - * 将字节数组形式的JSON解析为指定泛型类型对象 - * - * @param json 待解析的JSON字节数组 - * @param type 目标对象的Type类型(支持泛型) - * @param 泛型参数,表示目标对象的类型 - * @return 解析后的对象实例 - */ - default T parse(byte[] json, JsonTypeReference type) { - return parse(new String(json), type); - } - - /** - * 将JSON字符串解析为指定类型的对象,解析失败时返回默认值 - * - * @param json 待解析的JSON字符串 - * @param clazz 目标对象的Class类型 - * @param defaultValue 解析失败时返回的默认值 - * @param 泛型参数,表示目标对象的类型 - * @return 解析后的对象实例或默认值 - */ - default T parse(String json, Class clazz, T defaultValue) { - try { - return parse(json, clazz); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * 将JSON字符串解析为指定泛型类型对象,解析失败时返回默认值 - * - * @param json 待解析的JSON字符串 - * @param type 目标对象的Type类型(支持泛型) - * @param defaultValue 解析失败时返回的默认值 - * @param 泛型参数,表示目标对象的类型 - * @return 解析后的对象实例或默认值 - */ - default T parse( - String json, - JsonTypeReference type, - T defaultValue - ) { - try { - return parse(json, type); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * 将对象格式化为美化格式的JSON字符串(带缩进和换行) - * - * @param object 待格式化的对象 - * @return 格式化后的美化JSON字符串 - */ - String formatPretty(Object object); - - /** - * 将JSON字符串解析为指定元素类型的List集合 - * - * @param json 待解析的JSON字符串 - * @param elementType List中元素的类型 - * @param 泛型参数,表示List中元素的类型 - * @return 解析后的List集合 - */ - default List parseList(String json, Class elementType) { - return parse(json, JsonTypeUtils.listType(elementType)); - } - - /** - * 将JSON字符串解析为指定键值类型的Map集合 - * - * @param json 待解析的JSON字符串 - * @param keyType Map中键的类型 - * @param valueType Map中值的类型 - * @param 泛型参数,表示Map中键的类型 - * @param 泛型参数,表示Map中值的类型 - * @return 解析后的Map集合 - */ - default Map parseMap( - String json, - Class keyType, - Class valueType - ) { - JsonTypeReference> mapType = new JsonTypeReference< - Map - >() {}; - return parse(json, mapType); - } - - /** - * 验证字符串是否为有效的JSON格式 - * - * @param json 待验证的字符串 - * @return 如果是有效的JSON格式返回true,否则返回false - */ - boolean isValidJson(String json); - - /** - * 将对象转换为JSON字节数组 - * - * @param object 待转换的对象 - * @return 转换后的JSON字节数组 - */ - default byte[] toBytes(Object object) { - return format(object).getBytes(); - } - - /** - * 将对象转换为美化格式的JSON字节数组 - * - * @param object 待转换的对象 - * @return 转换后的美化格式JSON字节数组 - */ - default byte[] toBytesPretty(Object object) { - return formatPretty(object).getBytes(); - } - - /** - * 合并多个JSON字符串为一个JSON对象 - * - * @param jsons 待合并的JSON字符串数组 - * @return 合并后的JSON字符串 - */ - String merge(String... jsons); - - /** - * 获取JSON字符串中指定路径节点的值 - * - * @param json JSON字符串 - * @param path 节点路径(如:"user.name") - * @return 节点值的字符串表示 - */ - String getNodeValue(String json, String path); - - /** - * 更新JSON字符串中指定路径节点的值 - * - * @param json 原始JSON字符串 - * @param path 节点路径(如:"user.name") - * @param newValue 新的节点值 - * @return 更新后的JSON字符串 - */ - String updateNodeValue(String json, String path, Object newValue); - - D convert(T source, Class destinationClass); - D convert(T source, JsonTypeReference destinationType); -} diff --git a/src/com/mingliqiye/utils/stream/CStream.java b/src/com/mingliqiye/utils/stream/CStream.java deleted file mode 100644 index 90b6f86..0000000 --- a/src/com/mingliqiye/utils/stream/CStream.java +++ /dev/null @@ -1,1350 +0,0 @@ -/* - * Copyright 2025 mingliqiye - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ProjectName mingli-utils - * ModuleName mingli-utils.main - * CurrentFile CStream.java - * LastUpdate 2025-09-09 08:37:33 - * UpdateUser MingLiPro - */ - -package com.mingliqiye.utils.stream; - -import com.mingliqiye.utils.collection.ForEach; -import com.mingliqiye.utils.collection.Lists; -import com.mingliqiye.utils.random.RandomInt; -import java.util.*; -import java.util.concurrent.ConcurrentMap; -import java.util.function.*; -import java.util.stream.*; -import org.jetbrains.annotations.NotNull; - -/** - * 自定义的 CStream 实现类,用于对集合进行流式操作。 - * 该类实现了 Java 标准库中的 CStream 接口,并基于 List 数据结构提供了一系列流式处理方法。 - * - * @author MingLiPro - * @param 流中元素的类型 - */ -public class CStream implements java.util.stream.Stream { - - private final List list; - - /** - * 构造方法,初始化 CStream 实例。 - * - * @param list 用于构造 CStream 的列表数据,如果为 null 则使用空列表 - */ - private CStream(List list) { - this.list = list != null ? list : Lists.newArrayList(); - } - - /** - * 创建一个收集器,将元素收集到指定类型的集合中。 - * - * @param collectionFactory 用于创建目标集合的工厂函数 - * @param 元素类型 - * @param 目标集合类型 - * @return 收集器实例 - */ - public static > Collector toCollection( - @NotNull Supplier collectionFactory - ) { - return Collectors.toCollection(collectionFactory); - } - - /** - * 创建一个收集器,将元素收集到 List 中。 - * - * @param 元素类型 - * @return 收集器实例 - */ - public static Collector> toList() { - return Collectors.toList(); - } - - /** - * 创建一个收集器,将元素收集到 Set 中。 - * - * @param 元素类型 - * @return 收集器实例 - */ - public static Collector> toSet() { - return Collectors.toSet(); - } - - /** - * 创建一个收集器,将字符序列连接为字符串。 - * - * @return 收集器实例 - */ - public static Collector joining() { - return Collectors.joining(); - } - - /** - * 创建一个收集器,将字符序列使用指定分隔符连接为字符串。 - * - * @param delimiter 分隔符 - * @return 收集器实例 - */ - public static Collector joining( - @NotNull CharSequence delimiter - ) { - return Collectors.joining(delimiter); - } - - /** - * 创建一个收集器,将字符序列使用指定分隔符、前缀和后缀连接为字符串。 - * - * @param delimiter 分隔符 - * @param prefix 前缀 - * @param suffix 后缀 - * @return 收集器实例 - */ - public static Collector joining( - @NotNull CharSequence delimiter, - @NotNull CharSequence prefix, - @NotNull CharSequence suffix - ) { - return Collectors.joining(delimiter, prefix, suffix); - } - - /** - * 创建一个收集器,先对元素进行映射,再使用下游收集器收集。 - * - * @param mapper 映射函数 - * @param downstream 下游收集器 - * @param 输入元素类型 - * @param 映射后元素类型 - * @param 下游收集器中间类型 - * @param 结果类型 - * @return 收集器实例 - */ - public static Collector mapping( - @NotNull Function mapper, - @NotNull Collector downstream - ) { - return Collectors.mapping(mapper, downstream); - } - - /** - * 创建一个收集器,在下游收集完成后应用 finisher 函数。 - * - * @param downstream 下游收集器 - * @param finisher 完成后应用的函数 - * @param 输入元素类型 - * @param 下游收集器中间类型 - * @param 下游收集器结果类型 - * @param 最终结果类型 - * @return 收集器实例 - */ - public static Collector collectingAndThen( - @NotNull Collector downstream, - @NotNull Function finisher - ) { - return Collectors.collectingAndThen(downstream, finisher); - } - - /** - * 创建一个收集器,统计元素数量。 - * - * @param 元素类型 - * @return 收集器实例 - */ - public static Collector counting() { - return Collectors.counting(); - } - - /** - * 创建一个收集器,找出最小元素。 - * - * @param comparator 比较器 - * @param 元素类型 - * @return 收集器实例 - */ - public static Collector> minBy( - @NotNull Comparator comparator - ) { - return Collectors.minBy(comparator); - } - - /** - * 创建一个收集器,找出最大元素。 - * - * @param comparator 比较器 - * @param 元素类型 - * @return 收集器实例 - */ - public static Collector> maxBy( - @NotNull Comparator comparator - ) { - return Collectors.maxBy(comparator); - } - - /** - * 创建一个收集器,对元素映射为 int 后求和。 - * - * @param mapper 映射函数 - * @param 元素类型 - * @return 收集器实例 - */ - public static Collector summingInt( - @NotNull ToIntFunction mapper - ) { - return Collectors.summingInt(mapper); - } - - /** - * 创建一个收集器,对元素映射为 long 后求和。 - * - * @param mapper 映射函数 - * @param 元素类型 - * @return 收集器实例 - */ - public static Collector summingLong( - @NotNull ToLongFunction mapper - ) { - return Collectors.summingLong(mapper); - } - - /** - * 创建一个收集器,对元素映射为 double 后求和。 - * - * @param mapper 映射函数 - * @param 元素类型 - * @return 收集器实例 - */ - public static Collector summingDouble( - @NotNull ToDoubleFunction mapper - ) { - return Collectors.summingDouble(mapper); - } - - /** - * 创建一个收集器,对元素映射为 int 后计算平均值。 - * - * @param mapper 映射函数 - * @param 元素类型 - * @return 收集器实例 - */ - public static Collector averagingInt( - @NotNull ToIntFunction mapper - ) { - return Collectors.averagingInt(mapper); - } - - /** - * 创建一个收集器,对元素映射为 long 后计算平均值。 - * - * @param mapper 映射函数 - * @param 元素类型 - * @return 收集器实例 - */ - public static Collector averagingLong( - @NotNull ToLongFunction mapper - ) { - return Collectors.averagingLong(mapper); - } - - /** - * 创建一个收集器,对元素映射为 double 后计算平均值。 - * - * @param mapper 映射函数 - * @param 元素类型 - * @return 收集器实例 - */ - public static Collector averagingDouble( - @NotNull ToDoubleFunction mapper - ) { - return Collectors.averagingDouble(mapper); - } - - /** - * 创建一个收集器,使用指定初始值和操作符对元素进行归约。 - * - * @param identity 初始值 - * @param op 操作符 - * @param 元素类型 - * @return 收集器实例 - */ - public static Collector reducing( - T identity, - @NotNull BinaryOperator op - ) { - return Collectors.reducing(identity, op); - } - - /** - * 创建一个收集器,使用指定操作符对元素进行归约。 - * - * @param op 操作符 - * @param 元素类型 - * @return 收集器实例 - */ - public static Collector> reducing( - @NotNull BinaryOperator op - ) { - return Collectors.reducing(op); - } - - /** - * 创建一个收集器,先对元素进行映射,再使用指定初始值和操作符进行归约。 - * - * @param identity 初始值 - * @param mapper 映射函数 - * @param op 操作符 - * @param 输入元素类型 - * @param 映射后元素类型 - * @return 收集器实例 - */ - public static Collector reducing( - U identity, - @NotNull Function mapper, - @NotNull BinaryOperator op - ) { - return Collectors.reducing(identity, mapper, op); - } - - /** - * 创建一个收集器,根据分类器对元素进行分组。 - * - * @param classifier 分类器函数 - * @param 元素类型 - * @param 分类键类型 - * @return 收集器实例 - */ - public static Collector< - T, - ?, - @NotNull Map> - > groupingBy(@NotNull Function classifier) { - return Collectors.groupingBy(classifier); - } - - /** - * 创建一个收集器,根据分类器对元素进行分组,并使用下游收集器处理每组元素。 - * - * @param classifier 分类器函数 - * @param downstream 下游收集器 - * @param 元素类型 - * @param 分类键类型 - * @param 下游收集器中间类型 - * @param 下游收集器结果类型 - * @return 收集器实例 - */ - public static Collector> groupingBy( - @NotNull Function classifier, - @NotNull Collector downstream - ) { - return Collectors.groupingBy(classifier, downstream); - } - - /** - * 创建一个收集器,根据分类器对元素进行分组,使用指定的 Map 工厂和下游收集器。 - * - * @param classifier 分类器函数 - * @param mapFactory Map 工厂函数 - * @param downstream 下游收集器 - * @param 元素类型 - * @param 分类键类型 - * @param 下游收集器结果类型 - * @param 下游收集器中间类型 - * @param 目标 Map 类型 - * @return 收集器实例 - */ - public static > Collector< - T, - ?, - M - > groupingBy( - @NotNull Function classifier, - @NotNull Supplier mapFactory, - @NotNull Collector downstream - ) { - return Collectors.groupingBy(classifier, mapFactory, downstream); - } - - /** - * 创建一个并发收集器,根据分类器对元素进行分组。 - * - * @param classifier 分类器函数 - * @param 元素类型 - * @param 分类键类型 - * @return 收集器实例 - */ - public static Collector< - T, - ?, - @NotNull ConcurrentMap> - > groupingByConcurrent( - @NotNull Function classifier - ) { - return Collectors.groupingByConcurrent(classifier); - } - - /** - * 创建一个并发收集器,根据分类器对元素进行分组,并使用下游收集器处理每组元素。 - * - * @param classifier 分类器函数 - * @param downstream 下游收集器 - * @param 元素类型 - * @param 分类键类型 - * @param 下游收集器中间类型 - * @param 下游收集器结果类型 - * @return 收集器实例 - */ - public static Collector< - T, - ?, - @NotNull ConcurrentMap - > groupingByConcurrent( - @NotNull Function classifier, - @NotNull Collector downstream - ) { - return Collectors.groupingByConcurrent(classifier, downstream); - } - - /** - * 创建一个并发收集器,根据分类器对元素进行分组,使用指定的 Map 工厂和下游收集器。 - * - * @param classifier 分类器函数 - * @param mapFactory Map 工厂函数 - * @param downstream 下游收集器 - * @param 元素类型 - * @param 分类键类型 - * @param 下游收集器结果类型 - * @param 下游收集器中间类型 - * @param 目标 Map 类型 - * @return 收集器实例 - */ - public static > Collector< - T, - ?, - M - > groupingByConcurrent( - @NotNull Function classifier, - @NotNull Supplier mapFactory, - @NotNull Collector downstream - ) { - return Collectors.groupingByConcurrent( - classifier, - mapFactory, - downstream - ); - } - - /** - * 创建一个收集器,根据谓词条件对元素进行分区。 - * - * @param predicate 谓词函数 - * @param 元素类型 - * @return 收集器实例 - */ - public static Collector< - T, - ?, - @NotNull Map<@NotNull Boolean, @NotNull List> - > partitioningBy(@NotNull Predicate predicate) { - return Collectors.partitioningBy(predicate); - } - - /** - * 创建一个收集器,根据谓词条件对元素进行分区,并使用下游收集器处理每组元素。 - * - * @param predicate 谓词函数 - * @param downstream 下游收集器 - * @param 元素类型 - * @param 下游收集器结果类型 - * @param 下游收集器中间类型 - * @return 收集器实例 - */ - public static Collector< - T, - ?, - @NotNull Map<@NotNull Boolean, D> - > partitioningBy( - @NotNull Predicate predicate, - @NotNull Collector downstream - ) { - return Collectors.partitioningBy(predicate, downstream); - } - - /** - * 创建一个收集器,将元素转换为 Map。 - * - * @param keyMapper 键映射函数 - * @param valueMapper 值映射函数 - * @param 元素类型 - * @param 键类型 - * @param 值类型 - * @return 收集器实例 - */ - public static Collector> toMap( - @NotNull Function keyMapper, - @NotNull Function valueMapper - ) { - return Collectors.toMap(keyMapper, valueMapper); - } - - /** - * 创建一个收集器,将元素转换为 Map,并指定键冲突时的合并函数。 - * - * @param keyMapper 键映射函数 - * @param valueMapper 值映射函数 - * @param mergeFunction 键冲突合并函数 - * @param 元素类型 - * @param 键类型 - * @param 值类型 - * @return 收集器实例 - */ - public static Collector> toMap( - @NotNull Function keyMapper, - @NotNull Function valueMapper, - @NotNull BinaryOperator mergeFunction - ) { - return Collectors.toMap(keyMapper, valueMapper, mergeFunction); - } - - public static Collector> toMap( - @NotNull Function keyMapper - ) { - return Collectors.toMap(keyMapper, CStream::getThis); - } - - /** - * 创建一个收集器,将元素转换为 Map,指定键冲突合并函数和 Map 工厂。 - * - * @param keyMapper 键映射函数 - * @param valueMapper 值映射函数 - * @param mergeFunction 键冲突合并函数 - * @param mapSupplier Map 工厂函数 - * @param 元素类型 - * @param 键类型 - * @param 值类型 - * @param 目标 Map 类型 - * @return 收集器实例 - */ - public static > Collector toMap( - @NotNull Function keyMapper, - @NotNull Function valueMapper, - @NotNull BinaryOperator mergeFunction, - @NotNull Supplier mapSupplier - ) { - return Collectors.toMap( - keyMapper, - valueMapper, - mergeFunction, - mapSupplier - ); - } - - /** - * 创建一个并发收集器,将元素转换为 ConcurrentMap。 - * - * @param keyMapper 键映射函数 - * @param valueMapper 值映射函数 - * @param 元素类型 - * @param 键类型 - * @param 值类型 - * @return 收集器实例 - */ - public static Collector< - T, - ?, - @NotNull ConcurrentMap - > toConcurrentMap( - @NotNull Function keyMapper, - @NotNull Function valueMapper - ) { - return Collectors.toConcurrentMap(keyMapper, valueMapper); - } - - /** - * 创建一个并发收集器,将元素转换为 ConcurrentMap,并指定键冲突时的合并函数。 - * - * @param keyMapper 键映射函数 - * @param valueMapper 值映射函数 - * @param mergeFunction 键冲突合并函数 - * @param 元素类型 - * @param 键类型 - * @param 值类型 - * @return 收集器实例 - */ - public static Collector< - T, - ?, - @NotNull ConcurrentMap - > toConcurrentMap( - @NotNull Function keyMapper, - @NotNull Function valueMapper, - @NotNull BinaryOperator mergeFunction - ) { - return Collectors.toConcurrentMap( - keyMapper, - valueMapper, - mergeFunction - ); - } - - /** - * 创建一个并发收集器,将元素转换为 ConcurrentMap,指定键冲突合并函数和 Map 工厂。 - * - * @param keyMapper 键映射函数 - * @param valueMapper 值映射函数 - * @param mergeFunction 键冲突合并函数 - * @param mapSupplier Map 工厂函数 - * @param 元素类型 - * @param 键类型 - * @param 值类型 - * @param 目标 Map 类型 - * @return 收集器实例 - */ - public static > Collector< - T, - ?, - M - > toConcurrentMap( - @NotNull Function keyMapper, - @NotNull Function valueMapper, - @NotNull BinaryOperator mergeFunction, - @NotNull Supplier mapSupplier - ) { - return Collectors.toConcurrentMap( - keyMapper, - valueMapper, - mergeFunction, - mapSupplier - ); - } - - /** - * 创建一个收集器,对元素映射为 int 后生成统计信息。 - * - * @param mapper 映射函数 - * @param 元素类型 - * @return 收集器实例 - */ - public static Collector< - T, - ?, - @NotNull IntSummaryStatistics - > summarizingInt(@NotNull ToIntFunction mapper) { - return Collectors.summarizingInt(mapper); - } - - /** - * 创建一个收集器,对元素映射为 long 后生成统计信息。 - * - * @param mapper 映射函数 - * @param 元素类型 - * @return 收集器实例 - */ - public static Collector< - T, - ?, - @NotNull LongSummaryStatistics - > summarizingLong(@NotNull ToLongFunction mapper) { - return Collectors.summarizingLong(mapper); - } - - /** - * 创建一个收集器,对元素映射为 double 后生成统计信息。 - * - * @param mapper 映射函数 - * @param 元素类型 - * @return 收集器实例 - */ - public static Collector< - T, - ?, - @NotNull DoubleSummaryStatistics - > summarizingDouble(@NotNull ToDoubleFunction mapper) { - return Collectors.summarizingDouble(mapper); - } - - /** - * 创建一个包含指定元素的 CStream。 - * - * @param ts 可变参数,表示要包含在 CStream 中的元素 - * @param 元素类型 - * @return 包含指定元素的新 CStream 实例 - */ - @SafeVarargs - public static CStream of(T... ts) { - return new CStream<>(Lists.newArrayList(ts)); - } - - /** - * 创建一个包含指定列表元素的 CStream。 - * - * @param ts 列表,表示要包含在 CStream 中的元素 - * @param 元素类型 - * @return 包含指定元素的新 CStream 实例 - */ - public static CStream of(Collection ts) { - return new CStream<>(Lists.newArrayList(ts)); - } - - public static T getThis(T t) { - return t; - } - - /** - * 根据给定的谓词条件过滤流中的元素。 - * - * @param predicate 用于测试元素是否应保留的谓词函数 - * @return 包含满足条件元素的新 CStream 实例 - */ - @Override - public CStream filter(Predicate predicate) { - List result = Lists.newArrayList(); - for (T item : list) { - if (predicate.test(item)) { - result.add(item); - } - } - return new CStream<>(result); - } - - /** - * 根据属性提取器和目标值过滤流中的元素。 - * - * @param propertyExtractor 属性提取函数 - * @param targetValue 目标值 - * @return 包含满足条件元素的新 CStream 实例 - */ - public CStream filter( - Function propertyExtractor, - Object targetValue - ) { - List result = Lists.newArrayList(); - for (T item : list) { - if (Objects.equals(propertyExtractor.apply(item), targetValue)) { - result.add(item); - } - } - return new CStream<>(result); - } - - /** - * 将流中的每个元素通过映射函数转换为另一种类型。 - * - * @param mapper 映射函数,将元素从类型 T 转换为类型 R - * @param 映射后元素的类型 - * @return 包含转换后元素的新 CStream 实例 - */ - @Override - public CStream map(Function mapper) { - List result = Lists.newArrayList(); - for (T item : list) { - result.add(mapper.apply(item)); - } - return new CStream<>(result); - } - - /** - * 将流中的元素转换为数组。 - * - * @return 包含流中所有元素的数组 - */ - public T[] array() { - return (T[]) list.toArray(); - } - - /** - * 获取流中的元素列表。 - * - * @return 包含流中所有元素的列表 - */ - public List list() { - return list; - } - - /** - * 将流中的每个元素通过映射函数转换为 int 类型。 - * - * @param mapper 映射函数,将元素从类型 T 转换为 int - * @return 转换后的 IntStream 实例 - */ - @Override - public IntStream mapToInt(ToIntFunction mapper) { - return list.stream().mapToInt(mapper); - } - - /** - * 将流中的每个元素通过映射函数转换为 long 类型。 - * - * @param mapper 映射函数,将元素从类型 T 转换为 long - * @return 转换后的 LongStream 实例 - */ - @Override - public LongStream mapToLong(ToLongFunction mapper) { - return list.stream().mapToLong(mapper); - } - - /** - * 将流中的每个元素通过映射函数转换为 double 类型。 - * - * @param mapper 映射函数,将元素从类型 T 转换为 double - * @return 转换后的 DoubleStream 实例 - */ - @Override - public DoubleStream mapToDouble(ToDoubleFunction mapper) { - return list.stream().mapToDouble(mapper); - } - - /** - * 将流中的每个元素通过映射函数转换为另一个流,并将所有结果流合并为一个流。 - * - * @param mapper 映射函数,将元素从类型 T 转换为另一个 CStream - * @param 映射后流中元素的类型 - * @return 合并后的 CStream 实例 - */ - @Override - public CStream flatMap( - Function< - ? super T, - ? extends java.util.stream.Stream - > mapper - ) { - List result = Lists.newArrayList(); - for (T item : list) { - java.util.stream.Stream stream = mapper.apply(item); - if (stream != null) { - stream.forEach(result::add); - } - } - return new CStream<>(result); - } - - /** - * 将流中的每个元素通过映射函数转换为 IntStream,并将所有结果流合并为一个流。 - * - * @param mapper 映射函数,将元素从类型 T 转换为 IntStream - * @return 合并后的 IntStream 实例 - */ - @Override - public IntStream flatMapToInt( - Function mapper - ) { - return list.stream().flatMapToInt(mapper); - } - - /** - * 将流中的每个元素通过映射函数转换为 LongStream,并将所有结果流合并为一个流。 - * - * @param mapper 映射函数,将元素从类型 T 转换为 LongStream - * @return 合并后的 LongStream 实例 - */ - @Override - public LongStream flatMapToLong( - Function mapper - ) { - return list.stream().flatMapToLong(mapper); - } - - /** - * 将流中的每个元素通过映射函数转换为 DoubleStream,并将所有结果流合并为一个流。 - * - * @param mapper 映射函数,将元素从类型 T 转换为 DoubleStream - * @return 合并后的 DoubleStream 实例 - */ - @Override - public DoubleStream flatMapToDouble( - Function mapper - ) { - return list.stream().flatMapToDouble(mapper); - } - - /** - * 去除流中重复的元素,保持原有顺序。 - * - * @return 包含去重后元素的新 CStream 实例 - */ - @Override - public CStream distinct() { - Set seen = new LinkedHashSet<>(list); - return new CStream<>(new ArrayList<>(seen)); - } - - /** - * 对流中的元素进行自然排序。 - * - * @return 排序后的新 CStream 实例 - */ - @Override - public CStream sorted() { - List sortedList = Lists.newArrayList(list); - Collections.sort((List) sortedList); - return new CStream<>(sortedList); - } - - /** - * 根据给定的比较器对流中的元素进行排序。 - * - * @param comparator 用于比较元素的比较器 - * @return 排序后的新 CStream 实例 - */ - @Override - public CStream sorted(Comparator comparator) { - List sortedList = Lists.newArrayList(list); - sortedList.sort(comparator); - return new CStream<>(sortedList); - } - - /** - * 对流中的每个元素执行指定的操作,但不改变流本身。 - * - * @param action 要对每个元素执行的操作 - * @return 当前 CStream 实例 - */ - @Override - public CStream peek(Consumer action) { - for (T item : list) { - action.accept(item); - } - return this; - } - - /** - * 截取流中前 maxSize 个元素组成新的流。 - * - * @param maxSize 要截取的最大元素数量 - * @return 截取后的新 CStream 实例 - * @throws IllegalArgumentException 如果 maxSize 为负数 - */ - @Override - public CStream limit(long maxSize) { - if (maxSize < 0) { - throw new IllegalArgumentException("maxSize must be non-negative"); - } - if (maxSize == 0) { - return new CStream<>(Lists.newArrayList()); - } - - List limitedList = Lists.newArrayList(); - long count = 0; - for (T item : list) { - if (count >= maxSize) { - break; - } - limitedList.add(item); - count++; - } - return new CStream<>(limitedList); - } - - /** - * 跳过流中前 n 个元素,返回剩余元素组成的新流。 - * - * @param n 要跳过的元素数量 - * @return 跳过后的新 CStream 实例 - * @throws IllegalArgumentException 如果 n 为负数 - */ - @Override - public CStream skip(long n) { - if (n < 0) { - throw new IllegalArgumentException("n must be non-negative"); - } - if (n == 0) { - return new CStream<>(Lists.newArrayList(list)); - } - - List skippedList = Lists.newArrayList(); - long count = 0; - for (T item : list) { - if (count >= n) { - skippedList.add(item); - } - count++; - } - return new CStream<>(skippedList); - } - - /** - * 对流中的每个元素执行指定的操作。 - * - * @param action 要对每个元素执行的操作 - */ - @Override - public void forEach(Consumer action) { - ForEach.forEach(list, action); - } - - public void forEach( - com.mingliqiye.utils.collection.ForEach.Consumer action - ) { - ForEach.forEach(list, action); - } - - /** - * 按照元素出现的顺序对流中的每个元素执行指定的操作。 - * - * @param action 要对每个元素执行的操作 - */ - @Override - public void forEachOrdered(Consumer action) { - forEach(action); - } - - /** - * 将流中的元素转换为数组。 - * - * @return 包含流中所有元素的数组 - */ - @Override - public @NotNull Object@NotNull [] toArray() { - return list.toArray(); - } - - /** - * 使用指定的生成器函数将流中的元素转换为数组。 - * - * @param generator 用于生成目标数组的函数 - * @param 数组元素的类型 - * @return 包含流中所有元素的数组 - */ - @Override - public @NotNull A[] toArray(IntFunction generator) { - return list.toArray(generator.apply(list.size())); - } - - /** - * 使用指定的初始值和累积函数对流中的元素进行归约操作。 - * - * @param identity 初始值 - * @param accumulator 累积函数,用于将两个元素合并为一个 - * @return 归约后的结果 - */ - @Override - public T reduce(T identity, BinaryOperator accumulator) { - T result = identity; - for (T item : list) { - result = accumulator.apply(result, item); - } - return result; - } - - /** - * 使用指定的累积函数对流中的元素进行归约操作。 - * - * @param accumulator 累积函数,用于将两个元素合并为一个 - * @return 归约后的结果,如果流为空则返回空 Optional - */ - @Override - public @NotNull Optional reduce(BinaryOperator accumulator) { - if (list.isEmpty()) { - return Optional.empty(); - } - T result = list.get(0); - for (int i = 1; i < list.size(); i++) { - result = accumulator.apply(result, list.get(i)); - } - return Optional.of(result); - } - - /** - * 使用指定的初始值、累积函数和组合函数对流中的元素进行归约操作。 - * - * @param identity 初始值 - * @param accumulator 累积函数,用于将元素与累积值合并 - * @param combiner 组合函数,用于合并两个累积值 - * @param 累积值的类型 - * @return 归约后的结果 - */ - @Override - public U reduce( - U identity, - BiFunction accumulator, - BinaryOperator combiner - ) { - U result = identity; - for (T item : list) { - result = accumulator.apply(result, item); - } - return result; - } - - /** - * 使用指定的收集器将流中的元素收集到容器中。 - * - * @param supplier 用于创建容器的函数 - * @param accumulator 用于将元素添加到容器的函数 - * @param combiner 用于合并两个容器的函数 - * @param 容器的类型 - * @return 收集后的结果 - */ - @Override - public R collect( - Supplier supplier, - BiConsumer accumulator, - BiConsumer combiner - ) { - R result = supplier.get(); - for (T item : list) { - accumulator.accept(result, item); - } - return result; - } - - @Override - public String toString() { - if (list.isEmpty()) { - return "CStream()"; - } - StringBuilder sb = new StringBuilder(); - sb.append("CStream("); - forEach((item, index) -> { - sb.append(item); - if (index != list.size() - 1) { - sb.append(", "); - } else { - sb.append(")"); - } - }); - return sb.toString(); - } - - /** - * 使用指定的收集器将流中的元素收集到容器中。 - * - * @param collector 收集器,定义了如何收集元素 - * @param 收集结果的类型 - * @param 容器中元素的类型 - * @return 收集后的结果 - */ - @Override - public R collect(Collector collector) { - A container = collector.supplier().get(); - for (T item : list) { - collector.accumulator().accept(container, item); - } - return collector.finisher().apply(container); - } - - /** - * 根据给定的比较器找出流中的最小元素。 - * - * @param comparator 用于比较元素的比较器 - * @return 包含最小元素的 Optional,如果流为空则返回空 Optional - */ - @Override - public @NotNull Optional min(Comparator comparator) { - if (list.isEmpty()) { - return Optional.empty(); - } - T min = list.get(0); - for (int i = 1; i < list.size(); i++) { - T current = list.get(i); - if (comparator.compare(current, min) < 0) { - min = current; - } - } - return Optional.of(min); - } - - /** - * 根据给定的比较器找出流中的最大元素。 - * - * @param comparator 用于比较元素的比较器 - * @return 包含最大元素的 Optional,如果流为空则返回空 Optional - */ - @Override - public @NotNull Optional max(Comparator comparator) { - if (list.isEmpty()) { - return Optional.empty(); - } - T max = list.get(0); - for (int i = 1; i < list.size(); i++) { - T current = list.get(i); - if (comparator.compare(current, max) > 0) { - max = current; - } - } - return Optional.of(max); - } - - /** - * 返回流中元素的数量。 - * - * @return 元素数量 - */ - @Override - public long count() { - return list.size(); - } - - /** - * 检查流中是否有至少一个元素满足给定的谓词条件。 - * - * @param predicate 用于测试元素的谓词函数 - * @return 如果有至少一个元素满足条件则返回 true,否则返回 false - */ - @Override - public boolean anyMatch(Predicate predicate) { - for (T item : list) { - if (predicate.test(item)) { - return true; - } - } - return false; - } - - /** - * 检查流中是否所有元素都满足给定的谓词条件。 - * - * @param predicate 用于测试元素的谓词函数 - * @return 如果所有元素都满足条件则返回 true,否则返回 false - */ - @Override - public boolean allMatch(Predicate predicate) { - for (T item : list) { - if (!predicate.test(item)) { - return false; - } - } - return true; - } - - /** - * 检查流中是否没有任何元素满足给定的谓词条件。 - * - * @param predicate 用于测试元素的谓词函数 - * @return 如果没有任何元素满足条件则返回 true,否则返回 false - */ - @Override - public boolean noneMatch(Predicate predicate) { - return !anyMatch(predicate); - } - - /** - * 获取流中的第一个元素。 - * - * @return 包含第一个元素的 Optional,如果流为空则返回空 Optional - */ - @Override - public @NotNull Optional findFirst() { - return list.isEmpty() ? Optional.empty() : Optional.of(list.get(0)); - } - - /** - * 获取流中的最后一个元素。 - * - * @return 包含最后一个元素的 Optional,如果流为空则返回空 Optional - */ - public @NotNull Optional findEnd() { - return list.isEmpty() - ? Optional.empty() - : Optional.of(list.get(list.size() - 1)); - } - - /** - * 获取流中的任意一个元素。 - * - * @return 包含任意一个元素的 Optional,如果流为空则返回空 Optional - */ - @Override - public @NotNull Optional findAny() { - if (list.size() == 1) { - return Optional.of(list.get(0)); - } else { - return list.isEmpty() - ? Optional.empty() - : Optional.of( - list.get(RandomInt.randomInt(0, list.size() - 1)) - ); - } - } - - /** - * 返回流中元素的迭代器。 - * - * @return 元素迭代器 - */ - @Override - public @NotNull Iterator iterator() { - return list.iterator(); - } - - /** - * 返回流中元素的 Spliterator。 - * - * @return 元素 Spliterator - */ - @Override - public @NotNull Spliterator spliterator() { - return list.spliterator(); - } - - /** - * 检查当前流是否为并行流。 - * - * @return 如果是并行流则返回 true,否则返回 false - */ - @Override - public boolean isParallel() { - return false; - } - - /** - * 返回当前流的顺序版本。 - * - * @return 当前流的顺序版本 - */ - @Override - public @NotNull CStream sequential() { - return this; - } - - /** - * 返回当前流的并行版本。 - * - * @return 当前流的并行版本 - */ - @Override - public @NotNull CStream parallel() { - return new CStream<>(list); - } - - /** - * 返回当前流的无序版本。 - * - * @return 当前流的无序版本 - */ - @Override - public @NotNull CStream unordered() { - return this; - } - - /** - * 注册一个关闭处理器,在流关闭时执行。 - * - * @param closeHandler 关闭处理器 - * @return 当前 CStream 实例 - */ - @Override - public @NotNull CStream onClose(@NotNull Runnable closeHandler) { - return this; - } - - /** - * 关闭流。 - */ - @Override - public void close() { - list.clear(); - } -} diff --git a/src/com/mingliqiye/utils/Main.java b/src/main/java/com/mingliqiye/utils/Main.java similarity index 78% rename from src/com/mingliqiye/utils/Main.java rename to src/main/java/com/mingliqiye/utils/Main.java index 97a3fd9..6af2552 100644 --- a/src/com/mingliqiye/utils/Main.java +++ b/src/main/java/com/mingliqiye/utils/Main.java @@ -22,12 +22,21 @@ package com.mingliqiye.utils; +import com.mingliqiye.utils.collection.Lists; +import com.mingliqiye.utils.collection.Maps; import com.mingliqiye.utils.springboot.autoconfigure.AutoConfiguration; +import com.mingliqiye.utils.stream.SuperStream; import java.io.IOException; +import java.util.List; +import java.util.Map; public class Main { public static void main(String[] args) throws IOException { AutoConfiguration.printBanner(); + + Map map = Maps.of("1", "2", "3", "4"); + + SuperStream.of(map).entryToMap(); } } diff --git a/src/com/mingliqiye/utils/aes/AesUtils.java b/src/main/java/com/mingliqiye/utils/aes/AesUtils.java similarity index 100% rename from src/com/mingliqiye/utils/aes/AesUtils.java rename to src/main/java/com/mingliqiye/utils/aes/AesUtils.java diff --git a/src/com/mingliqiye/utils/base64/Base64Utils.java b/src/main/java/com/mingliqiye/utils/base64/Base64Utils.java similarity index 100% rename from src/com/mingliqiye/utils/base64/Base64Utils.java rename to src/main/java/com/mingliqiye/utils/base64/Base64Utils.java diff --git a/src/com/mingliqiye/utils/bean/Factory.java b/src/main/java/com/mingliqiye/utils/bean/Factory.java similarity index 100% rename from src/com/mingliqiye/utils/bean/Factory.java rename to src/main/java/com/mingliqiye/utils/bean/Factory.java diff --git a/src/com/mingliqiye/utils/bean/annotation/ComponentBean.java b/src/main/java/com/mingliqiye/utils/bean/annotation/ComponentBean.java similarity index 100% rename from src/com/mingliqiye/utils/bean/annotation/ComponentBean.java rename to src/main/java/com/mingliqiye/utils/bean/annotation/ComponentBean.java diff --git a/src/com/mingliqiye/utils/bean/annotation/InjectBean.java b/src/main/java/com/mingliqiye/utils/bean/annotation/InjectBean.java similarity index 100% rename from src/com/mingliqiye/utils/bean/annotation/InjectBean.java rename to src/main/java/com/mingliqiye/utils/bean/annotation/InjectBean.java diff --git a/src/com/mingliqiye/utils/bean/springboot/SpringBeanUtil.java b/src/main/java/com/mingliqiye/utils/bean/springboot/SpringBeanUtil.java similarity index 100% rename from src/com/mingliqiye/utils/bean/springboot/SpringBeanUtil.java rename to src/main/java/com/mingliqiye/utils/bean/springboot/SpringBeanUtil.java diff --git a/src/com/mingliqiye/utils/bytes/ByteUtil.java b/src/main/java/com/mingliqiye/utils/bytes/ByteUtil.java similarity index 100% rename from src/com/mingliqiye/utils/bytes/ByteUtil.java rename to src/main/java/com/mingliqiye/utils/bytes/ByteUtil.java diff --git a/src/com/mingliqiye/utils/callback/P10Function.java b/src/main/java/com/mingliqiye/utils/callback/P10Function.java similarity index 100% rename from src/com/mingliqiye/utils/callback/P10Function.java rename to src/main/java/com/mingliqiye/utils/callback/P10Function.java diff --git a/src/com/mingliqiye/utils/callback/P10RFunction.java b/src/main/java/com/mingliqiye/utils/callback/P10RFunction.java similarity index 100% rename from src/com/mingliqiye/utils/callback/P10RFunction.java rename to src/main/java/com/mingliqiye/utils/callback/P10RFunction.java diff --git a/src/com/mingliqiye/utils/callback/P1Function.java b/src/main/java/com/mingliqiye/utils/callback/P1Function.java similarity index 100% rename from src/com/mingliqiye/utils/callback/P1Function.java rename to src/main/java/com/mingliqiye/utils/callback/P1Function.java diff --git a/src/com/mingliqiye/utils/callback/P1RFunction.java b/src/main/java/com/mingliqiye/utils/callback/P1RFunction.java similarity index 100% rename from src/com/mingliqiye/utils/callback/P1RFunction.java rename to src/main/java/com/mingliqiye/utils/callback/P1RFunction.java diff --git a/src/com/mingliqiye/utils/callback/P2Function.java b/src/main/java/com/mingliqiye/utils/callback/P2Function.java similarity index 100% rename from src/com/mingliqiye/utils/callback/P2Function.java rename to src/main/java/com/mingliqiye/utils/callback/P2Function.java diff --git a/src/com/mingliqiye/utils/callback/P2RFunction.java b/src/main/java/com/mingliqiye/utils/callback/P2RFunction.java similarity index 100% rename from src/com/mingliqiye/utils/callback/P2RFunction.java rename to src/main/java/com/mingliqiye/utils/callback/P2RFunction.java diff --git a/src/com/mingliqiye/utils/callback/P3Function.java b/src/main/java/com/mingliqiye/utils/callback/P3Function.java similarity index 100% rename from src/com/mingliqiye/utils/callback/P3Function.java rename to src/main/java/com/mingliqiye/utils/callback/P3Function.java diff --git a/src/com/mingliqiye/utils/callback/P3RFunction.java b/src/main/java/com/mingliqiye/utils/callback/P3RFunction.java similarity index 100% rename from src/com/mingliqiye/utils/callback/P3RFunction.java rename to src/main/java/com/mingliqiye/utils/callback/P3RFunction.java diff --git a/src/com/mingliqiye/utils/callback/P4Function.java b/src/main/java/com/mingliqiye/utils/callback/P4Function.java similarity index 100% rename from src/com/mingliqiye/utils/callback/P4Function.java rename to src/main/java/com/mingliqiye/utils/callback/P4Function.java diff --git a/src/com/mingliqiye/utils/callback/P4RFunction.java b/src/main/java/com/mingliqiye/utils/callback/P4RFunction.java similarity index 100% rename from src/com/mingliqiye/utils/callback/P4RFunction.java rename to src/main/java/com/mingliqiye/utils/callback/P4RFunction.java diff --git a/src/com/mingliqiye/utils/callback/P5Function.java b/src/main/java/com/mingliqiye/utils/callback/P5Function.java similarity index 100% rename from src/com/mingliqiye/utils/callback/P5Function.java rename to src/main/java/com/mingliqiye/utils/callback/P5Function.java diff --git a/src/com/mingliqiye/utils/callback/P5RFunction.java b/src/main/java/com/mingliqiye/utils/callback/P5RFunction.java similarity index 100% rename from src/com/mingliqiye/utils/callback/P5RFunction.java rename to src/main/java/com/mingliqiye/utils/callback/P5RFunction.java diff --git a/src/com/mingliqiye/utils/callback/P6Function.java b/src/main/java/com/mingliqiye/utils/callback/P6Function.java similarity index 100% rename from src/com/mingliqiye/utils/callback/P6Function.java rename to src/main/java/com/mingliqiye/utils/callback/P6Function.java diff --git a/src/com/mingliqiye/utils/callback/P6RFunction.java b/src/main/java/com/mingliqiye/utils/callback/P6RFunction.java similarity index 100% rename from src/com/mingliqiye/utils/callback/P6RFunction.java rename to src/main/java/com/mingliqiye/utils/callback/P6RFunction.java diff --git a/src/com/mingliqiye/utils/callback/P7Function.java b/src/main/java/com/mingliqiye/utils/callback/P7Function.java similarity index 100% rename from src/com/mingliqiye/utils/callback/P7Function.java rename to src/main/java/com/mingliqiye/utils/callback/P7Function.java diff --git a/src/com/mingliqiye/utils/callback/P7RFunction.java b/src/main/java/com/mingliqiye/utils/callback/P7RFunction.java similarity index 100% rename from src/com/mingliqiye/utils/callback/P7RFunction.java rename to src/main/java/com/mingliqiye/utils/callback/P7RFunction.java diff --git a/src/com/mingliqiye/utils/callback/P8Function.java b/src/main/java/com/mingliqiye/utils/callback/P8Function.java similarity index 100% rename from src/com/mingliqiye/utils/callback/P8Function.java rename to src/main/java/com/mingliqiye/utils/callback/P8Function.java diff --git a/src/com/mingliqiye/utils/callback/P8RFunction.java b/src/main/java/com/mingliqiye/utils/callback/P8RFunction.java similarity index 100% rename from src/com/mingliqiye/utils/callback/P8RFunction.java rename to src/main/java/com/mingliqiye/utils/callback/P8RFunction.java diff --git a/src/com/mingliqiye/utils/callback/P9Function.java b/src/main/java/com/mingliqiye/utils/callback/P9Function.java similarity index 100% rename from src/com/mingliqiye/utils/callback/P9Function.java rename to src/main/java/com/mingliqiye/utils/callback/P9Function.java diff --git a/src/com/mingliqiye/utils/callback/P9RFunction.java b/src/main/java/com/mingliqiye/utils/callback/P9RFunction.java similarity index 100% rename from src/com/mingliqiye/utils/callback/P9RFunction.java rename to src/main/java/com/mingliqiye/utils/callback/P9RFunction.java diff --git a/src/com/mingliqiye/utils/clone/CloneUtil.java b/src/main/java/com/mingliqiye/utils/clone/CloneUtil.java similarity index 100% rename from src/com/mingliqiye/utils/clone/CloneUtil.java rename to src/main/java/com/mingliqiye/utils/clone/CloneUtil.java diff --git a/src/com/mingliqiye/utils/collection/Collection.java b/src/main/java/com/mingliqiye/utils/collection/Collection.java similarity index 100% rename from src/com/mingliqiye/utils/collection/Collection.java rename to src/main/java/com/mingliqiye/utils/collection/Collection.java diff --git a/src/com/mingliqiye/utils/collection/ForEach.java b/src/main/java/com/mingliqiye/utils/collection/ForEach.java similarity index 100% rename from src/com/mingliqiye/utils/collection/ForEach.java rename to src/main/java/com/mingliqiye/utils/collection/ForEach.java diff --git a/src/com/mingliqiye/utils/collection/Lists.java b/src/main/java/com/mingliqiye/utils/collection/Lists.java similarity index 99% rename from src/com/mingliqiye/utils/collection/Lists.java rename to src/main/java/com/mingliqiye/utils/collection/Lists.java index 5855766..790ac54 100644 --- a/src/com/mingliqiye/utils/collection/Lists.java +++ b/src/main/java/com/mingliqiye/utils/collection/Lists.java @@ -282,9 +282,7 @@ public class Lists { return null; } T[] items = (T[]) new Object[ts.size()]; - ForEach.forEach(ts, (t, i) -> { - items[i] = t; - }); + ForEach.forEach(ts, (t, i) -> items[i] = t); return items; } diff --git a/src/com/mingliqiye/utils/collection/Maps.java b/src/main/java/com/mingliqiye/utils/collection/Maps.java similarity index 99% rename from src/com/mingliqiye/utils/collection/Maps.java rename to src/main/java/com/mingliqiye/utils/collection/Maps.java index 6a5a703..696ff40 100644 --- a/src/com/mingliqiye/utils/collection/Maps.java +++ b/src/main/java/com/mingliqiye/utils/collection/Maps.java @@ -15974,4 +15974,12 @@ public class Maps { } return map; } + + public static Map ofEntries(List> entries) { + var map = new HashMap(entries.size() + 2); + for (Map.Entry entry : entries) { + map.put(entry.getKey(), entry.getValue()); + } + return map; + } } diff --git a/src/com/mingliqiye/utils/collection/Sets.java b/src/main/java/com/mingliqiye/utils/collection/Sets.java similarity index 100% rename from src/com/mingliqiye/utils/collection/Sets.java rename to src/main/java/com/mingliqiye/utils/collection/Sets.java diff --git a/src/com/mingliqiye/utils/concurrent/IsChanged.java b/src/main/java/com/mingliqiye/utils/concurrent/IsChanged.java similarity index 100% rename from src/com/mingliqiye/utils/concurrent/IsChanged.java rename to src/main/java/com/mingliqiye/utils/concurrent/IsChanged.java diff --git a/src/com/mingliqiye/utils/data/ThreadLocalDataHolder.java b/src/main/java/com/mingliqiye/utils/data/ThreadLocalDataHolder.java similarity index 100% rename from src/com/mingliqiye/utils/data/ThreadLocalDataHolder.java rename to src/main/java/com/mingliqiye/utils/data/ThreadLocalDataHolder.java diff --git a/src/com/mingliqiye/utils/file/FileUtil.java b/src/main/java/com/mingliqiye/utils/file/FileUtil.java similarity index 99% rename from src/com/mingliqiye/utils/file/FileUtil.java rename to src/main/java/com/mingliqiye/utils/file/FileUtil.java index 9344a34..b298e71 100644 --- a/src/com/mingliqiye/utils/file/FileUtil.java +++ b/src/main/java/com/mingliqiye/utils/file/FileUtil.java @@ -103,7 +103,9 @@ public class FileUtil { Charset charset ) throws IOException { Path path = Paths.get(filePath); - Files.createDirectories(path.getParent()); + if (path.getParent() != null) { + Files.createDirectories(path.getParent()); + } Files.write(path, content.getBytes(charset)); } diff --git a/src/com/mingliqiye/utils/functions/Debouncer.java b/src/main/java/com/mingliqiye/utils/functions/Debouncer.java similarity index 100% rename from src/com/mingliqiye/utils/functions/Debouncer.java rename to src/main/java/com/mingliqiye/utils/functions/Debouncer.java diff --git a/src/com/mingliqiye/utils/hash/HashUtils.java b/src/main/java/com/mingliqiye/utils/hash/HashUtils.java similarity index 100% rename from src/com/mingliqiye/utils/hash/HashUtils.java rename to src/main/java/com/mingliqiye/utils/hash/HashUtils.java diff --git a/src/com/mingliqiye/utils/http/Response.java b/src/main/java/com/mingliqiye/utils/http/Response.java similarity index 100% rename from src/com/mingliqiye/utils/http/Response.java rename to src/main/java/com/mingliqiye/utils/http/Response.java diff --git a/src/com/mingliqiye/utils/jackson/Serializers.java b/src/main/java/com/mingliqiye/utils/jackson/Serializers.java similarity index 100% rename from src/com/mingliqiye/utils/jackson/Serializers.java rename to src/main/java/com/mingliqiye/utils/jackson/Serializers.java diff --git a/src/com/mingliqiye/utils/jna/FieldStructure.java b/src/main/java/com/mingliqiye/utils/jna/FieldStructure.java similarity index 100% rename from src/com/mingliqiye/utils/jna/FieldStructure.java rename to src/main/java/com/mingliqiye/utils/jna/FieldStructure.java diff --git a/src/com/mingliqiye/utils/jna/time/WinKernel32.java b/src/main/java/com/mingliqiye/utils/jna/time/WinKernel32.java similarity index 100% rename from src/com/mingliqiye/utils/jna/time/WinKernel32.java rename to src/main/java/com/mingliqiye/utils/jna/time/WinKernel32.java diff --git a/src/com/mingliqiye/utils/json/JacksonJsonApi.java b/src/main/java/com/mingliqiye/utils/json/JacksonJsonApi.java similarity index 89% rename from src/com/mingliqiye/utils/json/JacksonJsonApi.java rename to src/main/java/com/mingliqiye/utils/json/JacksonJsonApi.java index f99dd90..67830e0 100644 --- a/src/com/mingliqiye/utils/json/JacksonJsonApi.java +++ b/src/main/java/com/mingliqiye/utils/json/JacksonJsonApi.java @@ -22,6 +22,7 @@ package com.mingliqiye.utils.json; +import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -51,7 +52,7 @@ public class JacksonJsonApi implements JsonApi { * @param objectMapper 自定义的ObjectMapper实例 */ public JacksonJsonApi(ObjectMapper objectMapper) { - this.objectMapper = objectMapper; + this.objectMapper = objectMapper.copy(); } /** @@ -112,6 +113,18 @@ public class JacksonJsonApi implements JsonApi { } } + @Override + public String formatUnicode(Object object) { + try { + return objectMapper + .writer() + .with(JsonGenerator.Feature.ESCAPE_NON_ASCII) + .writeValueAsString(object); + } catch (JsonProcessingException e) { + throw new JsonException(e); + } + } + /** * 将对象格式化为美化(带缩进)的JSON字符串 * @@ -133,6 +146,21 @@ public class JacksonJsonApi implements JsonApi { } } + @Override + public String formatPrettyUnicode(Object object) { + try { + return objectMapper + .writerWithDefaultPrettyPrinter() + .with(JsonGenerator.Feature.ESCAPE_NON_ASCII) + .writeValueAsString(object); + } catch (JsonProcessingException e) { + throw new JsonException( + "Failed to format object to pretty JSON string", + e + ); + } + } + /** * 将JSON字符串解析为指定元素类型的List * @@ -283,10 +311,10 @@ public class JacksonJsonApi implements JsonApi { /** * 在不同对象类型之间进行转换 * - * @param source 源对象 - * @param destinationClass 目标对象类型 - * @param 源对象类型 - * @param 目标对象类型 + * @param source 源对象 + * @param destinationClass 目标对象类型 + * @param 源对象类型 + * @param 目标对象类型 * @return 转换后的对象 */ @Override @@ -297,10 +325,10 @@ public class JacksonJsonApi implements JsonApi { /** * 在不同泛型对象类型之间进行转换 * - * @param source 源对象 - * @param destinationType 目标对象的泛型类型引用 - * @param 源对象类型 - * @param 目标对象类型 + * @param source 源对象 + * @param destinationType 目标对象的泛型类型引用 + * @param 源对象类型 + * @param 目标对象类型 * @return 转换后的对象 */ @Override diff --git a/src/main/java/com/mingliqiye/utils/json/JsonApi.java b/src/main/java/com/mingliqiye/utils/json/JsonApi.java new file mode 100644 index 0000000..c487bad --- /dev/null +++ b/src/main/java/com/mingliqiye/utils/json/JsonApi.java @@ -0,0 +1,393 @@ +/* + * Copyright 2025 mingliqiye + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ProjectName mingli-utils + * ModuleName mingli-utils.main + * CurrentFile JsonApi.java + * LastUpdate 2025-09-09 09:22:02 + * UpdateUser MingLiPro + */ + +package com.mingliqiye.utils.json; + +import com.mingliqiye.utils.collection.Maps; +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Map; + +/** + * JSON处理接口,提供JSON字符串与Java对象之间的相互转换功能 + */ +public interface JsonApi { + final Map UNICODE_BIND = Maps.of("1", ""); + + /** + * 将JSON字符串解析为指定类型的对象 + * + * @param json 待解析的JSON字符串 + * @param clazz 目标对象的Class类型 + * @param 泛型参数,表示目标对象的类型 + * @return 解析后的对象实例 + */ + T parse(String json, Class clazz); + + /** + * 将JSON字符串解析为指定泛型类型对象 + * + * @param json 待解析的JSON字符串 + * @param type 目标对象的Type类型(支持泛型) + * @param 泛型参数,表示目标对象的类型 + * @return 解析后的对象实例 + */ + T parse(String json, JsonTypeReference type); + + /** + * 将对象格式化为JSON字符串 + * + * @param object 待格式化的对象 + * @return 格式化后的JSON字符串 + */ + String format(Object object); + + String formatUnicode(Object object); + + default T parseFrom(String path, Class clazz) throws IOException { + return parseFrom(Paths.get(path), clazz); + } + + default T parseFrom(Path path, Class clazz) throws IOException { + return parseFrom(path.toFile(), clazz); + } + + default T parseFrom(File file, Class clazz) throws IOException { + try (InputStream inputStream = Files.newInputStream(file.toPath())) { + return parseFrom(inputStream, clazz); + } + } + + default T parseFrom(InputStream inputStream, Class clazz) + throws IOException { + if (inputStream == null) { + throw new IllegalArgumentException("inputStream cannot be null"); + } + if (clazz == null) { + throw new IllegalArgumentException("clazz cannot be null"); + } + byte[] bytes = new byte[1024]; + try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) { + int readlength; + while ((readlength = inputStream.read(bytes)) != -1) { + bos.write(bytes, 0, readlength); + } + return parse(bos.toByteArray(), clazz); + } + } + + default T parseFrom(String path, JsonTypeReference type) + throws IOException { + return parseFrom(Paths.get(path), type); + } + + default T parseFrom(Path path, JsonTypeReference type) + throws IOException { + return parseFrom(path.toFile(), type); + } + + default T parseFrom(File file, JsonTypeReference type) + throws IOException { + try (InputStream inputStream = Files.newInputStream(file.toPath())) { + return parseFrom(inputStream, type); + } + } + + default T parseFrom(InputStream inputStream, JsonTypeReference type) + throws IOException { + if (inputStream == null) { + throw new IllegalArgumentException("inputStream cannot be null"); + } + if (type == null) { + throw new IllegalArgumentException("type cannot be null"); + } + byte[] bytes = new byte[1024]; + try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) { + int readlength; + while ((readlength = inputStream.read(bytes)) != -1) { + bos.write(bytes, 0, readlength); + } + return parse(bos.toByteArray(), type); + } + } + + /** + * 将字节数组形式的JSON解析为指定类型的对象 + * + * @param json 待解析的JSON字节数组 + * @param clazz 目标对象的Class类型 + * @param 泛型参数,表示目标对象的类型 + * @return 解析后的对象实例 + */ + default T parse(byte[] json, Class clazz) { + return parse(new String(json), clazz); + } + + /** + * 将字节数组形式的JSON解析为指定泛型类型对象 + * + * @param json 待解析的JSON字节数组 + * @param type 目标对象的Type类型(支持泛型) + * @param 泛型参数,表示目标对象的类型 + * @return 解析后的对象实例 + */ + default T parse(byte[] json, JsonTypeReference type) { + return parse(new String(json), type); + } + + /** + * 将JSON字符串解析为指定类型的对象,解析失败时返回默认值 + * + * @param json 待解析的JSON字符串 + * @param clazz 目标对象的Class类型 + * @param defaultValue 解析失败时返回的默认值 + * @param 泛型参数,表示目标对象的类型 + * @return 解析后的对象实例或默认值 + */ + default T parse(String json, Class clazz, T defaultValue) { + try { + return parse(json, clazz); + } catch (Exception e) { + return defaultValue; + } + } + + /** + * 将JSON字符串解析为指定泛型类型对象,解析失败时返回默认值 + * + * @param json 待解析的JSON字符串 + * @param type 目标对象的Type类型(支持泛型) + * @param defaultValue 解析失败时返回的默认值 + * @param 泛型参数,表示目标对象的类型 + * @return 解析后的对象实例或默认值 + */ + default T parse( + String json, + JsonTypeReference type, + T defaultValue + ) { + try { + return parse(json, type); + } catch (Exception e) { + return defaultValue; + } + } + + /** + * 将对象格式化为美化格式的JSON字符串(带缩进和换行) + * + * @param object 待格式化的对象 + * @return 格式化后的美化JSON字符串 + */ + String formatPretty(Object object); + + default byte[] formatPrettyBytes(Object object) { + return formatPretty(object).getBytes(); + } + + String formatPrettyUnicode(Object object); + + default byte[] formatPrettyUnicodeBytes(Object object) { + return formatPrettyUnicode(object).getBytes(); + } + + default void formatPretty(Object object, String file) throws IOException { + formatPretty(object, Paths.get(file)); + } + + default void formatPretty(Object object, Path file) throws IOException { + formatPretty(object, file.toFile()); + } + + default void formatPretty(Object object, File file) throws IOException { + try (FileOutputStream fos = new FileOutputStream(file)) { + formatPretty(object, fos); + } + } + + default void formatPretty(Object object, OutputStream stream) + throws IOException { + stream.write(formatPrettyBytes(object)); + } + + default void formatPrettyUnicode(Object object, String file) + throws IOException { + formatPrettyUnicode(object, Paths.get(file)); + } + + default void formatPrettyUnicode(Object object, Path file) + throws IOException { + formatPrettyUnicode(object, file.toFile()); + } + + default void formatPrettyUnicode(Object object, File file) + throws IOException { + try (FileOutputStream fos = new FileOutputStream(file)) { + formatPrettyUnicode(object, fos); + } + } + + default void formatPrettyUnicode(Object object, OutputStream stream) + throws IOException { + stream.write(formatPrettyUnicodeBytes(object)); + } + + default byte[] formatBytes(Object object) { + return format(object).getBytes(); + } + + default byte[] formatUnicodeBytes(Object object) { + return formatUnicode(object).getBytes(); + } + + default void format(Object object, String file) throws IOException { + format(object, Paths.get(file)); + } + + default void format(Object object, Path file) throws IOException { + format(object, file.toFile()); + } + + default void format(Object object, File file) throws IOException { + try (FileOutputStream fos = new FileOutputStream(file)) { + format(object, fos); + } + } + + default void format(Object object, OutputStream stream) throws IOException { + stream.write(formatPrettyBytes(object)); + } + + default void formatUnicode(Object object, String file) throws IOException { + formatUnicode(object, Paths.get(file)); + } + + default void formatUnicode(Object object, Path file) throws IOException { + formatUnicode(object, file.toFile()); + } + + default void formatUnicode(Object object, File file) throws IOException { + try (FileOutputStream fos = new FileOutputStream(file)) { + formatUnicode(object, fos); + } + } + + default void formatUnicode(Object object, OutputStream stream) + throws IOException { + stream.write(formatPrettyUnicodeBytes(object)); + } + + /** + * 将JSON字符串解析为指定元素类型的List集合 + * + * @param json 待解析的JSON字符串 + * @param elementType List中元素的类型 + * @param 泛型参数,表示List中元素的类型 + * @return 解析后的List集合 + */ + default List parseList(String json, Class elementType) { + return parse(json, JsonTypeUtils.listType(elementType)); + } + + /** + * 将JSON字符串解析为指定键值类型的Map集合 + * + * @param json 待解析的JSON字符串 + * @param keyType Map中键的类型 + * @param valueType Map中值的类型 + * @param 泛型参数,表示Map中键的类型 + * @param 泛型参数,表示Map中值的类型 + * @return 解析后的Map集合 + */ + default Map parseMap( + String json, + Class keyType, + Class valueType + ) { + JsonTypeReference> mapType = new JsonTypeReference< + Map + >() {}; + return parse(json, mapType); + } + + /** + * 验证字符串是否为有效的JSON格式 + * + * @param json 待验证的字符串 + * @return 如果是有效的JSON格式返回true,否则返回false + */ + boolean isValidJson(String json); + + /** + * 将对象转换为JSON字节数组 + * + * @param object 待转换的对象 + * @return 转换后的JSON字节数组 + */ + default byte[] toBytes(Object object) { + return format(object).getBytes(); + } + + /** + * 将对象转换为美化格式的JSON字节数组 + * + * @param object 待转换的对象 + * @return 转换后的美化格式JSON字节数组 + */ + default byte[] toBytesPretty(Object object) { + return formatPretty(object).getBytes(); + } + + /** + * 合并多个JSON字符串为一个JSON对象 + * + * @param jsons 待合并的JSON字符串数组 + * @return 合并后的JSON字符串 + */ + String merge(String... jsons); + + /** + * 获取JSON字符串中指定路径节点的值 + * + * @param json JSON字符串 + * @param path 节点路径(如:"user.name") + * @return 节点值的字符串表示 + */ + String getNodeValue(String json, String path); + + /** + * 更新JSON字符串中指定路径节点的值 + * + * @param json 原始JSON字符串 + * @param path 节点路径(如:"user.name") + * @param newValue 新的节点值 + * @return 更新后的JSON字符串 + */ + String updateNodeValue(String json, String path, Object newValue); + + D convert(T source, Class destinationClass); + + D convert(T source, JsonTypeReference destinationType); +} diff --git a/src/com/mingliqiye/utils/json/JsonException.java b/src/main/java/com/mingliqiye/utils/json/JsonException.java similarity index 92% rename from src/com/mingliqiye/utils/json/JsonException.java rename to src/main/java/com/mingliqiye/utils/json/JsonException.java index be1b16c..f53aea3 100644 --- a/src/com/mingliqiye/utils/json/JsonException.java +++ b/src/main/java/com/mingliqiye/utils/json/JsonException.java @@ -31,4 +31,8 @@ public class JsonException extends RuntimeException { public JsonException(String message, Throwable cause) { super(message, cause); } + + public JsonException(Throwable cause) { + this(cause.getMessage(), cause); + } } diff --git a/src/com/mingliqiye/utils/json/JsonTypeReference.java b/src/main/java/com/mingliqiye/utils/json/JsonTypeReference.java similarity index 100% rename from src/com/mingliqiye/utils/json/JsonTypeReference.java rename to src/main/java/com/mingliqiye/utils/json/JsonTypeReference.java diff --git a/src/com/mingliqiye/utils/json/JsonTypeUtils.java b/src/main/java/com/mingliqiye/utils/json/JsonTypeUtils.java similarity index 100% rename from src/com/mingliqiye/utils/json/JsonTypeUtils.java rename to src/main/java/com/mingliqiye/utils/json/JsonTypeUtils.java diff --git a/src/main/java/com/mingliqiye/utils/minecraft/pe/json/Pseudocryptography.java b/src/main/java/com/mingliqiye/utils/minecraft/pe/json/Pseudocryptography.java new file mode 100644 index 0000000..7067fa1 --- /dev/null +++ b/src/main/java/com/mingliqiye/utils/minecraft/pe/json/Pseudocryptography.java @@ -0,0 +1,57 @@ +package com.mingliqiye.utils.minecraft.pe.json; + +import com.mingliqiye.utils.collection.ForEach; +import com.mingliqiye.utils.file.FileUtil; +import com.mingliqiye.utils.json.JsonApi; +import com.mingliqiye.utils.json.JsonTypeReference; +import com.mingliqiye.utils.string.StringUtil; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import lombok.val; + +public class Pseudocryptography { + + private final JsonApi jsonApi; + + public Pseudocryptography(JsonApi jsonApi) { + this.jsonApi = jsonApi; + } + + private Object prossed(Object object) { + if (object instanceof Map) { + System.out.println(object.getClass()); + val map = new HashMap<>((Map) object); + val map2 = new HashMap<>(map.size() + 3); + map.forEach((key, value) -> { + if (key instanceof String) { + map2.put(prossed(key), prossed(value)); + } + }); + + return map2; + } else if (object instanceof String) { + return StringUtil.stringToUnicode((String) object); + } else if (object instanceof List) { + ForEach.forEach((List) object, (t, i) -> { + ((List) object).set(i, prossed(t)); + }); + } + return object; + } + + public void decode(String path) { + try { + final Map map = jsonApi.parseFrom( + path, + new JsonTypeReference>() {} + ); + + String s = jsonApi.format(prossed(map)).replace("\\\\u", "\\u"); + FileUtil.writeStringToFile(StringUtil.format("old-{}", path), s); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/com/mingliqiye/utils/minecraft/slp/Description.java b/src/main/java/com/mingliqiye/utils/minecraft/slp/Description.java similarity index 100% rename from src/com/mingliqiye/utils/minecraft/slp/Description.java rename to src/main/java/com/mingliqiye/utils/minecraft/slp/Description.java diff --git a/src/com/mingliqiye/utils/minecraft/slp/Extra.java b/src/main/java/com/mingliqiye/utils/minecraft/slp/Extra.java similarity index 100% rename from src/com/mingliqiye/utils/minecraft/slp/Extra.java rename to src/main/java/com/mingliqiye/utils/minecraft/slp/Extra.java diff --git a/src/com/mingliqiye/utils/minecraft/slp/MinecraftServerStatus.java b/src/main/java/com/mingliqiye/utils/minecraft/slp/MinecraftServerStatus.java similarity index 100% rename from src/com/mingliqiye/utils/minecraft/slp/MinecraftServerStatus.java rename to src/main/java/com/mingliqiye/utils/minecraft/slp/MinecraftServerStatus.java diff --git a/src/com/mingliqiye/utils/minecraft/slp/PlayerSample.java b/src/main/java/com/mingliqiye/utils/minecraft/slp/PlayerSample.java similarity index 100% rename from src/com/mingliqiye/utils/minecraft/slp/PlayerSample.java rename to src/main/java/com/mingliqiye/utils/minecraft/slp/PlayerSample.java diff --git a/src/com/mingliqiye/utils/minecraft/slp/Players.java b/src/main/java/com/mingliqiye/utils/minecraft/slp/Players.java similarity index 100% rename from src/com/mingliqiye/utils/minecraft/slp/Players.java rename to src/main/java/com/mingliqiye/utils/minecraft/slp/Players.java diff --git a/src/com/mingliqiye/utils/minecraft/slp/SLP.java b/src/main/java/com/mingliqiye/utils/minecraft/slp/SLP.java similarity index 100% rename from src/com/mingliqiye/utils/minecraft/slp/SLP.java rename to src/main/java/com/mingliqiye/utils/minecraft/slp/SLP.java diff --git a/src/com/mingliqiye/utils/minecraft/slp/Version.java b/src/main/java/com/mingliqiye/utils/minecraft/slp/Version.java similarity index 100% rename from src/com/mingliqiye/utils/minecraft/slp/Version.java rename to src/main/java/com/mingliqiye/utils/minecraft/slp/Version.java diff --git a/src/com/mingliqiye/utils/network/NetworkAddress.java b/src/main/java/com/mingliqiye/utils/network/NetworkAddress.java similarity index 100% rename from src/com/mingliqiye/utils/network/NetworkAddress.java rename to src/main/java/com/mingliqiye/utils/network/NetworkAddress.java diff --git a/src/com/mingliqiye/utils/network/NetworkEndpoint.java b/src/main/java/com/mingliqiye/utils/network/NetworkEndpoint.java similarity index 100% rename from src/com/mingliqiye/utils/network/NetworkEndpoint.java rename to src/main/java/com/mingliqiye/utils/network/NetworkEndpoint.java diff --git a/src/com/mingliqiye/utils/network/NetworkException.java b/src/main/java/com/mingliqiye/utils/network/NetworkException.java similarity index 100% rename from src/com/mingliqiye/utils/network/NetworkException.java rename to src/main/java/com/mingliqiye/utils/network/NetworkException.java diff --git a/src/com/mingliqiye/utils/network/NetworkPort.java b/src/main/java/com/mingliqiye/utils/network/NetworkPort.java similarity index 100% rename from src/com/mingliqiye/utils/network/NetworkPort.java rename to src/main/java/com/mingliqiye/utils/network/NetworkPort.java diff --git a/src/com/mingliqiye/utils/path/OsPath.java b/src/main/java/com/mingliqiye/utils/path/OsPath.java similarity index 100% rename from src/com/mingliqiye/utils/path/OsPath.java rename to src/main/java/com/mingliqiye/utils/path/OsPath.java diff --git a/src/com/mingliqiye/utils/random/RandomBytes.java b/src/main/java/com/mingliqiye/utils/random/RandomBytes.java similarity index 100% rename from src/com/mingliqiye/utils/random/RandomBytes.java rename to src/main/java/com/mingliqiye/utils/random/RandomBytes.java diff --git a/src/com/mingliqiye/utils/random/RandomInt.java b/src/main/java/com/mingliqiye/utils/random/RandomInt.java similarity index 100% rename from src/com/mingliqiye/utils/random/RandomInt.java rename to src/main/java/com/mingliqiye/utils/random/RandomInt.java diff --git a/src/com/mingliqiye/utils/random/RandomString.java b/src/main/java/com/mingliqiye/utils/random/RandomString.java similarity index 100% rename from src/com/mingliqiye/utils/random/RandomString.java rename to src/main/java/com/mingliqiye/utils/random/RandomString.java diff --git a/src/com/mingliqiye/utils/springboot/autoconfigure/AutoConfiguration.java b/src/main/java/com/mingliqiye/utils/springboot/autoconfigure/AutoConfiguration.java similarity index 100% rename from src/com/mingliqiye/utils/springboot/autoconfigure/AutoConfiguration.java rename to src/main/java/com/mingliqiye/utils/springboot/autoconfigure/AutoConfiguration.java diff --git a/src/main/java/com/mingliqiye/utils/stream/InOutSteam.java b/src/main/java/com/mingliqiye/utils/stream/InOutSteam.java new file mode 100644 index 0000000..40a0cdd --- /dev/null +++ b/src/main/java/com/mingliqiye/utils/stream/InOutSteam.java @@ -0,0 +1,279 @@ +package com.mingliqiye.utils.stream; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import org.jetbrains.annotations.NotNull; + +/** + * 自定义的输入输出流工具类,支持线程安全的数据读写操作。
+ * 谁闲着没事干用本地输入输出
+ * 实现了 AutoCloseable、Closeable 和 Flushable 接口,便于资源管理。 + * + * @author MingLiPro + */ +public class InOutSteam implements AutoCloseable, Closeable, Flushable { + + private final Lock lock = new ReentrantLock(); + + List bytes; + + /** + * 从内部缓冲区中读取最多 len 个字节到指定的字节数组 b 中。 + * + * @param b 目标字节数组,用于存储读取的数据 + * @param off 起始偏移位置 + * @param len 最大读取字节数 + * @return 实际读取的字节数;如果已到达流末尾,则返回 -1 + * @throws IndexOutOfBoundsException 如果 off 或 len 参数非法 + */ + public int read(byte@NotNull [] b, int off, int len) { + if (bytes == null) return -1; + if (bytes.isEmpty()) { + return 0; + } + + if (off < 0 || len < 0 || off + len > b.length) { + throw new IndexOutOfBoundsException(); + } + + try { + lock.lock(); + int bytesRead = Math.min(len, bytes.size()); + + for (int i = 0; i < bytesRead; i++) { + b[off + i] = bytes.get(i); + } + if (bytesRead > 0) { + bytes.subList(0, bytesRead).clear(); + } + + return bytesRead; + } finally { + lock.unlock(); + } + } + + /** + * 读取一个字节的数据。 + * + * @return 下一个字节数据(0~255),如果已到达流末尾则返回 -1 + */ + public int read() { + if (bytes == null) return -1; + try { + lock.lock(); + if (bytes.isEmpty()) { + return -1; + } + return bytes.remove(0); + } finally { + lock.unlock(); + } + } + + /** + * 从内部缓冲区中读取最多 b.length 个字节到指定的字节数组 b 中。 + * + * @param b 目标字节数组,用于存储读取的数据 + * @return 实际读取的字节数;如果已到达流末尾,则返回 -1 + */ + public int read(byte@NotNull [] b) { + if (bytes == null) return -1; + return read(b, 0, b.length); + } + + /** + * 跳过并丢弃此输入流中数据的 n 个字节。 + * + * @param n 要跳过的字节数 + * @return 实际跳过的字节数 + */ + public long skip(long n) { + if (bytes == null) return -1; + if (bytes.isEmpty()) { + return 0; + } + + try { + lock.lock(); + if (n <= 0) { + return 0; + } + long bytesToSkip = Math.min(n, bytes.size()); + + // 移除跳过的字节 + if (bytesToSkip > 0) { + bytes.subList(0, (int) bytesToSkip).clear(); + } + + return bytesToSkip; + } finally { + lock.unlock(); + } + } + + /** + * 返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数。 + * + * @return 可以无阻塞读取的字节数 + */ + public int available() { + if (bytes == null) return -1; + try { + lock.lock(); + return bytes.size(); + } finally { + lock.unlock(); + } + } + + /** + * 获取与当前对象关联的 InputStream 实例。 + * + * @return InputStream 实例 + */ + public InputStream getInputStream() { + if (inputStream == null) { + inputStream = inputStream(); + } + return inputStream; + } + + private InputStream inputStream; + private OutputStream outputStream; + + /** + * 获取与当前对象关联的 OutputStream 实例。 + * + * @return OutputStream 实例 + */ + public OutputStream getOutputStream() { + if (outputStream == null) { + outputStream = outputStream(); + } + return outputStream; + } + + /** + * 创建并返回一个包装后的 InputStream 实例。 + * + * @return 新创建的 InputStream 实例 + */ + private InputStream inputStream() { + return new InputStreanWrapper( + new InputStream() { + @Override + public int read() { + return InOutSteam.this.read(); + } + + @Override + public int read(byte@NotNull [] b, int off, int len) { + return InOutSteam.this.read(b, off, len); + } + + @Override + public long skip(long n) { + return InOutSteam.this.skip(n); + } + + @Override + public int available() { + return InOutSteam.this.available(); + } + } + ); + } + + /** + * 创建并返回一个 OutputStream 实例。 + * + * @return 新创建的 OutputStream 实例 + */ + private OutputStream outputStream() { + return new OutputStream() { + @Override + public void write(int b) { + InOutSteam.this.write(b); + } + + @Override + public void write(byte@NotNull [] b, int off, int len) { + InOutSteam.this.write(b, off, len); + } + }; + } + + /** + * 构造函数,初始化内部字节列表。 + */ + public InOutSteam() { + bytes = new ArrayList<>(); + } + + /** + * 将指定的字节写入此输出流。 + * + * @param b 要写入的字节 + */ + public void write(int b) { + try { + lock.lock(); + bytes.add((byte) b); + } finally { + lock.unlock(); + } + } + + /** + * 将指定字节数组中的部分数据写入此输出流。 + * + * @param b 数据源字节数组 + * @param off 起始偏移位置 + * @param len 写入的字节数 + * @throws IndexOutOfBoundsException 如果 off 或 len 参数非法 + */ + public void write(byte@NotNull [] b, int off, int len) { + if (off < 0 || len < 0 || off + len > b.length) { + throw new IndexOutOfBoundsException("Invalid offset or length"); + } + + try { + lock.lock(); + for (int i = off; i < off + len; i++) { + bytes.add(b[i]); + } + } finally { + lock.unlock(); + } + } + + /** + * 将整个字节数组写入此输出流。 + * + * @param b 要写入的字节数组 + */ + public void write(byte@NotNull [] b) { + write(b, 0, b.length); + } + + /** + * 刷新此输出流并强制写出所有缓冲的输出字节。 + * 当前实现为空方法。 + */ + @Override + public void flush() {} + + /** + * 关闭此流并释放与其相关的所有资源。 + * 清空并置空内部字节列表。 + */ + @Override + public void close() { + bytes.clear(); + bytes = null; + } +} diff --git a/src/main/java/com/mingliqiye/utils/stream/InputStreamUtils.java b/src/main/java/com/mingliqiye/utils/stream/InputStreamUtils.java new file mode 100644 index 0000000..0da7602 --- /dev/null +++ b/src/main/java/com/mingliqiye/utils/stream/InputStreamUtils.java @@ -0,0 +1,98 @@ +package com.mingliqiye.utils.stream; + +import com.mingliqiye.utils.collection.Lists; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; +import lombok.val; + +/** + * 输入流工具类,提供对InputStream的常用操作封装 + */ +public class InputStreamUtils { + + /** + * 默认缓冲区大小:1MB + */ + public static final int DEFAULT_BUFFER_SIZE = 1024 * 1024; + + /** + * 将输入流读取到字节数组中
+ * 请在外部自行关闭输入流对象 避免资源泄露 + * + * @param inputStream 输入流对象,用于读取数据 + * @return 包含输入流所有数据的字节数组 + * @throws IOException 当读取输入流或写入输出流时发生IO异常 + */ + public static byte[] readToArray(InputStream inputStream) + throws IOException { + // 使用ByteArrayOutputStream来收集输入流中的所有数据 + try (val byteArrayOutputStream = new ByteArrayOutputStream()) { + val bytes = new byte[DEFAULT_BUFFER_SIZE]; + int length; + // 循环读取输入流数据,直到读取完毕 + while ((length = inputStream.read(bytes)) != -1) { + byteArrayOutputStream.write(bytes, 0, length); + } + return byteArrayOutputStream.toByteArray(); + } + } + + /** + * 将输入流读取到Byte列表中
+ * 请在外部自行关闭输入流对象 避免资源泄露 + * + * @param inputStream 输入流对象,用于读取数据 + * @return 包含输入流所有数据的Byte列表 + * @throws IOException 当读取输入流时发生IO异常 + */ + public static List readToList(InputStream inputStream) + throws IOException { + return Lists.toList(readToArray(inputStream)); + } + + /** + * 将输入流读取为字符串
+ * 请在外部自行关闭输入流对象 避免资源泄露 + * @param inputStream 输入流对象,用于读取数据 + * @return 输入流对应的字符串内容 + * @throws IOException 当读取输入流时发生IO异常 + */ + public static String readToString(InputStream inputStream) + throws IOException { + return new String(readToArray(inputStream)); + } + + /** + * 将输入流的数据传输到输出流中
+ * 请在外部自行关闭输入流输出流对象 避免资源泄露 + * + * @param inputStream 源输入流,用于读取数据 + * @param outputStream 目标输出流,用于写入数据 + * @return 传输的总字节数 + * @throws IOException 当读取或写入流时发生IO异常 + */ + public static long transferTo( + InputStream inputStream, + OutputStream outputStream + ) throws IOException { + if (inputStream == null) { + throw new IllegalArgumentException("inputStream can not be null"); + } + if (outputStream == null) { + throw new IllegalArgumentException("outputStream can not be null"); + } + val bytes = new byte[DEFAULT_BUFFER_SIZE]; + int length; + long readAll = 0L; + // 循环读取并写入数据,直到输入流读取完毕 + while ((length = inputStream.read(bytes)) != -1) { + outputStream.write(bytes, 0, length); + readAll += length; + } + outputStream.flush(); + return readAll; + } +} diff --git a/src/main/java/com/mingliqiye/utils/stream/InputStreanWrapper.java b/src/main/java/com/mingliqiye/utils/stream/InputStreanWrapper.java new file mode 100644 index 0000000..915108a --- /dev/null +++ b/src/main/java/com/mingliqiye/utils/stream/InputStreanWrapper.java @@ -0,0 +1,95 @@ +package com.mingliqiye.utils.stream; + +import java.io.*; +import java.util.List; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; + +public class InputStreanWrapper extends InputStream implements AutoCloseable { + + @Getter + private final InputStream inputStream; + + public InputStreanWrapper(InputStream inputStream) { + this.inputStream = inputStream; + } + + private static InputStreanWrapper of(InputStream inputStream) { + return new InputStreanWrapper(inputStream); + } + + @Override + public int available() throws IOException { + return inputStream.available(); + } + + @Override + public int read() throws IOException { + return inputStream.read(); + } + + @Override + public int read(byte@NotNull [] b) throws IOException { + return inputStream.read(b); + } + + @Override + public int read(byte@NotNull [] b, int off, int len) throws IOException { + return inputStream.read(b, off, len); + } + + @Override + public long skip(long n) throws IOException { + return inputStream.skip(n); + } + + @Override + public void mark(int readlimit) { + inputStream.mark(readlimit); + } + + @Override + public void reset() throws IOException { + inputStream.reset(); + } + + @Override + public boolean markSupported() { + return inputStream.markSupported(); + } + + @Override + public void close() { + try { + inputStream.close(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * 输入流转换为输出流
+ * jdk8 兼容实现 jdk9+
+ * 请使用 InputStream.transferTo() + * + * @param outputStream + * @return 转换的字节数 + * @throws IOException + */ + public long transferToOutputStream(OutputStream outputStream) + throws IOException { + return InputStreamUtils.transferTo(inputStream, outputStream); + } + + public byte[] readToArray() throws IOException { + return InputStreamUtils.readToArray(inputStream); + } + + public List readToList() throws IOException { + return InputStreamUtils.readToList(inputStream); + } + + public String readToString() throws IOException { + return InputStreamUtils.readToString(inputStream); + } +} diff --git a/src/main/java/com/mingliqiye/utils/stream/OutputStreamWrapper.java b/src/main/java/com/mingliqiye/utils/stream/OutputStreamWrapper.java new file mode 100644 index 0000000..2aee383 --- /dev/null +++ b/src/main/java/com/mingliqiye/utils/stream/OutputStreamWrapper.java @@ -0,0 +1,81 @@ +package com.mingliqiye.utils.stream; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; + +public class OutputStreamWrapper extends OutputStream implements AutoCloseable { + + @Getter + private final OutputStream outputStream; + + private final ByteArrayOutputStream byteArrayOutputStream = + new ByteArrayOutputStream(); + + public OutputStreamWrapper(OutputStream outputStream) { + this.outputStream = outputStream; + } + + public static OutputStreamWrapper of(OutputStream outputStream) { + return new OutputStreamWrapper(outputStream); + } + + @Override + public void write(int b) throws IOException { + byteArrayOutputStream.write(b); + } + + @Override + public void write(byte@NotNull [] b) throws IOException { + byteArrayOutputStream.write(b); + } + + public void write(List b) throws IOException { + write(b, 0, b.size()); + } + + @Override + public void write(byte@NotNull [] b, int off, int len) throws IOException { + byteArrayOutputStream.write(b, off, len); + } + + public void write(List b, int off, int len) throws IOException { + byte[] bytes = new byte[b.size()]; + for (int i = 0; i < b.size(); i++) { + bytes[i] = b.get(i); + } + byteArrayOutputStream.write(bytes, off, len); + } + + @Override + public void flush() throws IOException { + outputStream.write(byteArrayOutputStream.toByteArray()); + byteArrayOutputStream.reset(); + } + + public int getBufferCachedSize() { + return byteArrayOutputStream.size(); + } + + public byte[] getBufferCachedBytes() { + return byteArrayOutputStream.toByteArray(); + } + + @Override + public void close() { + try { + outputStream.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public long transferFromOutputStream(InputStream inputStream) + throws IOException { + return InputStreamUtils.transferTo(inputStream, outputStream); + } +} diff --git a/src/main/java/com/mingliqiye/utils/stream/SuperStream.java b/src/main/java/com/mingliqiye/utils/stream/SuperStream.java new file mode 100644 index 0000000..60d3b8b --- /dev/null +++ b/src/main/java/com/mingliqiye/utils/stream/SuperStream.java @@ -0,0 +1,1411 @@ +/* + * Copyright 2025 mingliqiye + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ProjectName mingli-utils + * ModuleName mingli-utils.main + * CurrentFile SuperStream.java + * LastUpdate 2025-09-09 08:37:33 + * UpdateUser MingLiPro + */ + +package com.mingliqiye.utils.stream; + +import com.mingliqiye.utils.collection.Maps; +import java.util.*; +import java.util.concurrent.ConcurrentMap; +import java.util.function.*; +import java.util.stream.*; +import org.jetbrains.annotations.NotNull; + +/** + * 自定义的 SuperStream 实现类,用于对集合进行流式操作。 + * 该类实现了 Java 标准库中的 Stream 接口,并基于 List 数据结构提供了一系列流式处理方法。 + * + * @param 流中元素的类型 + * @author MingLiPro + */ +public class SuperStream implements Stream { + + /** + * 内部静态类 Collectors,用于提供常用的收集器实现。 + * 所有方法均是对 java.util.stream.Collectors 的封装或扩展。 + */ + public static class Collectors { + + /** + * 返回一个收集器,用于将元素映射为 long 值并求和。 + * + * @param mapper 映射函数,将元素转换为 long 值 + * @param 元素类型 + * @return 收集器 + */ + public static Collector summingLong( + @NotNull ToLongFunction mapper + ) { + return java.util.stream.Collectors.summingLong(mapper); + } + + /** + * 返回一个收集器,将元素收集到指定类型的集合中。 + * + * @param collectionFactory 集合工厂,用于创建目标集合 + * @param 元素类型 + * @param 目标集合类型 + * @return 收集器 + */ + public static > Collector< + T, + ?, + C + > toCollection(@NotNull Supplier collectionFactory) { + return java.util.stream.Collectors.toCollection(collectionFactory); + } + + /** + * 返回一个收集器,将元素收集到 List 中。 + * + * @param 元素类型 + * @return 收集器 + */ + public static Collector> toList() { + return java.util.stream.Collectors.toList(); + } + + /** + * 返回一个收集器,将元素收集到 Set 中。 + * + * @param 元素类型 + * @return 收集器 + */ + public static Collector> toSet() { + return java.util.stream.Collectors.toSet(); + } + + /** + * 返回一个收集器,将字符序列连接成字符串。 + * + * @return 收集器 + */ + public static Collector joining() { + return java.util.stream.Collectors.joining(); + } + + /** + * 返回一个收集器,将字符序列使用指定分隔符连接成字符串。 + * + * @param delimiter 分隔符 + * @return 收集器 + */ + public static Collector joining( + @NotNull CharSequence delimiter + ) { + return java.util.stream.Collectors.joining(delimiter); + } + + /** + * 返回一个收集器,将字符序列使用指定前缀、后缀和分隔符连接成字符串。 + * + * @param delimiter 分隔符 + * @param prefix 前缀 + * @param suffix 后缀 + * @return 收集器 + */ + public static Collector joining( + @NotNull CharSequence delimiter, + @NotNull CharSequence prefix, + @NotNull CharSequence suffix + ) { + return java.util.stream.Collectors.joining( + delimiter, + prefix, + suffix + ); + } + + /** + * 返回一个收集器,先对元素进行映射,再使用下游收集器进行收集。 + * + * @param mapper 映射函数 + * @param downstream 下游收集器 + * @param 输入元素类型 + * @param 映射后的元素类型 + * @param 下游收集器的中间结果类型 + * @param 最终结果类型 + * @return 收集器 + */ + public static Collector mapping( + @NotNull Function mapper, + @NotNull Collector downstream + ) { + return java.util.stream.Collectors.mapping(mapper, downstream); + } + + /** + * 返回一个收集器,在下游收集完成后应用 finisher 函数。 + * + * @param downstream 下游收集器 + * @param finisher 完成后应用的函数 + * @param 元素类型 + * @param 下游收集器的中间结果类型 + * @param 下游收集器的结果类型 + * @param 最终结果类型 + * @return 收集器 + */ + public static Collector collectingAndThen( + @NotNull Collector downstream, + @NotNull Function finisher + ) { + return java.util.stream.Collectors.collectingAndThen( + downstream, + finisher + ); + } + + /** + * 返回一个收集器,用于统计元素数量。 + * + * @param 元素类型 + * @return 收集器 + */ + public static Collector counting() { + return java.util.stream.Collectors.counting(); + } + + /** + * 返回一个收集器,找出最小元素。 + * + * @param comparator 比较器 + * @param 元素类型 + * @return 收集器 + */ + public static Collector> minBy( + @NotNull Comparator comparator + ) { + return java.util.stream.Collectors.minBy(comparator); + } + + /** + * 返回一个收集器,找出最大元素。 + * + * @param comparator 比较器 + * @param 元素类型 + * @return 收集器 + */ + public static Collector> maxBy( + @NotNull Comparator comparator + ) { + return java.util.stream.Collectors.maxBy(comparator); + } + + /** + * 返回一个收集器,将元素映射为 int 值并求和。 + * + * @param mapper 映射函数 + * @param 元素类型 + * @return 收集器 + */ + public static Collector summingInt( + @NotNull ToIntFunction mapper + ) { + return java.util.stream.Collectors.summingInt(mapper); + } + + /** + * 返回一个收集器,将元素映射为 double 值并求和。 + * + * @param mapper 映射函数 + * @param 元素类型 + * @return 收集器 + */ + public static Collector summingDouble( + @NotNull ToDoubleFunction mapper + ) { + return java.util.stream.Collectors.summingDouble(mapper); + } + + /** + * 返回一个收集器,计算元素映射为 int 值的平均值。 + * + * @param mapper 映射函数 + * @param 元素类型 + * @return 收集器 + */ + public static Collector averagingInt( + @NotNull ToIntFunction mapper + ) { + return java.util.stream.Collectors.averagingInt(mapper); + } + + /** + * 返回一个收集器,计算元素映射为 long 值的平均值。 + * + * @param mapper 映射函数 + * @param 元素类型 + * @return 收集器 + */ + public static Collector averagingLong( + @NotNull ToLongFunction mapper + ) { + return java.util.stream.Collectors.averagingLong(mapper); + } + + /** + * 返回一个收集器,计算元素映射为 double 值的平均值。 + * + * @param mapper 映射函数 + * @param 元素类型 + * @return 收集器 + */ + public static Collector averagingDouble( + @NotNull ToDoubleFunction mapper + ) { + return java.util.stream.Collectors.averagingDouble(mapper); + } + + /** + * 返回一个收集器,使用指定的初始值和二元操作符进行归约。 + * + * @param identity 初始值 + * @param op 二元操作符 + * @param 元素类型 + * @return 收集器 + */ + public static Collector reducing( + T identity, + @NotNull BinaryOperator op + ) { + return java.util.stream.Collectors.reducing(identity, op); + } + + /** + * 返回一个收集器,使用指定的二元操作符进行归约。 + * + * @param op 二元操作符 + * @param 元素类型 + * @return 收集器 + */ + public static Collector> reducing( + @NotNull BinaryOperator op + ) { + return java.util.stream.Collectors.reducing(op); + } + + /** + * 返回一个收集器,先对元素进行映射,再使用指定的初始值和二元操作符进行归约。 + * + * @param identity 初始值 + * @param mapper 映射函数 + * @param op 二元操作符 + * @param 元素类型 + * @param 映射后的元素类型 + * @return 收集器 + */ + public static Collector reducing( + U identity, + @NotNull Function mapper, + @NotNull BinaryOperator op + ) { + return java.util.stream.Collectors.reducing(identity, mapper, op); + } + + /** + * 返回一个收集器,按分类器对元素进行分组。 + * + * @param classifier 分类器函数 + * @param 元素类型 + * @param 分类键类型 + * @return 收集器 + */ + public static Collector< + T, + ?, + @NotNull Map> + > groupingBy(@NotNull Function classifier) { + return java.util.stream.Collectors.groupingBy(classifier); + } + + /** + * 返回一个收集器,按分类器对元素进行分组,并使用下游收集器处理每个组。 + * + * @param classifier 分类器函数 + * @param downstream 下游收集器 + * @param 元素类型 + * @param 分类键类型 + * @param 下游收集器的中间结果类型 + * @param 下游收集器的结果类型 + * @return 收集器 + */ + public static Collector< + T, + ?, + @NotNull Map + > groupingBy( + @NotNull Function classifier, + @NotNull Collector downstream + ) { + return java.util.stream.Collectors.groupingBy( + classifier, + downstream + ); + } + + /** + * 返回一个收集器,按分类器对元素进行分组,并使用指定的 Map 工厂和下游收集器。 + * + * @param classifier 分类器函数 + * @param mapFactory Map 工厂 + * @param downstream 下游收集器 + * @param 元素类型 + * @param 分类键类型 + * @param 下游收集器的结果类型 + * @param 下游收集器的中间结果类型 + * @param Map 类型 + * @return 收集器 + */ + public static > Collector< + T, + ?, + M + > groupingBy( + @NotNull Function classifier, + @NotNull Supplier mapFactory, + @NotNull Collector downstream + ) { + return java.util.stream.Collectors.groupingBy( + classifier, + mapFactory, + downstream + ); + } + + /** + * 返回一个并发收集器,按分类器对元素进行分组。 + * + * @param classifier 分类器函数 + * @param 元素类型 + * @param 分类键类型 + * @return 收集器 + */ + public static Collector< + T, + ?, + @NotNull ConcurrentMap> + > groupingByConcurrent( + @NotNull Function classifier + ) { + return java.util.stream.Collectors.groupingByConcurrent(classifier); + } + + /** + * 返回一个并发收集器,按分类器对元素进行分组,并使用下游收集器处理每个组。 + * + * @param classifier 分类器函数 + * @param downstream 下游收集器 + * @param 元素类型 + * @param 分类键类型 + * @param 下游收集器的中间结果类型 + * @param 下游收集器的结果类型 + * @return 收集器 + */ + public static Collector< + T, + ?, + @NotNull ConcurrentMap + > groupingByConcurrent( + @NotNull Function classifier, + @NotNull Collector downstream + ) { + return java.util.stream.Collectors.groupingByConcurrent( + classifier, + downstream + ); + } + + /** + * 返回一个并发收集器,按分类器对元素进行分组,并使用指定的 Map 工厂和下游收集器。 + * + * @param classifier 分类器函数 + * @param mapFactory Map 工厂 + * @param downstream 下游收集器 + * @param 元素类型 + * @param 分类键类型 + * @param 下游收集器的结果类型 + * @param 下游收集器的中间结果类型 + * @param Map 类型 + * @return 收集器 + */ + public static > Collector< + T, + ?, + M + > groupingByConcurrent( + @NotNull Function classifier, + @NotNull Supplier mapFactory, + @NotNull Collector downstream + ) { + return java.util.stream.Collectors.groupingByConcurrent( + classifier, + mapFactory, + downstream + ); + } + + /** + * 返回一个收集器,按谓词对元素进行分区。 + * + * @param predicate 谓词函数 + * @param 元素类型 + * @return 收集器 + */ + public static Collector< + T, + ?, + @NotNull Map<@NotNull Boolean, @NotNull List> + > partitioningBy(@NotNull Predicate predicate) { + return java.util.stream.Collectors.partitioningBy(predicate); + } + + /** + * 返回一个收集器,按谓词对元素进行分区,并使用下游收集器处理每个分区。 + * + * @param predicate 谓词函数 + * @param downstream 下游收集器 + * @param 元素类型 + * @param 下游收集器的结果类型 + * @param 下游收集器的中间结果类型 + * @return 收集器 + */ + public static Collector< + T, + ?, + @NotNull Map<@NotNull Boolean, D> + > partitioningBy( + @NotNull Predicate predicate, + @NotNull Collector downstream + ) { + return java.util.stream.Collectors.partitioningBy( + predicate, + downstream + ); + } + + /** + * 返回一个收集器,将元素转换为 Map。 + * + * @param keyMapper 键映射函数 + * @param valueMapper 值映射函数 + * @param 元素类型 + * @param 键类型 + * @param 值类型 + * @return 收集器 + */ + public static Collector< + T, + ?, + @NotNull Map + > toMap( + @NotNull Function keyMapper, + @NotNull Function valueMapper + ) { + return java.util.stream.Collectors.toMap(keyMapper, valueMapper); + } + + /** + * 返回一个收集器,将元素转换为 Map,并指定合并函数。 + * + * @param keyMapper 键映射函数 + * @param valueMapper 值映射函数 + * @param mergeFunction 合并函数 + * @param 元素类型 + * @param 键类型 + * @param 值类型 + * @return 收集器 + */ + public static Collector< + T, + ?, + @NotNull Map + > toMap( + @NotNull Function keyMapper, + @NotNull Function valueMapper, + @NotNull BinaryOperator mergeFunction + ) { + return java.util.stream.Collectors.toMap( + keyMapper, + valueMapper, + mergeFunction + ); + } + + /** + * 返回一个收集器,将元素转换为 Map,并指定合并函数和 Map 工厂。 + * + * @param keyMapper 键映射函数 + * @param valueMapper 值映射函数 + * @param mergeFunction 合并函数 + * @param mapSupplier Map 工厂 + * @param 元素类型 + * @param 键类型 + * @param 值类型 + * @param Map 类型 + * @return 收集器 + */ + public static > Collector toMap( + @NotNull Function keyMapper, + @NotNull Function valueMapper, + @NotNull BinaryOperator mergeFunction, + @NotNull Supplier mapSupplier + ) { + return java.util.stream.Collectors.toMap( + keyMapper, + valueMapper, + mergeFunction, + mapSupplier + ); + } + + /** + * 返回一个并发收集器,将元素转换为 ConcurrentMap。 + * + * @param keyMapper 键映射函数 + * @param valueMapper 值映射函数 + * @param 元素类型 + * @param 键类型 + * @param 值类型 + * @return 收集器 + */ + public static Collector< + T, + ?, + @NotNull ConcurrentMap + > toConcurrentMap( + @NotNull Function keyMapper, + @NotNull Function valueMapper + ) { + return java.util.stream.Collectors.toConcurrentMap( + keyMapper, + valueMapper + ); + } + + /** + * 返回一个并发收集器,将元素转换为 ConcurrentMap,并指定合并函数。 + * + * @param keyMapper 键映射函数 + * @param valueMapper 值映射函数 + * @param mergeFunction 合并函数 + * @param 元素类型 + * @param 键类型 + * @param 值类型 + * @return 收集器 + */ + public static Collector< + T, + ?, + @NotNull ConcurrentMap + > toConcurrentMap( + @NotNull Function keyMapper, + @NotNull Function valueMapper, + @NotNull BinaryOperator mergeFunction + ) { + return java.util.stream.Collectors.toConcurrentMap( + keyMapper, + valueMapper, + mergeFunction + ); + } + + /** + * 返回一个并发收集器,将元素转换为 ConcurrentMap,并指定合并函数和 Map 工厂。 + * + * @param keyMapper 键映射函数 + * @param valueMapper 值映射函数 + * @param mergeFunction 合并函数 + * @param mapSupplier Map 工厂 + * @param 元素类型 + * @param 键类型 + * @param 值类型 + * @param Map 类型 + * @return 收集器 + */ + public static > Collector< + T, + ?, + M + > toConcurrentMap( + @NotNull Function keyMapper, + @NotNull Function valueMapper, + @NotNull BinaryOperator mergeFunction, + @NotNull Supplier mapSupplier + ) { + return java.util.stream.Collectors.toConcurrentMap( + keyMapper, + valueMapper, + mergeFunction, + mapSupplier + ); + } + + /** + * 返回一个收集器,计算元素映射为 int 值的统计信息。 + * + * @param mapper 映射函数 + * @param 元素类型 + * @return 收集器 + */ + public static Collector< + T, + ?, + @NotNull IntSummaryStatistics + > summarizingInt(@NotNull ToIntFunction mapper) { + return java.util.stream.Collectors.summarizingInt(mapper); + } + + /** + * 返回一个收集器,计算元素映射为 long 值的统计信息。 + * + * @param mapper 映射函数 + * @param 元素类型 + * @return 收集器 + */ + public static Collector< + T, + ?, + @NotNull LongSummaryStatistics + > summarizingLong(@NotNull ToLongFunction mapper) { + return java.util.stream.Collectors.summarizingLong(mapper); + } + + /** + * 返回一个收集器,计算元素映射为 double 值的统计信息。 + * + * @param mapper 映射函数 + * @param 元素类型 + * @return 收集器 + */ + public static Collector< + T, + ?, + @NotNull DoubleSummaryStatistics + > summarizingDouble(@NotNull ToDoubleFunction mapper) { + return java.util.stream.Collectors.summarizingDouble(mapper); + } + + /** + * 返回当前元素本身。 + * + * @param t 元素 + * @param 元素类型 + * @return 元素本身 + */ + public static T getThis(T t) { + return t; + } + + /** + * 返回一个收集器,将元素收集到 List 中。 + * + * @param 元素类型 + * @return 收集器 + */ + public static Collector> toMap() { + return Collectors.toList(); + } + + /** + * 返回一个收集器,将元素转换为 Map,键由 keyMapper 生成,值为元素本身。 + * + * @param keyMapper 键映射函数 + * @param 元素类型 + * @param 键类型 + * @return 收集器 + */ + public static Collector> toMap( + @NotNull Function keyMapper + ) { + return Collectors.toMap(keyMapper, Collectors::getThis); + } + } + + /** + * 内部流对象,用于执行实际的流操作。 + */ + private final Stream stream; + + /** + * 构造函数,使用给定的流对象初始化 SuperStream。 + * + * @param stream 流对象 + */ + public SuperStream(Stream stream) { + this.stream = stream; + } + + /** + * 将流中的元素收集到 List 中。 + * + * @return 包含流中所有元素的 List + */ + public List toList() { + return stream.collect(Collectors.toList()); + } + + /** + * 将流中的元素收集到 Set 中。 + * + * @return 包含流中所有元素的 Set + */ + public Set toSet() { + return stream.collect(Collectors.toSet()); + } + + /** + * 将流中的元素转换为 Map,键由 mapper 生成,值为元素本身。 + * + * @param mapper 键映射函数 + * @param 键类型 + * @return 包含流中所有元素的 Map + */ + public Map toMap(Function mapper) { + return stream.collect(Collectors.toMap(mapper)); + } + + /** + * 将流中的元素转换为 Map.Entry 列表,并使用 Maps.ofEntries 方法转换为 Map。 + * + * @param 键类型 + * @param 值类型 + * @return 包含流中所有元素的 Map + */ + @SuppressWarnings("unchecked") + public Map entryToMap() { + return Maps.ofEntries((List>) toList()); + } + + /** + * 创建一个 SuperStream 实例,基于给定的集合。 + * + * @param collection 集合 + * @param parallel 是否并行流 + * @param 元素类型 + * @return SuperStream 实例 + */ + public static SuperStream of( + Collection collection, + boolean parallel + ) { + return new SuperStream<>( + parallel ? collection.parallelStream() : collection.stream() + ); + } + + /** + * 创建一个 SuperStream 实例,基于给定的集合。 + * + * @param collection 集合 + * @param 元素类型 + * @return SuperStream 实例 + */ + public static SuperStream of(Collection collection) { + return of(collection, false); + } + + /** + * 创建一个 SuperStream 实例,基于给定的 Map。 + * + * @param map Map + * @param parallel 是否并行流 + * @param 键类型 + * @param 值类型 + * @return SuperStream 实例 + */ + public static SuperStream> of( + Map map, + boolean parallel + ) { + return new SuperStream<>( + parallel ? map.entrySet().parallelStream() : map.entrySet().stream() + ); + } + + /** + * 创建一个 SuperStream 实例,基于给定的 Map。 + * + * @param map Map + * @param 键类型 + * @param 值类型 + * @return SuperStream 实例 + */ + public static SuperStream> of(Map map) { + return of(map, false); + } + + /** + * 返回一个顺序流。 + * + * @return SuperStream 实例 + */ + @Override + public @NotNull SuperStream sequential() { + return new SuperStream<>(stream.sequential()); + } + + /** + * 过滤流中的元素。 + * + * @param predicate 谓词函数 + * @return SuperStream 实例 + */ + @Override + public SuperStream filter(Predicate predicate) { + return new SuperStream<>(stream.filter(predicate)); + } + + /** + * 过滤流中的元素,使用 Function 作为谓词。 + * + * @param predicate 谓词函数 + * @return SuperStream 实例 + */ + public SuperStream filter(Function predicate) { + return new SuperStream<>(stream.filter(predicate::apply)); + } + + /** + * 映射流中的元素。 + * + * @param mapper 映射函数 + * @param 映射后的元素类型 + * @return SuperStream 实例 + */ + @Override + public SuperStream map(Function mapper) { + return new SuperStream<>(stream.map(mapper)); + } + + /** + * 扁平化映射流中的元素。 + * + * @param mapper 映射函数 + * @param 映射后的元素类型 + * @return SuperStream 实例 + */ + @Override + public SuperStream flatMap( + Function> mapper + ) { + return new SuperStream<>(stream.flatMap(mapper)); + } + + /** + * 将流中的元素映射为 int 值。 + * + * @param mapper 映射函数 + * @return IntStream 实例 + */ + @Override + public IntStream mapToInt(ToIntFunction mapper) { + return stream.mapToInt(mapper); + } + + /** + * 将流中的元素映射为 long 值。 + * + * @param mapper 映射函数 + * @return LongStream 实例 + */ + @Override + public LongStream mapToLong(ToLongFunction mapper) { + return stream.mapToLong(mapper); + } + + /** + * 将流中的元素映射为 double 值。 + * + * @param mapper 映射函数 + * @return DoubleStream 实例 + */ + @Override + public DoubleStream mapToDouble(ToDoubleFunction mapper) { + return stream.mapToDouble(mapper); + } + + /** + * 扁平化映射流中的元素为 IntStream。 + * + * @param mapper 映射函数 + * @return IntStream 实例 + */ + @Override + public IntStream flatMapToInt( + Function mapper + ) { + return stream.flatMapToInt(mapper); + } + + /** + * 扁平化映射流中的元素为 LongStream。 + * + * @param mapper 映射函数 + * @return LongStream 实例 + */ + @Override + public LongStream flatMapToLong( + Function mapper + ) { + return stream.flatMapToLong(mapper); + } + + /** + * 扁平化映射流中的元素为 DoubleStream。 + * + * @param mapper 映射函数 + * @return DoubleStream 实例 + */ + @Override + public DoubleStream flatMapToDouble( + Function mapper + ) { + return stream.flatMapToDouble(mapper); + } + + /** + * 去除流中的重复元素。 + * + * @return SuperStream 实例 + */ + @Override + public SuperStream distinct() { + return new SuperStream<>(stream.distinct()); + } + + /** + * 对流中的元素进行排序。 + * + * @return SuperStream 实例 + */ + @Override + public SuperStream sorted() { + return new SuperStream<>(stream.sorted()); + } + + /** + * 使用指定的比较器对流中的元素进行排序。 + * + * @param comparator 比较器 + * @return SuperStream 实例 + */ + @Override + public SuperStream sorted(Comparator comparator) { + return new SuperStream<>(stream.sorted(comparator)); + } + + /** + * 对流中的每个元素执行操作。 + * + * @param action 操作函数 + * @return SuperStream 实例 + */ + @Override + public SuperStream peek(Consumer action) { + return new SuperStream<>(stream.peek(action)); + } + + /** + * 限制流中的元素数量。 + * + * @param maxSize 最大元素数量 + * @return SuperStream 实例 + */ + @Override + public SuperStream limit(long maxSize) { + return new SuperStream<>(stream.limit(maxSize)); + } + + /** + * 跳过流中的前 n 个元素。 + * + * @param n 跳过的元素数量 + * @return SuperStream 实例 + */ + @Override + public SuperStream skip(long n) { + return new SuperStream<>(stream.skip(n)); + } + + /** + * 对流中的每个元素执行操作。 + * + * @param action 操作函数 + */ + @Override + public void forEach(Consumer action) { + stream.forEach(action); + } + + /** + * 对流中的每个元素按顺序执行操作。 + * + * @param action 操作函数 + */ + @Override + public void forEachOrdered(Consumer action) { + stream.forEachOrdered(action); + } + + /** + * 将流中的元素转换为数组。 + * + * @return 包含流中所有元素的数组 + */ + @Override + public @NotNull Object@NotNull [] toArray() { + return stream.toArray(); + } + + /** + * 将流中的元素转换为指定类型的数组。 + * + * @param generator 数组生成器 + * @param 数组元素类型 + * @return 包含流中所有元素的数组 + */ + @Override + public @NotNull A@NotNull [] toArray(IntFunction generator) { + return stream.toArray(generator); + } + + /** + * 使用指定的初始值和累加器对流中的元素进行归约。 + * + * @param identity 初始值 + * @param accumulator 累加器 + * @return 归约结果 + */ + @Override + public T reduce(T identity, BinaryOperator accumulator) { + return stream.reduce(identity, accumulator); + } + + /** + * 使用指定的累加器对流中的元素进行归约。 + * + * @param accumulator 累加器 + * @return 归约结果 + */ + @Override + public @NotNull Optional reduce(BinaryOperator accumulator) { + return stream.reduce(accumulator); + } + + /** + * 使用指定的初始值、累加器和组合器对流中的元素进行归约。 + * + * @param identity 初始值 + * @param accumulator 累加器 + * @param combiner 组合器 + * @param 归约结果类型 + * @return 归约结果 + */ + @Override + public U reduce( + U identity, + BiFunction accumulator, + BinaryOperator combiner + ) { + return stream.reduce(identity, accumulator, combiner); + } + + /** + * 使用指定的供应商、累加器和组合器对流中的元素进行收集。 + * + * @param supplier 供应商 + * @param accumulator 累加器 + * @param combiner 组合器 + * @param 收集结果类型 + * @return 收集结果 + */ + @Override + public R collect( + Supplier supplier, + BiConsumer accumulator, + BiConsumer combiner + ) { + return stream.collect(supplier, accumulator, combiner); + } + + /** + * 使用指定的收集器对流中的元素进行收集。 + * + * @param collector 收集器 + * @param 收集结果类型 + * @param 收集器中间结果类型 + * @return 收集结果 + */ + @Override + public R collect(Collector collector) { + return stream.collect(collector); + } + + /** + * 找出流中的最小元素。 + * + * @param comparator 比较器 + * @return 最小元素 + */ + @Override + public @NotNull Optional min(Comparator comparator) { + return stream.min(comparator); + } + + /** + * 找出流中的最大元素。 + * + * @param comparator 比较器 + * @return 最大元素 + */ + @Override + public @NotNull Optional max(Comparator comparator) { + return stream.max(comparator); + } + + /** + * 计算流中的元素数量。 + * + * @return 元素数量 + */ + @Override + public long count() { + return stream.count(); + } + + /** + * 判断流中是否有任意元素满足谓词。 + * + * @param predicate 谓词函数 + * @return 是否满足 + */ + @Override + public boolean anyMatch(Predicate predicate) { + return stream.anyMatch(predicate); + } + + /** + * 判断流中是否所有元素都满足谓词。 + * + * @param predicate 谓词函数 + * @return 是否满足 + */ + @Override + public boolean allMatch(Predicate predicate) { + return stream.allMatch(predicate); + } + + /** + * 判断流中是否没有元素满足谓词。 + * + * @param predicate 谓词函数 + * @return 是否满足 + */ + @Override + public boolean noneMatch(Predicate predicate) { + return stream.noneMatch(predicate); + } + + /** + * 找出流中的第一个元素。 + * + * @return 第一个元素 + */ + @Override + public @NotNull Optional findFirst() { + return stream.findFirst(); + } + + /** + * 找出流中的任意元素。 + * + * @return 任意元素 + */ + @Override + public @NotNull Optional findAny() { + return stream.findAny(); + } + + /** + * 创建一个 SuperStream 构建器。 + * + * @param 元素类型 + * @return 构建器 + */ + public static Builder builder() { + return new Builder() { + private final List list = new ArrayList<>(); + + @Override + public void accept(T t) { + list.add(t); + } + + @Override + public @NotNull SuperStream build() { + return new SuperStream<>(list.stream()); + } + }; + } + + /** + * 创建一个空的 SuperStream 实例。 + * + * @param 元素类型 + * @return SuperStream 实例 + */ + public static @NotNull SuperStream empty() { + return new SuperStream<>(Stream.empty()); + } + + /** + * 创建一个包含单个元素的 SuperStream 实例。 + * + * @param t 元素 + * @param 元素类型 + * @return SuperStream 实例 + */ + public static @NotNull SuperStream of(T t) { + return new SuperStream<>(Stream.of(t)); + } + + /** + * 创建一个包含多个元素的 SuperStream 实例。 + * + * @param values 元素数组 + * @param 元素类型 + * @return SuperStream 实例 + */ + @SafeVarargs + public static @NotNull SuperStream of(T... values) { + return new SuperStream<>(Stream.of(values)); + } + + /** + * 创建一个无限流,使用指定的种子和函数生成元素。 + * + * @param seed 种子 + * @param f 函数 + * @param 元素类型 + * @return SuperStream 实例 + */ + public static @NotNull SuperStream iterate( + T seed, + UnaryOperator f + ) { + return new SuperStream<>(Stream.iterate(seed, f)); + } + + /** + * 创建一个无限流,使用指定的供应商生成元素。 + * + * @param s 供应商 + * @param 元素类型 + * @return SuperStream 实例 + */ + public static @NotNull SuperStream generate(Supplier s) { + return new SuperStream<>(Stream.generate(s)); + } + + /** + * 连接两个流。 + * + * @param a 第一个流 + * @param b 第二个流 + * @param 元素类型 + * @return SuperStream 实例 + */ + public static @NotNull SuperStream concat( + @NotNull Stream a, + @NotNull Stream b + ) { + return new SuperStream<>(Stream.concat(a, b)); + } + + /** + * 返回流的迭代器。 + * + * @return 迭代器 + */ + @Override + public @NotNull Iterator iterator() { + return stream.iterator(); + } + + /** + * 返回流的 Spliterator。 + * + * @return Spliterator + */ + @Override + public @NotNull Spliterator spliterator() { + return stream.spliterator(); + } + + /** + * 判断流是否为并行流。 + * + * @return 是否为并行流 + */ + @Override + public boolean isParallel() { + return stream.isParallel(); + } + + /** + * 返回一个并行流。 + * + * @return SuperStream 实例 + */ + @Override + public @NotNull SuperStream parallel() { + return new SuperStream<>(stream.parallel()); + } + + /** + * 返回一个无序流。 + * + * @return SuperStream 实例 + */ + @Override + public @NotNull SuperStream unordered() { + return new SuperStream<>(stream.unordered()); + } + + /** + * 注册流关闭时的处理器。 + * + * @param closeHandler 关闭处理器 + * @return SuperStream 实例 + */ + @Override + public @NotNull SuperStream onClose(@NotNull Runnable closeHandler) { + return new SuperStream<>(stream.onClose(closeHandler)); + } + + /** + * 关闭流。 + */ + @Override + public void close() { + stream.close(); + } +} diff --git a/src/com/mingliqiye/utils/string/StringUtil.java b/src/main/java/com/mingliqiye/utils/string/StringUtil.java similarity index 76% rename from src/com/mingliqiye/utils/string/StringUtil.java rename to src/main/java/com/mingliqiye/utils/string/StringUtil.java index 365f49a..276eb70 100644 --- a/src/com/mingliqiye/utils/string/StringUtil.java +++ b/src/main/java/com/mingliqiye/utils/string/StringUtil.java @@ -212,4 +212,60 @@ public class StringUtil { public static StringBuilder stringBuilder(int i) { return new StringBuilder(i); } + + /** + * 将字符串转换为Unicode编码格式 + * + * @param str 待转换的字符串 + * @return 转换后的Unicode编码字符串,每个字符都以\\u开头的十六进制形式表示 + */ + public static String stringToUnicode(String str) { + StringBuilder sb = new StringBuilder(); + char[] c = str.toCharArray(); + for (char value : c) { + sb.append(stringToUnicode(value)); + } + return sb.toString(); + } + + /** + * 将字符转换为Unicode转义字符串 + * + * @param c 需要转换的字符 + * @return 返回格式为"\\uXXXX"的Unicode转义字符串,其中XXXX为字符的十六进制Unicode码点 + */ + public static String stringToUnicode(char c) { + return "\\u" + String.format("%04x", (int) c); + } + + /** + * 将整数转换为Unicode字符串表示形式 + * + * @param c 要转换的整数,表示Unicode码点 + * @return 返回格式为"\\uXXXX"的Unicode字符串,其中XXXX是参数c的十六进制表示 + */ + public static String stringToUnicode(Integer c) { + return "\\u" + Integer.toHexString(c); + } + + /** + * 将Unicode编码字符串转换为普通字符串 + * 该函数接收一个包含Unicode转义序列的字符串,将其解析并转换为对应的字符序列 + * + * @param unicode 包含Unicode转义序列的字符串,格式如"\\uXXXX",其中XXXX为十六进制数 + * @return 转换后的普通字符串,包含对应的Unicode字符 + */ + public static String unicodeToString(String unicode) { + StringBuilder sb = new StringBuilder(); + // 按照Unicode转义符分割字符串,得到包含十六进制编码的数组 + String[] hex = unicode.split("\\\\u"); + // 从索引1开始遍历,因为分割后的第一个元素是转义符前面的内容(可能为空) + for (int i = 1; i < hex.length; i++) { + // 将十六进制字符串转换为整数,作为字符的Unicode码点 + int index = Integer.parseInt(hex[i], 16); + // 将Unicode码点转换为对应字符并添加到结果中 + sb.append((char) index); + } + return sb.toString(); + } } diff --git a/src/com/mingliqiye/utils/system/SystemUtil.java b/src/main/java/com/mingliqiye/utils/system/SystemUtil.java similarity index 100% rename from src/com/mingliqiye/utils/system/SystemUtil.java rename to src/main/java/com/mingliqiye/utils/system/SystemUtil.java diff --git a/src/com/mingliqiye/utils/time/DateTime.java b/src/main/java/com/mingliqiye/utils/time/DateTime.java similarity index 100% rename from src/com/mingliqiye/utils/time/DateTime.java rename to src/main/java/com/mingliqiye/utils/time/DateTime.java diff --git a/src/com/mingliqiye/utils/time/DateTimeOffset.java b/src/main/java/com/mingliqiye/utils/time/DateTimeOffset.java similarity index 100% rename from src/com/mingliqiye/utils/time/DateTimeOffset.java rename to src/main/java/com/mingliqiye/utils/time/DateTimeOffset.java diff --git a/src/com/mingliqiye/utils/time/DateTimeUnit.java b/src/main/java/com/mingliqiye/utils/time/DateTimeUnit.java similarity index 100% rename from src/com/mingliqiye/utils/time/DateTimeUnit.java rename to src/main/java/com/mingliqiye/utils/time/DateTimeUnit.java diff --git a/src/com/mingliqiye/utils/time/Formatter.java b/src/main/java/com/mingliqiye/utils/time/Formatter.java similarity index 100% rename from src/com/mingliqiye/utils/time/Formatter.java rename to src/main/java/com/mingliqiye/utils/time/Formatter.java diff --git a/src/com/mingliqiye/utils/time/serialization/Jackson.java b/src/main/java/com/mingliqiye/utils/time/serialization/Jackson.java similarity index 100% rename from src/com/mingliqiye/utils/time/serialization/Jackson.java rename to src/main/java/com/mingliqiye/utils/time/serialization/Jackson.java diff --git a/src/com/mingliqiye/utils/time/typehandlers/DateTimeTypeHandler.java b/src/main/java/com/mingliqiye/utils/time/typehandlers/DateTimeTypeHandler.java similarity index 100% rename from src/com/mingliqiye/utils/time/typehandlers/DateTimeTypeHandler.java rename to src/main/java/com/mingliqiye/utils/time/typehandlers/DateTimeTypeHandler.java diff --git a/src/com/mingliqiye/utils/uuid/MysqlUUIDv1.java b/src/main/java/com/mingliqiye/utils/uuid/MysqlUUIDv1.java similarity index 100% rename from src/com/mingliqiye/utils/uuid/MysqlUUIDv1.java rename to src/main/java/com/mingliqiye/utils/uuid/MysqlUUIDv1.java diff --git a/src/com/mingliqiye/utils/uuid/UUID.java b/src/main/java/com/mingliqiye/utils/uuid/UUID.java similarity index 92% rename from src/com/mingliqiye/utils/uuid/UUID.java rename to src/main/java/com/mingliqiye/utils/uuid/UUID.java index 67f77ce..8d70c27 100644 --- a/src/com/mingliqiye/utils/uuid/UUID.java +++ b/src/main/java/com/mingliqiye/utils/uuid/UUID.java @@ -16,7 +16,7 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile UUID.java - * LastUpdate 2025-09-09 08:37:33 + * LastUpdate 2025-09-10 11:14:27 * UpdateUser MingLiPro */ @@ -58,10 +58,14 @@ public class UUID implements Serializable { } /** - * 构造一个基于当前时间的时间戳型 UUID(版本1)。 + * 构造一个基于当前时间的时间戳型 UUID(版本1)。
+ * 由于springboot 默认使用此构造函数构造UUID 导致致命BUG 废弃
+ * 下个大版本删除
+ * @deprecated 请使用 UUID.getTimeBased() */ + @Deprecated public UUID() { - uuid = UuidCreator.getTimeBased(); + uuid = UUID.getTimeBased().GetUUID(); } /** @@ -82,6 +86,15 @@ public class UUID implements Serializable { this.uuid = java.util.UUID.fromString(uuid); } + /** + * 获取一个基于当前时间生成的时间戳型 UUID(版本1)。 + * + * @return 时间戳型 UUID + */ + public static UUID getTimeBased() { + return new UUID(UuidCreator.getTimeBased()); + } + /** * 将字节数组转换为 UUID 实例。 * @@ -110,10 +123,7 @@ public class UUID implements Serializable { return null; } try { - java.util.UUID uuid1 = java.util.UUID.fromString(data); - UUID uuid = new UUID(); - uuid.setUuid(uuid1); - return uuid; + return new UUID(java.util.UUID.fromString(data)); } catch (Exception e) { throw new UUIDException(e.getMessage(), e); } diff --git a/src/com/mingliqiye/utils/uuid/UUIDException.java b/src/main/java/com/mingliqiye/utils/uuid/UUIDException.java similarity index 100% rename from src/com/mingliqiye/utils/uuid/UUIDException.java rename to src/main/java/com/mingliqiye/utils/uuid/UUIDException.java diff --git a/src/com/mingliqiye/utils/uuid/serialization/Jackson.java b/src/main/java/com/mingliqiye/utils/uuid/serialization/Jackson.java similarity index 100% rename from src/com/mingliqiye/utils/uuid/serialization/Jackson.java rename to src/main/java/com/mingliqiye/utils/uuid/serialization/Jackson.java diff --git a/src/com/mingliqiye/utils/uuid/typehandlers/UUIDBinaryTypeHandler.java b/src/main/java/com/mingliqiye/utils/uuid/typehandlers/UUIDBinaryTypeHandler.java similarity index 100% rename from src/com/mingliqiye/utils/uuid/typehandlers/UUIDBinaryTypeHandler.java rename to src/main/java/com/mingliqiye/utils/uuid/typehandlers/UUIDBinaryTypeHandler.java diff --git a/src/com/mingliqiye/utils/uuid/typehandlers/UUIDConverter.java b/src/main/java/com/mingliqiye/utils/uuid/typehandlers/UUIDConverter.java similarity index 100% rename from src/com/mingliqiye/utils/uuid/typehandlers/UUIDConverter.java rename to src/main/java/com/mingliqiye/utils/uuid/typehandlers/UUIDConverter.java diff --git a/src/com/mingliqiye/utils/uuid/typehandlers/UUIDStringTypeHandler.java b/src/main/java/com/mingliqiye/utils/uuid/typehandlers/UUIDStringTypeHandler.java similarity index 100% rename from src/com/mingliqiye/utils/uuid/typehandlers/UUIDStringTypeHandler.java rename to src/main/java/com/mingliqiye/utils/uuid/typehandlers/UUIDStringTypeHandler.java diff --git a/src/com/mingliqiye/utils/version/VersionUtils.java b/src/main/java/com/mingliqiye/utils/version/VersionUtils.java similarity index 100% rename from src/com/mingliqiye/utils/version/VersionUtils.java rename to src/main/java/com/mingliqiye/utils/version/VersionUtils.java diff --git a/resources/META-INF/meta-data b/src/main/resources/META-INF/meta-data similarity index 100% rename from resources/META-INF/meta-data rename to src/main/resources/META-INF/meta-data diff --git a/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports similarity index 100% rename from resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports rename to src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports