diff --git a/build.gradle.kts b/build.gradle.kts index 8c87925..ba806c4 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-17 12:08:42 + * LastUpdate 2025-09-19 09:39:33 * UpdateUser MingLiPro */ @@ -99,7 +99,7 @@ tasks.withType { manifest { attributes( mapOf( - "Main-Class" to "com.mingliqiye.utils.Main", + "Main-Class" to "com.mingliqiye.utils.main.Main", "Specification-Title" to ARTIFACTID, "Specification-Version" to VERSIONS, "Specification-Vendor" to "minglipro", diff --git a/gradle.properties b/gradle.properties index b7aba5d..62be1e0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,13 +16,13 @@ # ProjectName mingli-utils # ModuleName mingli-utils # CurrentFile gradle.properties -# LastUpdate 2025-09-17 21:09:18 +# LastUpdate 2025-09-20 14:01:07 # UpdateUser MingLiPro # JDKVERSIONS=1.8 GROUPSID=com.mingliqiye.utils ARTIFACTID=mingli-utils -VERSIONS=4.1.4 +VERSIONS=4.1.6 signing.keyId=B22AA93B signing.password= signing.secretKeyRingFile=secret.gpg diff --git a/jdk8/build.gradle.kts b/jdk8/build.gradle.kts index 1c8393c..13c06da 100644 --- a/jdk8/build.gradle.kts +++ b/jdk8/build.gradle.kts @@ -16,7 +16,7 @@ * ProjectName mingli-utils * ModuleName mingli-utils.jdk8 * CurrentFile build.gradle.kts - * LastUpdate 2025-09-17 11:07:31 + * LastUpdate 2025-09-19 21:35:53 * UpdateUser MingLiPro */ diff --git a/src/main/kotlin/com/mingliqiye/utils/bean/annotation/ComponentBean.kt b/src/main/java/com/mingliqiye/utils/stream/StreamEmptyException.java similarity index 56% rename from src/main/kotlin/com/mingliqiye/utils/bean/annotation/ComponentBean.kt rename to src/main/java/com/mingliqiye/utils/stream/StreamEmptyException.java index a99b7e4..14b8bcc 100644 --- a/src/main/kotlin/com/mingliqiye/utils/bean/annotation/ComponentBean.kt +++ b/src/main/java/com/mingliqiye/utils/stream/StreamEmptyException.java @@ -15,29 +15,20 @@ * * ProjectName mingli-utils * ModuleName mingli-utils.main - * CurrentFile ComponentBean.kt - * LastUpdate 2025-09-15 22:32:50 + * CurrentFile StreamEmptyException.java + * LastUpdate 2025-09-20 13:24:07 * UpdateUser MingLiPro */ -package com.mingliqiye.utils.bean.annotation +package com.mingliqiye.utils.stream; -import kotlin.annotation.AnnotationRetention.RUNTIME -import kotlin.annotation.AnnotationTarget.CLASS -import kotlin.annotation.AnnotationTarget.FIELD +public class StreamEmptyException extends java.lang.RuntimeException { -/** - * 组件bean注解 - * @author MingLiPro - */ -@Retention(RUNTIME) -@Target(CLASS) -annotation class ComponentBean(val value: String = "") + public StreamEmptyException(String message) { + super(message); + } -/** - * 注入bean注解 - * @author MingLiPro - */ -@Retention(RUNTIME) -@Target(FIELD) -annotation class InjectBean(val value: String = "") + public StreamEmptyException(String message, Throwable cause) { + super(message, cause); + } +} 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..d268101 --- /dev/null +++ b/src/main/java/com/mingliqiye/utils/stream/SuperStream.java @@ -0,0 +1,1135 @@ +/* + * 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-20 13:24:35 + * UpdateUser MingLiPro + */ + +package com.mingliqiye.utils.stream; + +import com.mingliqiye.utils.collection.Collections; +import com.mingliqiye.utils.foreach.ForEach; +import com.mingliqiye.utils.functions.P1Function; +import com.mingliqiye.utils.functions.P2Function; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.Array; +import java.util.*; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.*; +import java.util.stream.*; + + +/** + * SuperStream 是对 Java 原生 Stream 的增强封装类,提供更便捷的流式操作接口。 + * 它支持链式调用,并扩展了部分原生 Stream 不支持的功能,例如带索引的 forEach 操作。 + * + * @param 流中元素的类型 + */ +public class SuperStream implements Stream { + + private final Stream stream; + + /** + * 构造方法,将传入的 Stream 包装为 SuperStream。 + * + * @param stream 要包装的原始 Stream + */ + private SuperStream(Stream stream) { + this.stream = stream; + } + + /** + * 将指定的 Stream 包装为 SuperStream。 + * + * @param stream 原始 Stream + * @param 流中元素的类型 + * @return 包装后的 SuperStream 实例 + */ + public static SuperStream of(Stream stream) { + return new SuperStream<>(stream); + } + + public static SuperStream of(T[] ts, boolean parallel) { + return of(Collections.newArrayLists(ts), parallel); + } + + public static SuperStream of(T[] ts) { + return of(ts, false); + } + + /** + * 将指定的 Collection 转换为 SuperStream,默认为顺序流。 + * + * @param collection 原始集合 + * @param 集合中元素的类型 + * @return 包装后的 SuperStream 实例 + */ + public static SuperStream of(Collection collection) { + return of(collection, false); + } + + /** + * 将指定的 Map 转换为 SuperStream,默认为顺序流。 + * + * @param map 原始 Map + * @param Map 键的类型 + * @param Map 值的类型 + * @return 包含 Map.Entry 的 SuperStream 实例 + */ + public static SuperStream> of(Map map) { + return of(map.entrySet(), false); + } + + /** + * 将指定的 Map 转换为 SuperStream,可选择是否为并行流。 + * + * @param map 原始 Map + * @param parallel 是否使用并行流 + * @param Map 键的类型 + * @param Map 值的类型 + * @return 包含 Map.Entry 的 SuperStream 实例 + */ + public static SuperStream> of(Map map, boolean parallel) { + return SuperStream.of(map.entrySet(), parallel); + } + + /** + * 将指定的 Collection 转换为 SuperStream,可选择是否为并行流。 + * + * @param stream 原始集合 + * @param parallel 是否使用并行流 + * @param 集合中元素的类型 + * @return 包装后的 SuperStream 实例 + */ + public static SuperStream of(Collection stream, boolean parallel) { + return parallel ? SuperStream.of(stream.parallelStream()) : SuperStream.of(stream.stream()); + } + + /** + * 返回一个用于收集 Double 类型统计信息的 Collector。 + * + * @param mapper 映射函数,将元素转换为 double 值 + * @param 元素类型 + * @return Collector 实例 + */ + public static Collector summarizingDouble(@NotNull ToDoubleFunction mapper) { + return Collectors.summarizingDouble(mapper); + } + + /** + * 返回一个用于收集 Long 类型统计信息的 Collector。 + * + * @param mapper 映射函数,将元素转换为 long 值 + * @param 元素类型 + * @return Collector 实例 + */ + public static Collector summarizingLong(@NotNull ToLongFunction mapper) { + return Collectors.summarizingLong(mapper); + } + + /** + * 返回一个用于收集 Integer 类型统计信息的 Collector。 + * + * @param mapper 映射函数,将元素转换为 int 值 + * @param 元素类型 + * @return Collector 实例 + */ + public static Collector summarizingInt(@NotNull ToIntFunction mapper) { + return Collectors.summarizingInt(mapper); + } + + /** + * 返回一个用于收集元素到 ConcurrentMap 的 Collector,支持自定义合并策略和 Map 工厂。 + * + * @param keyMapper 键映射函数 + * @param valueMapper 值映射函数 + * @param mergeFunction 合并函数 + * @param mapSupplier Map 工厂 + * @param 元素类型 + * @param 键类型 + * @param 值类型 + * @param Map 类型 + * @return Collector 实例 + */ + public static > Collector toConcurrentMap( + @NotNull Function keyMapper, + @NotNull Function valueMapper, + @NotNull BinaryOperator mergeFunction, + @NotNull Supplier mapSupplier) { + return Collectors.toConcurrentMap(keyMapper, valueMapper, mergeFunction, mapSupplier); + } + + /** + * 返回一个用于收集元素到 ConcurrentMap 的 Collector,支持自定义合并策略。 + * + * @param keyMapper 键映射函数 + * @param valueMapper 值映射函数 + * @param mergeFunction 合并函数 + * @param 元素类型 + * @param 键类型 + * @param 值类型 + * @return Collector 实例 + */ + public static Collector> toConcurrentMap( + @NotNull Function keyMapper, + @NotNull Function valueMapper, + @NotNull BinaryOperator mergeFunction) { + return Collectors.toConcurrentMap(keyMapper, valueMapper, mergeFunction); + } + + /** + * 返回一个用于收集元素到 ConcurrentMap 的 Collector。 + * + * @param keyMapper 键映射函数 + * @param valueMapper 值映射函数 + * @param 元素类型 + * @param 键类型 + * @param 值类型 + * @return Collector 实例 + */ + public static Collector> toConcurrentMap( + @NotNull Function keyMapper, + @NotNull Function valueMapper) { + return Collectors.toConcurrentMap(keyMapper, valueMapper); + } + + /** + * 返回一个用于收集元素到 Map 的 Collector,支持自定义合并策略和 Map 工厂。 + * + * @param keyMapper 键映射函数 + * @param valueMapper 值映射函数 + * @param mergeFunction 合并函数 + * @param mapSupplier Map 工厂 + * @param 元素类型 + * @param 键类型 + * @param 值类型 + * @param Map 类型 + * @return Collector 实例 + */ + public static > Collector toMap( + @NotNull Function keyMapper, + @NotNull Function valueMapper, + @NotNull BinaryOperator mergeFunction, + @NotNull Supplier mapSupplier) { + return Collectors.toMap(keyMapper, valueMapper, mergeFunction, mapSupplier); + } + + /** + * 返回一个用于收集元素到 Map 的 Collector,支持自定义合并策略。 + * + * @param keyMapper 键映射函数 + * @param valueMapper 值映射函数 + * @param mergeFunction 合并函数 + * @param 元素类型 + * @param 键类型 + * @param 值类型 + * @return Collector 实例 + */ + public static Collector> toMap( + @NotNull Function keyMapper, + @NotNull Function valueMapper, + @NotNull BinaryOperator mergeFunction) { + return Collectors.toMap(keyMapper, valueMapper, mergeFunction); + } + + /** + * 返回一个用于收集元素到 Map 的 Collector。 + * + * @param keyMapper 键映射函数 + * @param valueMapper 值映射函数 + * @param 元素类型 + * @param 键类型 + * @param 值类型 + * @return Collector 实例 + */ + public static Collector> toMap( + @NotNull Function keyMapper, + @NotNull Function valueMapper) { + return Collectors.toMap(keyMapper, valueMapper); + } + + /** + * 返回一个用于根据条件将元素分组到两个列表中的 Collector。 + * + * @param predicate 判断条件 + * @param downstream 下游 Collector + * @param 元素类型 + * @param 下游结果类型 + * @return Collector 实例 + */ + public static Collector> partitioningBy( + @NotNull Predicate predicate, + @NotNull Collector downstream) { + return Collectors.partitioningBy(predicate, downstream); + } + + /** + * 返回一个用于根据条件将元素分组到两个列表中的 Collector。 + * + * @param predicate 判断条件 + * @param 元素类型 + * @return Collector 实例 + */ + public static Collector>> partitioningBy(@NotNull Predicate predicate) { + return Collectors.partitioningBy(predicate); + } + + /** + * 返回一个用于并发分组的 Collector,支持自定义 Map 工厂和下游 Collector。 + * + * @param classifier 分类函数 + * @param mapFactory Map 工厂 + * @param downstream 下游 Collector + * @param 元素类型 + * @param 键类型 + * @param 下游结果类型 + * @param 下游中间类型 + * @param Map 类型 + * @return Collector 实例 + */ + public static > Collector groupingByConcurrent( + @NotNull Function classifier, + @NotNull Supplier mapFactory, + @NotNull Collector downstream) { + return Collectors.groupingByConcurrent(classifier, mapFactory, downstream); + } + + /** + * 返回一个用于并发分组的 Collector,支持自定义下游 Collector。 + * + * @param classifier 分类函数 + * @param downstream 下游 Collector + * @param 元素类型 + * @param 键类型 + * @param 下游中间类型 + * @param 下游结果类型 + * @return Collector 实例 + */ + public static Collector> groupingByConcurrent( + @NotNull Function classifier, + @NotNull Collector downstream) { + return Collectors.groupingByConcurrent(classifier, downstream); + } + + /** + * 返回一个用于并发分组的 Collector。 + * + * @param classifier 分类函数 + * @param 元素类型 + * @param 键类型 + * @return Collector 实例 + */ + public static Collector>> groupingByConcurrent( + @NotNull Function classifier) { + return Collectors.groupingByConcurrent(classifier); + } + + /** + * 返回一个用于分组的 Collector,支持自定义 Map 工厂和下游 Collector。 + * + * @param classifier 分类函数 + * @param mapFactory Map 工厂 + * @param downstream 下游 Collector + * @param 元素类型 + * @param 键类型 + * @param 下游结果类型 + * @param 下游中间类型 + * @param Map 类型 + * @return Collector 实例 + */ + public static > Collector groupingBy( + @NotNull Function classifier, + @NotNull Supplier mapFactory, + @NotNull Collector downstream) { + return Collectors.groupingBy(classifier, mapFactory, downstream); + } + + /** + * 返回一个用于分组的 Collector,支持自定义下游 Collector。 + * + * @param classifier 分类函数 + * @param downstream 下游 Collector + * @param 元素类型 + * @param 键类型 + * @param 下游中间类型 + * @param 下游结果类型 + * @return Collector 实例 + */ + public static Collector> groupingBy( + @NotNull Function classifier, + @NotNull Collector downstream) { + return Collectors.groupingBy(classifier, downstream); + } + + /** + * 返回一个用于分组的 Collector。 + * + * @param classifier 分类函数 + * @param 元素类型 + * @param 键类型 + * @return Collector 实例 + */ + public static Collector>> groupingBy(@NotNull Function classifier) { + return Collectors.groupingBy(classifier); + } + + /** + * 返回一个用于归约的 Collector,支持映射和合并操作。 + * + * @param identity 初始值 + * @param mapper 映射函数 + * @param op 合并函数 + * @param 元素类型 + * @param 结果类型 + * @return Collector 实例 + */ + public static Collector reducing(U identity, @NotNull Function mapper, @NotNull BinaryOperator op) { + return Collectors.reducing(identity, mapper, op); + } + + /** + * 返回一个用于归约的 Collector。 + * + * @param op 合并函数 + * @param 元素类型 + * @return Collector 实例 + */ + public static Collector> reducing(@NotNull BinaryOperator op) { + return Collectors.reducing(op); + } + + /** + * 返回一个用于归约的 Collector,支持初始值。 + * + * @param identity 初始值 + * @param op 合并函数 + * @param 元素类型 + * @return Collector 实例 + */ + public static Collector reducing(T identity, @NotNull BinaryOperator op) { + return Collectors.reducing(identity, op); + } + + /** + * 返回一个用于计算平均值的 Collector,适用于 double 类型。 + * + * @param mapper 映射函数 + * @param 元素类型 + * @return Collector 实例 + */ + public static Collector averagingDouble(@NotNull ToDoubleFunction mapper) { + return Collectors.averagingDouble(mapper); + } + + /** + * 返回一个用于计算平均值的 Collector,适用于 long 类型。 + * + * @param mapper 映射函数 + * @param 元素类型 + * @return Collector 实例 + */ + public static Collector averagingLong(@NotNull ToLongFunction mapper) { + return Collectors.averagingLong(mapper); + } + + /** + * 返回一个用于计算平均值的 Collector,适用于 int 类型。 + * + * @param mapper 映射函数 + * @param 元素类型 + * @return Collector 实例 + */ + public static Collector averagingInt(@NotNull ToIntFunction mapper) { + return Collectors.averagingInt(mapper); + } + + /** + * 返回一个用于求和的 Collector,适用于 double 类型。 + * + * @param mapper 映射函数 + * @param 元素类型 + * @return Collector 实例 + */ + public static Collector summingDouble(@NotNull ToDoubleFunction mapper) { + return Collectors.summingDouble(mapper); + } + + /** + * 返回一个用于求和的 Collector,适用于 long 类型。 + * + * @param mapper 映射函数 + * @param 元素类型 + * @return Collector 实例 + */ + public static Collector summingLong(@NotNull ToLongFunction mapper) { + return Collectors.summingLong(mapper); + } + + /** + * 返回一个用于求和的 Collector,适用于 int 类型。 + * + * @param mapper 映射函数 + * @param 元素类型 + * @return Collector 实例 + */ + public static Collector summingInt(@NotNull ToIntFunction mapper) { + return Collectors.summingInt(mapper); + } + + /** + * 返回一个用于查找最大值的 Collector。 + * + * @param comparator 比较器 + * @param 元素类型 + * @return Collector 实例 + */ + public static Collector> maxBy(@NotNull Comparator comparator) { + return Collectors.maxBy(comparator); + } + + /** + * 返回一个用于查找最小值的 Collector。 + * + * @param comparator 比较器 + * @param 元素类型 + * @return Collector 实例 + */ + public static Collector> minBy(@NotNull Comparator comparator) { + return Collectors.minBy(comparator); + } + + /** + * 返回一个用于计数的 Collector。 + * + * @param 元素类型 + * @return Collector 实例 + */ + public static Collector counting() { + return Collectors.counting(); + } + + /** + * 返回一个用于在下游收集后进行后续处理的 Collector。 + * + * @param downstream 下游 Collector + * @param finisher 后续处理函数 + * @param 元素类型 + * @param 下游中间类型 + * @param 下游结果类型 + * @param 最终结果类型 + * @return Collector 实例 + */ + public static Collector collectingAndThen( + @NotNull Collector downstream, + @NotNull Function finisher) { + return Collectors.collectingAndThen(downstream, finisher); + } + + /** + * 返回一个用于映射后收集的 Collector。 + * + * @param mapper 映射函数 + * @param downstream 下游 Collector + * @param 元素类型 + * @param 映射后的类型 + * @param 下游中间类型 + * @param 下游结果类型 + * @return Collector 实例 + */ + public static Collector mapping( + @NotNull Function mapper, + @NotNull Collector downstream) { + return Collectors.mapping(mapper, downstream); + } + + /** + * 返回一个用于连接字符串的 Collector,支持前缀、后缀和分隔符。 + * + * @param delimiter 分隔符 + * @param prefix 前缀 + * @param suffix 后缀 + * @return Collector 实例 + */ + public static Collector joining(@NotNull CharSequence delimiter, @NotNull CharSequence prefix, @NotNull CharSequence suffix) { + return Collectors.joining(delimiter, prefix, suffix); + } + + /** + * 返回一个用于连接字符串的 Collector,支持分隔符。 + * + * @param delimiter 分隔符 + * @return Collector 实例 + */ + public static Collector joining(@NotNull CharSequence delimiter) { + return Collectors.joining(delimiter); + } + + /** + * 返回一个用于连接字符串的 Collector。 + * + * @return Collector 实例 + */ + public static Collector joining() { + return Collectors.joining(); + } + + /** + * 返回一个用于收集元素到 Set 的 Collector。 + * + * @param 元素类型 + * @return Collector 实例 + */ + public static Collector> toSet() { + return Collectors.toSet(); + } + + /** + * 返回一个用于收集元素到 List 的 Collector。 + * + * @param 元素类型 + * @return Collector 实例 + */ + public static Collector> toList() { + return Collectors.toList(); + } + + /** + * 返回一个用于收集元素到指定集合类型的 Collector。 + * + * @param collectionFactory 集合工厂 + * @param 元素类型 + * @param 集合类型 + * @return Collector 实例 + */ + public static > Collector toCollection(@NotNull Supplier collectionFactory) { + return Collectors.toCollection(collectionFactory); + } + + /** + * 返回一个用于收集元素到 Map 的 Collector,键由 keyMapper 提供,值为元素本身。 + * + * @param keyMapper 键映射函数 + * @param 元素类型 + * @param 键类型 + * @return Collector 实例 + */ + public static Collector> toMap(Function keyMapper) { + return toMap(keyMapper, Function.identity()); + } + + /** + * 返回一个用于收集 Map.Entry 到 Map 的 Collector。 + * + * @param Map.Entry 类型 + * @param 键类型 + * @param 值类型 + * @return Collector 实例 + */ + public static , K, V> Collector> toMap() { + return Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue); + } + + /** + * 过滤流中的元素。 + * + * @param predicate 过滤条件 + * @return 过滤后的 SuperStream 实例 + */ + public SuperStream filter(Predicate predicate) { + return SuperStream.of(stream.filter(predicate)); + } + + /** + * 使用指定的 Collector 收集流中的元素。 + * + * @param collector Collector 实例 + * @param 结果类型 + * @param 中间类型 + * @return 收集结果 + */ + public R collect(Collector collector) { + return stream.collect(collector); + } + + /** + * 返回此流的Spliterator对象 + * + * @return 此流的Spliterator对象,用于并行处理流中的元素 + */ + @NotNull + public Spliterator spliterator() { + return stream.spliterator(); + } + + /** + * 将此流中的每个元素转换为一个IntStream,然后将所有生成的IntStream连接成一个IntStream + * + * @param mapper 用于将流中每个元素转换为IntStream的函数 + * @return 由所有转换后的IntStream连接而成的新IntStream + */ + public IntStream flatMapToInt(Function mapper) { + return stream.flatMapToInt(mapper); + } + + /** + * 判断此流是否为并行流 + * + * @return 如果此流是并行流则返回true,否则返回false + */ + public boolean isParallel() { + return stream.isParallel(); + } + + /** + * 返回此流的迭代器对象 + * + * @return 此流的迭代器对象,用于顺序访问流中的元素 + */ + @NotNull + public Iterator iterator() { + return stream.iterator(); + } + + + /** + * 对流中每个元素执行指定操作。 + * + * @param action 操作函数 + */ + public void forEach(P1Function action) { + stream.forEach(action::call); + } + + /** + * 对流中每个元素执行指定操作,并传入元素索引。 + * + * @param action 操作函数,接受元素和索引 + */ + public void forEach(P2Function action) { + AtomicInteger i22 = new AtomicInteger(0); + stream.forEach(i -> { + action.call(i, i22.getAndAdd(1)); + }); + } + + /** + * 对流中的每个元素执行给定的操作。 + * + * @param action 要对每个元素执行的操作,不能为 null + */ + public void forEach(Consumer action) { + stream.forEach(action); + } + + /** + * 将流中的每个元素转换为一个流,并将这些流合并为一个流。 + * + * @param mapper 用于将每个元素映射为流的函数,不能为 null + * @param 映射后流中元素的类型 + * @return 合并后的流 + */ + public Stream flatMap(Function> mapper) { + return stream.flatMap(mapper); + } + + /** + * 返回一个顺序执行的流。 + * + * @return 顺序执行的 SuperStream 实例 + */ + @NotNull + public SuperStream sequential() { + return SuperStream.of(stream.sequential()); + } + + /** + * 跳过流中的前 n 个元素。 + * + * @param n 要跳过的元素数量 + * @return 跳过元素后的 SuperStream 实例 + */ + public SuperStream skip(long n) { + return SuperStream.of(stream.skip(n)); + } + + /** + * 使用提供的供应器、累加器和组合器对流进行归约操作。 + * + * @param supplier 结果容器的供应器 + * @param accumulator 将元素累积到结果容器中的函数 + * @param combiner 合并两个结果容器的函数 + * @param 结果容器的类型 + * @return 归约后的结果 + */ + public R collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner) { + return stream.collect(supplier, accumulator, combiner); + } + + /** + * 返回一个并行执行的流。 + * + * @return 并行执行的 SuperStream 实例 + */ + @NotNull + public SuperStream parallel() { + return SuperStream.of(stream.parallel()); + } + + /** + * 将流中的每个元素映射为 DoubleStream,并将这些流合并为一个 DoubleStream。 + * + * @param mapper 用于将每个元素映射为 DoubleStream 的函数,不能为 null + * @return 合并后的 DoubleStream + */ + public DoubleStream flatMapToDouble(Function mapper) { + return stream.flatMapToDouble(mapper); + } + + /** + * 使用提供的生成器函数将流转换为数组。 + * + * @param generator 用于创建数组的函数 + * @param 数组元素的类型 + * @return 转换后的数组 + */ + @NotNull + public A[] toArray(IntFunction generator) { + return stream.toArray(generator); + } + + /** + * 返回流中的第一个元素(如果存在)。 + * + * @return 包含第一个元素的 Optional,如果流为空则返回空 Optional + */ + @NotNull + public Optional findFirst() { + return stream.findFirst(); + } + + /** + * 返回一个无序的流。 + * + * @return 无序的 SuperStream 实例 + */ + @NotNull + public SuperStream unordered() { + return SuperStream.of(stream.unordered()); + } + + /** + * 根据提供的比较器返回流中的最小元素(如果存在)。 + * + * @param comparator 用于比较元素的比较器,不能为 null + * @return 包含最小元素的 Optional,如果流为空则返回空 Optional + */ + @NotNull + public Optional min(Comparator comparator) { + return stream.min(comparator); + } + + /** + * 返回流中的任意元素(如果存在)。 + * + * @return 包含任意元素的 Optional,如果流为空则返回空 Optional + */ + @NotNull + public Optional findAny() { + return stream.findAny(); + } + + /** + * 注册一个关闭处理器,在流关闭时执行。 + * + * @param closeHandler 流关闭时要执行的处理器,不能为 null + * @return 注册了关闭处理器的 SuperStream 实例 + */ + @NotNull + public SuperStream onClose(@NotNull Runnable closeHandler) { + return SuperStream.of(stream.onClose(closeHandler)); + } + + /** + * 将流中的每个元素映射为 LongStream,并将这些流合并为一个 LongStream。 + * + * @param mapper 用于将每个元素映射为 LongStream 的函数,不能为 null + * @return 合并后的 LongStream + */ + public LongStream flatMapToLong(Function mapper) { + return stream.flatMapToLong(mapper); + } + + /** + * 将流转换为数组。
+ * 使用反射获取类型 是空的的话抛出 + * {@code StreamEmptyException } + * + * @return 转换后的数组 + * @throws StreamEmptyException 如果流为空 + * @see StreamEmptyException + */ + @NotNull + @SuppressWarnings("unchecked") + public T[] toArray() { + List list = toAList(); + if (list.isEmpty()) { + throw new StreamEmptyException("Stream is empty"); + } + T[] items = (T[]) Array.newInstance(list.get(0).getClass(), list.size()); + ForEach.forEach(list, (v, i) -> { + items[i] = v; + }); + return items; + } + + /** + * 按照 encounter order 对流中的每个元素执行给定的操作。 + * + * @param action 要对每个元素执行的操作,不能为 null + */ + public void forEachOrdered(Consumer action) { + stream.forEachOrdered(action); + } + + /** + * 关闭流并释放相关资源。 + */ + public void close() { + stream.close(); + } + + /** + * 使用提供的累加器函数对流进行归约操作。 + * + * @param accumulator 用于归约的累加器函数 + * @return 包含归约结果的 Optional,如果流为空则返回空 Optional + */ + @NotNull + public Optional reduce(BinaryOperator accumulator) { + return stream.reduce(accumulator); + } + + /** + * 根据提供的比较器对流进行排序。 + * + * @param comparator 用于排序的比较器,不能为 null + * @return 排序后的 SuperStream 实例 + */ + public SuperStream sorted(Comparator comparator) { + return SuperStream.of(stream.sorted(comparator)); + } + + /** + * 检查流中的所有元素是否都满足给定的谓词。 + * + * @param predicate 用于测试元素的谓词,不能为 null + * @return 如果所有元素都满足谓词则返回 true,否则返回 false + */ + public boolean allMatch(Predicate predicate) { + return stream.allMatch(predicate); + } + + /** + * 对流中的元素进行自然排序。 + * + * @return 排序后的 SuperStream 实例 + */ + public SuperStream sorted() { + return SuperStream.of(stream.sorted()); + } + + /** + * 返回流中元素的数量。 + * + * @return 元素的数量 + */ + public long count() { + return stream.count(); + } + + /** + * 将流中的每个元素通过映射函数转换为另一种类型。 + * + * @param mapper 用于映射元素的函数,不能为 null + * @param 映射后元素的类型 + * @return 映射后的 SuperStream 实例 + */ + public SuperStream map(Function mapper) { + return SuperStream.of(stream.map(mapper)); + } + + /** + * 使用提供的标识值和累加器函数对流进行归约操作。 + * + * @param identity 归约的初始值 + * @param accumulator 用于归约的累加器函数 + * @return 归约后的结果 + */ + public T reduce(T identity, BinaryOperator accumulator) { + return stream.reduce(identity, accumulator); + } + + /** + * 检查流中是否没有任何元素满足给定的谓词。 + * + * @param predicate 用于测试元素的谓词,不能为 null + * @return 如果没有任何元素满足谓词则返回 true,否则返回 false + */ + public boolean noneMatch(Predicate predicate) { + return stream.noneMatch(predicate); + } + + /** + * 返回一个去除重复元素后的流。 + * + * @return 去重后的 SuperStream 实例 + */ + public SuperStream distinct() { + return SuperStream.of(stream.distinct()); + } + + /** + * 根据提供的比较器返回流中的最大元素(如果存在)。 + * + * @param comparator 用于比较元素的比较器,不能为 null + * @return 包含最大元素的 Optional,如果流为空则返回空 Optional + */ + @NotNull + public Optional max(Comparator comparator) { + return stream.max(comparator); + } + + /** + * 将流中的每个元素映射为 double 值,并返回一个 DoubleStream。 + * + * @param mapper 用于将元素映射为 double 的函数,不能为 null + * @return 映射后的 DoubleStream + */ + public DoubleStream mapToDouble(ToDoubleFunction mapper) { + return stream.mapToDouble(mapper); + } + + /** + * 限制流中元素的数量。 + * + * @param maxSize 最大元素数量 + * @return 限制后的 SuperStream 实例 + */ + public SuperStream limit(long maxSize) { + return SuperStream.of(stream.limit(maxSize)); + } + + /** + * 将流中的每个元素映射为 long 值,并返回一个 LongStream。 + * + * @param mapper 用于将元素映射为 long 的函数,不能为 null + * @return 映射后的 LongStream + */ + public LongStream mapToLong(ToLongFunction mapper) { + return stream.mapToLong(mapper); + } + + /** + * 对流中的每个元素执行给定的操作,并返回相同的流。 + * + * @param action 要对每个元素执行的操作,不能为 null + * @return 相同的 SuperStream 实例 + */ + public SuperStream peek(Consumer action) { + return SuperStream.of(stream.peek(action)); + } + + /** + * 使用提供的标识值、累加器函数和组合器对流进行归约操作。 + * + * @param identity 归约的初始值 + * @param accumulator 用于归约的累加器函数 + * @param combiner 用于合并部分结果的组合器函数 + * @param 归约结果的类型 + * @return 归约后的结果 + */ + public U reduce(U identity, BiFunction accumulator, BinaryOperator combiner) { + return stream.reduce(identity, accumulator, combiner); + } + + /** + * 将流中的每个元素映射为 int 值,并返回一个 IntStream。 + * + * @param mapper 用于将元素映射为 int 的函数,不能为 null + * @return 映射后的 IntStream + */ + public IntStream mapToInt(ToIntFunction mapper) { + return stream.mapToInt(mapper); + } + + /** + * 检查流中是否有任何元素满足给定的谓词。 + * + * @param predicate 用于测试元素的谓词,不能为 null + * @return 如果有任何元素满足谓词则返回 true,否则返回 false + */ + public boolean anyMatch(Predicate predicate) { + return stream.anyMatch(predicate); + } + + + /** + * 获取原始 Stream。 + * + * @return 原始 Stream 实例 + */ + public Stream getStream() { + return stream; + } + + /** + * 将流中的元素收集到 Map 中。 + * + * @param keyMapper 键映射函数 + * @param valueMapper 值映射函数 + * @param 键类型 + * @param 值类型 + * @return 收集结果 Map + */ + public Map toAMap(Function keyMapper, Function valueMapper) { + return collect(toMap(keyMapper, valueMapper)); + } + + /** + * 将流中的元素收集到 Map 中,值为元素本身。 + * + * @param keyMapper 键映射函数 + * @param 键类型 + * @return 收集结果 Map + */ + public Map toAMap(Function keyMapper) { + return collect(toMap(keyMapper)); + } + + /** + * 将流中的元素收集到 List 中。 + * + * @return 收集结果 List + */ + public List toAList() { + return collect(toList()); + } + +} diff --git a/src/main/kotlin/com/mingliqiye/utils/aes/AesUtils.kt b/src/main/kotlin/com/mingliqiye/utils/aes/AesUtils.kt index 1ed9757..7861276 100644 --- a/src/main/kotlin/com/mingliqiye/utils/aes/AesUtils.kt +++ b/src/main/kotlin/com/mingliqiye/utils/aes/AesUtils.kt @@ -16,7 +16,7 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile AesUtils.kt - * LastUpdate 2025-09-17 10:40:03 + * LastUpdate 2025-09-19 21:35:53 * UpdateUser MingLiPro */ @@ -121,3 +121,4 @@ private fun createSecretKey(sKey: String): SecretKeySpec { val digest = md.digest(key) return SecretKeySpec(digest, ALGORITHM) } + diff --git a/src/main/kotlin/com/mingliqiye/utils/base/Base256.kt b/src/main/kotlin/com/mingliqiye/utils/base/Base256.kt index d9a356f..77d9766 100644 --- a/src/main/kotlin/com/mingliqiye/utils/base/Base256.kt +++ b/src/main/kotlin/com/mingliqiye/utils/base/Base256.kt @@ -16,7 +16,7 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile Base256.kt - * LastUpdate 2025-09-18 14:36:40 + * LastUpdate 2025-09-20 14:01:29 * UpdateUser MingLiPro */ @@ -311,7 +311,3 @@ class Base256 : BaseCodec { return result } } - -fun main() { - -} diff --git a/src/main/kotlin/com/mingliqiye/utils/base/Base91.kt b/src/main/kotlin/com/mingliqiye/utils/base/Base91.kt index 342b0cf..ba31a2b 100644 --- a/src/main/kotlin/com/mingliqiye/utils/base/Base91.kt +++ b/src/main/kotlin/com/mingliqiye/utils/base/Base91.kt @@ -16,7 +16,7 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile Base91.kt - * LastUpdate 2025-09-18 14:42:59 + * LastUpdate 2025-09-19 20:08:46 * UpdateUser MingLiPro */ @@ -402,10 +402,3 @@ class Base91 : BaseCodec { return buffer.copyOf(index) } } - -fun main() { - val base91 = Base91() - val bytes = "Hello, World!".toByteArray() - val encoded = base91.encode(bytes) - println(encoded) -} diff --git a/src/main/kotlin/com/mingliqiye/utils/base/BaseUtils.kt b/src/main/kotlin/com/mingliqiye/utils/base/BaseUtils.kt index 5d7a3c3..ac4d998 100644 --- a/src/main/kotlin/com/mingliqiye/utils/base/BaseUtils.kt +++ b/src/main/kotlin/com/mingliqiye/utils/base/BaseUtils.kt @@ -16,7 +16,7 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile BaseUtils.kt - * LastUpdate 2025-09-18 14:36:40 + * LastUpdate 2025-09-19 20:18:09 * UpdateUser MingLiPro */ @@ -60,3 +60,4 @@ val BASE256: BaseCodec by lazy { Base256() } + diff --git a/src/main/kotlin/com/mingliqiye/utils/bcrypt/BCrypt.kt b/src/main/kotlin/com/mingliqiye/utils/bcrypt/BCrypt.kt index 65e982e..7780a71 100644 --- a/src/main/kotlin/com/mingliqiye/utils/bcrypt/BCrypt.kt +++ b/src/main/kotlin/com/mingliqiye/utils/bcrypt/BCrypt.kt @@ -16,7 +16,7 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile BCrypt.kt - * LastUpdate 2025-09-18 09:46:16 + * LastUpdate 2025-09-19 20:17:41 * UpdateUser MingLiPro */ @@ -57,4 +57,3 @@ fun gensalt(long: Int): String { fun gensalt(long: Int, secureRandom: SecureRandom): String { return JBCrypt.gensalt(long, secureRandom) } - diff --git a/src/main/kotlin/com/mingliqiye/utils/bean/Factory.kt b/src/main/kotlin/com/mingliqiye/utils/bean/Factory.kt deleted file mode 100644 index 44c8730..0000000 --- a/src/main/kotlin/com/mingliqiye/utils/bean/Factory.kt +++ /dev/null @@ -1,241 +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 Factory.kt - * LastUpdate 2025-09-15 22:32:50 - * UpdateUser MingLiPro - */ -@file:JvmName("Factory") - -package com.mingliqiye.utils.bean - -import com.mingliqiye.utils.bean.annotation.ComponentBean -import com.mingliqiye.utils.bean.annotation.InjectBean -import java.io.File -import java.net.URL -import java.util.* -import java.util.concurrent.ConcurrentHashMap -import kotlin.reflect.KClass - -/** - * 存储所有已注册的Bean实例,键为Bean名称,值为Bean实例 - */ -private val BEANS: ConcurrentHashMap = ConcurrentHashMap() - -/** - * 存储按类型查找的Bean实例,键为Bean的Class对象,值为Bean实例 - */ -private val TYPE_BEANS: ConcurrentHashMap, Any> = ConcurrentHashMap() - -/** - * 自动扫描指定类所在包下的所有类并注册为Bean - * - * @param c 指定的类,用于获取其所在的包 - * @throws IllegalArgumentException 如果传入的类为null或位于默认包中 - */ -fun autoScan(c: Class<*>?) { - if (c == null) { - throw IllegalArgumentException("Class cannot be null") - } - val pkg = c.`package` - if (pkg == null) { - throw IllegalArgumentException("Class is in the default package") - } - scan(pkg.name) -} - -/** - * 扫描指定包路径下的所有类文件,并注册其中带有@ComponentBean注解的类为Bean - * - * @param basePackage 要扫描的基础包名 - * @throws RuntimeException 如果在扫描过程中发生异常 - */ -fun scan(basePackage: String) { - try { - val path = basePackage.replace('.', '/') - val classLoader = Thread.currentThread().contextClassLoader - val resources: Enumeration = classLoader.getResources(path) - while (resources.hasMoreElements()) { - val resource = resources.nextElement() - val file = File(resource.toURI()) - scanDirectory(file, basePackage) - } - injectDependencies() - } catch (e: Exception) { - throw RuntimeException(e) - } -} - -/** - * 递归扫描目录中的所有类文件,并注册符合条件的类为Bean - * - * @param directory 当前要扫描的目录 - * @param packageName 当前目录对应的包名 - * @throws Exception 如果在扫描或类加载过程中发生异常 - */ -private fun scanDirectory(directory: File, packageName: String) { - val files = directory.listFiles() ?: return - - for (file in files) { - if (file.isDirectory) { - scanDirectory(file, "$packageName.${file.name}") - } else if (file.name.endsWith(".class")) { - val className = packageName + '.' + file.name.replace(".class", "") - registerComponent(Class.forName(className)) - } - } -} - -/** - * 注册一个带有@ComponentBean注解的类为Bean实例 - * - * @param clazz 要注册的类 - * @throws Exception 如果在实例化类或处理注解时发生异常 - */ -private fun registerComponent(clazz: Class<*>) { - if (clazz.isAnnotationPresent(ComponentBean::class.java)) { - val component = clazz.getAnnotation(ComponentBean::class.java) - val name = component.value.ifEmpty { clazz.name } - val instance = clazz.getDeclaredConstructor().newInstance() - BEANS[name] = instance - val kClass = clazz.kotlin - TYPE_BEANS[kClass] = instance - - for (interfaceClass in clazz.interfaces) { - TYPE_BEANS.putIfAbsent(interfaceClass.kotlin, instance) - } - } -} - -/** - * 对所有已注册的Bean进行依赖注入处理 - * - * @throws Exception 如果在注入过程中发生异常 - */ -private fun injectDependencies() { - for (bean in BEANS.values) { - for (field in bean.javaClass.declaredFields) { - if (field.isAnnotationPresent(InjectBean::class.java)) { - val inject = field.getAnnotation(InjectBean::class.java) - val dependency = findDependency(field.type, inject.value) - if (dependency == null) { - throw IllegalStateException( - "No suitable dependency found for field " + field.name + " in class " + bean.javaClass.name - ) - } - field.isAccessible = true - field.set(bean, dependency) - } - } - } -} - -/** - * 根据类型和名称查找对应的依赖实例 - * - * @param type 依赖的类型 - * @param name 依赖的名称(可为空) - * @return 找到的依赖实例,未找到则返回null - */ -private fun findDependency(type: Class<*>, name: String): Any? { - if (name.isNotEmpty()) { - return BEANS[name] - } - - val dependency = TYPE_BEANS[type.kotlin] - if (dependency != null) { - return dependency - } - - for (interfaceType in TYPE_BEANS.keys) { - if (type.isAssignableFrom(interfaceType.java)) { - return TYPE_BEANS[interfaceType] - } - } - - return null -} - -/** - * 将一个对象添加到Bean容器中,使用其类名作为键 - * - * @param obj 要添加的对象 - * @throws RuntimeException 如果在注入依赖时发生异常 - */ -fun add(obj: Any) { - val clazz = obj.javaClass - val name = clazz.name - BEANS[name] = obj - TYPE_BEANS[clazz.kotlin] = obj - try { - injectDependencies() - } catch (e: Exception) { - throw RuntimeException(e) - } -} - -/** - * 将一个对象以指定名称添加到Bean容器中 - * - * @param name Bean的名称 - * @param obj 要添加的对象 - * @throws RuntimeException 如果在注入依赖时发生异常 - */ -fun add(name: String, obj: Any) { - BEANS[name] = obj - TYPE_BEANS[obj.javaClass.kotlin] = obj - try { - injectDependencies() - } catch (e: Exception) { - throw RuntimeException(e) - } -} - -/** - * 根据类型获取对应的Bean实例 - * - * @param objclass Bean的类型 - * @param T Bean的泛型类型 - * @return 对应类型的Bean实例,未找到则返回null - */ -@Suppress("UNCHECKED_CAST") -fun get(objclass: KClass): T? { - return TYPE_BEANS[objclass] as? T -} - -/** - * 根据名称和类型获取对应的Bean实例 - * - * @param name Bean的名称 - * @param objclass Bean的类型 - * @param T Bean的泛型类型 - * @return 对应名称和类型的Bean实例,未找到则返回null - */ -@Suppress("UNCHECKED_CAST") -fun get(name: String, objclass: KClass): T? { - return BEANS[name] as? T -} - -/** - * 根据名称获取对应的Bean实例 - * - * @param name Bean的名称 - * @return 对应名称的Bean实例,未找到则返回null - */ -fun get(name: String): Any? { - return BEANS[name] -} diff --git a/src/main/kotlin/com/mingliqiye/utils/bytes/ByteUtils.kt b/src/main/kotlin/com/mingliqiye/utils/bytes/ByteUtils.kt index 47e2366..b189cc0 100644 --- a/src/main/kotlin/com/mingliqiye/utils/bytes/ByteUtils.kt +++ b/src/main/kotlin/com/mingliqiye/utils/bytes/ByteUtils.kt @@ -16,13 +16,15 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile ByteUtils.kt - * LastUpdate 2025-09-16 16:55:36 + * LastUpdate 2025-09-20 11:49:05 * UpdateUser MingLiPro */ @file:JvmName("ByteUtils") package com.mingliqiye.utils.bytes +import com.mingliqiye.utils.stream.SuperStream + const val ESC_ASC: Byte = 0x10 const val ESC_DESC: Byte = 0x1B const val ESC_NONE: Byte = 0x00 @@ -40,7 +42,7 @@ const val ESC_RESERVED: Byte = 0x06 */ fun ByteArray.getByteArrayString(): MutableList { return this.toList().stream().map { a -> String.format("0X%02X", a!!.toInt() and 0xFF) } - .collect(com.mingliqiye.utils.stream.toList()) as MutableList + .collect(SuperStream.toList()) as MutableList } diff --git a/src/main/kotlin/com/mingliqiye/utils/clone/CloneUtils.kt b/src/main/kotlin/com/mingliqiye/utils/clone/CloneUtils.kt index 9dd97e7..5900668 100644 --- a/src/main/kotlin/com/mingliqiye/utils/clone/CloneUtils.kt +++ b/src/main/kotlin/com/mingliqiye/utils/clone/CloneUtils.kt @@ -16,7 +16,7 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile CloneUtils.kt - * LastUpdate 2025-09-15 09:30:37 + * LastUpdate 2025-09-20 14:01:29 * UpdateUser MingLiPro */ @file:JvmName("CloneUtils") @@ -38,8 +38,7 @@ inline fun T.deepJsonClone(jsonApi: JsonApi): T { } catch (e: Exception) { throw JsonException( - "Failed to deep clone object using JSON", - e + "Failed to deep clone object using JSON", e ) } } diff --git a/src/main/kotlin/com/mingliqiye/utils/collection/Collection.kt b/src/main/kotlin/com/mingliqiye/utils/collection/Collection.kt index 40558bf..0559e57 100644 --- a/src/main/kotlin/com/mingliqiye/utils/collection/Collection.kt +++ b/src/main/kotlin/com/mingliqiye/utils/collection/Collection.kt @@ -16,7 +16,7 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile Collection.kt - * LastUpdate 2025-09-15 17:26:00 + * LastUpdate 2025-09-20 14:01:07 * UpdateUser MingLiPro */ @@ -24,22 +24,47 @@ package com.mingliqiye.utils.collection +import com.mingliqiye.utils.stream.SuperStream import java.util.* import java.util.stream.Collectors +/** + * 将当前集合转换为数组。 + * + * @param T 集合元素类型 + * @return 转换后的数组 + */ inline fun Collection.toArray(): Array { return arrayOf(*this.toTypedArray()) } +/** + * 将当前集合转换为 Map,其中键为集合元素本身,值由给定函数生成。 + * + * @param T 集合元素类型 + * @param V 映射值的类型 + * @param v 用于生成映射值的函数 + * @return 转换后的 Map + */ inline fun Collection.toMap(noinline v: (T) -> V): Map { return this.stream().collect( - com.mingliqiye.utils.stream.toMapValueThis( + SuperStream.toMap( v ) - ) + ) as Map } +/** + * 将当前集合转换为 Map,其中键和值分别由给定函数生成。 + * + * @param T 集合元素类型 + * @param V 映射值的类型 + * @param K 映射键的类型 + * @param k 用于生成映射键的函数 + * @param v 用于生成映射值的函数 + * @return 转换后的 Map + */ inline fun Collection.toMap(noinline k: (T) -> K, noinline v: (T) -> V): Map { return this.stream().collect( Collectors.toMap( @@ -48,11 +73,24 @@ inline fun Collection.toMap(noinline k: (T) -> K, noinline ) } +/** + * 将数组转换为 Set。 + * + * @param T 数组元素类型 + * @param array 输入数组 + * @return 转换后的 Set + */ fun toSet(array: Array): Set { return array.toSet() } +/** + * 获取集合中的第一个元素,如果集合为空则返回 null。 + * + * @param T 集合元素类型 + * @return 第一个元素或 null + */ inline fun Collection.getFirst(): T? { if (this.isEmpty()) { return null @@ -63,6 +101,12 @@ inline fun Collection.getFirst(): T? { return this.iterator().next() } +/** + * 获取数组中的第一个元素,如果数组为空则返回 null。 + * + * @param T 数组元素类型 + * @return 第一个元素或 null + */ inline fun Array.getFirst(): T? { if (this.isEmpty()) { return null @@ -70,6 +114,12 @@ inline fun Array.getFirst(): T? { return this.first() } +/** + * 获取集合中的最后一个元素,如果集合为空则返回 null。 + * + * @param T 集合元素类型 + * @return 最后一个元素或 null + */ inline fun Collection.getLast(): T? { if (this.isEmpty()) { return null @@ -84,6 +134,12 @@ inline fun Collection.getLast(): T? { return lastElement } +/** + * 获取数组中的最后一个元素,如果数组为空则返回 null。 + * + * @param T 数组元素类型 + * @return 最后一个元素或 null + */ inline fun Array.getLast(): T? { if (this.isEmpty()) { return null @@ -92,6 +148,14 @@ inline fun Array.getLast(): T? { } +/** + * 根据索引获取集合中的元素,若索引越界则返回默认值。 + * + * @param T 集合元素类型 + * @param index 索引位置 + * @param defaultValue 默认返回值 + * @return 指定索引处的元素或默认值 + */ inline fun Collection.getOrDefault( index: Int, defaultValue: T ): T { @@ -111,54 +175,135 @@ inline fun Collection.getOrDefault( return defaultValue } +/** + * 创建一个新的 ArrayList 实例。 + * + * @param T 元素类型 + * @return 新创建的 ArrayList + */ fun newArrayList(): ArrayList { return ArrayList() } +/** + * 创建一个指定初始容量的新 ArrayList 实例。 + * + * @param T 元素类型 + * @param size 初始容量大小 + * @return 新创建的 ArrayList + */ fun newArrayList(size: Int): ArrayList { return ArrayList() } +/** + * 使用可变参数创建一个新的 ArrayList 实例。 + * + * @param T 元素类型 + * @param elements 可变参数列表 + * @return 新创建的 ArrayList + */ fun newArrayList(vararg elements: T): ArrayList { return newArrayList(elements.asList()) } +/** + * 将当前集合转换为新的 ArrayList 实例。 + * + * @param T 元素类型 + * @return 新创建的 ArrayList + */ fun Collection.newArrayLists(): ArrayList { return newArrayList(this) } +/** + * 将数组转换为新的 ArrayList 实例。 + * + * @param T 元素类型 + * @param elements 输入数组 + * @return 新创建的 ArrayList + */ fun newArrayLists(elements: Array): ArrayList { return newArrayList(elements.asList()) } +/** + * 将集合转换为新的 ArrayList 实例。 + * + * @param T 元素类型 + * @param elements 输入集合 + * @return 新创建的 ArrayList + */ fun newArrayList(elements: Collection): ArrayList { return ArrayList(elements.toList()) } +/** + * 将 Iterable 转换为新的 ArrayList 实例。 + * + * @param T 元素类型 + * @param elements 输入 Iterable + * @return 新创建的 ArrayList + */ fun newArrayList(elements: Iterable): ArrayList { return newArrayList(elements.toList()) } +/** + * 将 Sequence 转换为新的 ArrayList 实例。 + * + * @param T 元素类型 + * @param elements 输入 Sequence + * @return 新创建的 ArrayList + */ fun newArrayList(elements: Sequence): ArrayList { return newArrayList(elements.toList()) } +/** + * 创建一个新的 LinkedList 实例。 + * + * @param T 元素类型 + * @return 新创建的 LinkedList + */ fun newLinkedList(): LinkedList { return LinkedList() } +/** + * 使用可变参数创建一个新的 LinkedList 实例。 + * + * @param T 元素类型 + * @param elements 可变参数列表 + * @return 新创建的 LinkedList + */ fun newLinkedList(vararg elements: T): LinkedList { val list = newLinkedList() list.addAll(elements.asList()) return list } +/** + * 将集合转换为新的 LinkedList 实例。 + * + * @param T 元素类型 + * @param elements 输入集合 + * @return 新创建的 LinkedList + */ fun newLinkedList(elements: Collection): LinkedList { val list = newLinkedList() list.addAll(elements) return list } +/** + * 将 Iterable 转换为新的 LinkedList 实例。 + * + * @param T 元素类型 + * @param elements 输入 Iterable + * @return 新创建的 LinkedList + */ fun newLinkedList(elements: Iterable): LinkedList { val list = newLinkedList() for (element in elements) { @@ -167,26 +312,60 @@ fun newLinkedList(elements: Iterable): LinkedList { return list } +/** + * 将 Sequence 转换为新的 LinkedList 实例。 + * + * @param T 元素类型 + * @param elements 输入 Sequence + * @return 新创建的 LinkedList + */ fun newLinkedList(elements: Sequence): LinkedList { return newLinkedList(elements.toList()) } +/** + * 创建一个新的 Vector 实例。 + * + * @param T 元素类型 + * @return 新创建的 Vector + */ fun newVector(): Vector { return Vector() } +/** + * 使用可变参数创建一个新的 Vector 实例。 + * + * @param T 元素类型 + * @param elements 可变参数列表 + * @return 新创建的 Vector + */ fun newVector(vararg elements: T): Vector { val vector = newVector() vector.addAll(elements.asList()) return vector } +/** + * 将集合转换为新的 Vector 实例。 + * + * @param T 元素类型 + * @param elements 输入集合 + * @return 新创建的 Vector + */ fun newVector(elements: Collection): Vector { val vector = newVector() vector.addAll(elements) return vector } +/** + * 将 Iterable 转换为新的 Vector 实例。 + * + * @param T 元素类型 + * @param elements 输入 Iterable + * @return 新创建的 Vector + */ fun newVector(elements: Iterable): Vector { val vector = newVector() for (element in elements) { @@ -195,31 +374,72 @@ fun newVector(elements: Iterable): Vector { return vector } +/** + * 将 Sequence 转换为新的 Vector 实例。 + * + * @param T 元素类型 + * @param elements 输入 Sequence + * @return 新创建的 Vector + */ fun newVector(elements: Sequence): Vector { return newVector(elements.toList()) } +/** + * 创建一个新的 HashSet 实例。 + * + * @param T 元素类型 + * @return 新创建的 HashSet + */ fun newHashSet(): HashSet { return HashSet() } +/** + * 创建一个指定初始容量的新 HashSet 实例。 + * + * @param T 元素类型 + * @param size 初始容量大小 + * @return 新创建的 HashSet + */ fun newHashSet(size: Int): HashSet { return HashSet(size) } +/** + * 使用可变参数创建一个新的 HashSet 实例。 + * + * @param T 元素类型 + * @param elements 可变参数列表 + * @return 新创建的 HashSet + */ fun newHashSet(vararg elements: T): HashSet { val set = newHashSet() set.addAll(elements.asList()) return set } +/** + * 将集合转换为新的 HashSet 实例。 + * + * @param T 元素类型 + * @param elements 输入集合 + * @return 新创建的 HashSet + */ fun newHashSet(elements: Collection): HashSet { val set = newHashSet() set.addAll(elements) return set } +/** + * 将 Iterable 转换为新的 HashSet 实例。 + * + * @param T 元素类型 + * @param elements 输入 Iterable + * @return 新创建的 HashSet + */ fun newHashSet(elements: Iterable): HashSet { val set = newHashSet() for (element in elements) { @@ -228,30 +448,71 @@ fun newHashSet(elements: Iterable): HashSet { return set } +/** + * 将 Sequence 转换为新的 HashSet 实例。 + * + * @param T 元素类型 + * @param elements 输入 Sequence + * @return 新创建的 HashSet + */ fun newHashSet(elements: Sequence): HashSet { return newHashSet(elements.toSet()) } +/** + * 创建一个新的 LinkedHashSet 实例。 + * + * @param T 元素类型 + * @return 新创建的 LinkedHashSet + */ fun newLinkedHashSet(): LinkedHashSet { return LinkedHashSet() } +/** + * 创建一个指定初始容量的新 LinkedHashSet 实例。 + * + * @param T 元素类型 + * @param size 初始容量大小 + * @return 新创建的 LinkedHashSet + */ fun newLinkedHashSet(size: Int): LinkedHashSet { return LinkedHashSet(size) } +/** + * 使用可变参数创建一个新的 LinkedHashSet 实例。 + * + * @param T 元素类型 + * @param elements 可变参数列表 + * @return 新创建的 LinkedHashSet + */ fun newLinkedHashSet(vararg elements: T): LinkedHashSet { val set = newLinkedHashSet() set.addAll(elements.asList()) return set } +/** + * 将集合转换为新的 LinkedHashSet 实例。 + * + * @param T 元素类型 + * @param elements 输入集合 + * @return 新创建的 LinkedHashSet + */ fun newLinkedHashSet(elements: Collection): LinkedHashSet { val set = newLinkedHashSet() set.addAll(elements) return set } +/** + * 将 Iterable 转换为新的 LinkedHashSet 实例。 + * + * @param T 元素类型 + * @param elements 输入 Iterable + * @return 新创建的 LinkedHashSet + */ fun newLinkedHashSet(elements: Iterable): LinkedHashSet { val set = newLinkedHashSet() for (element in elements) { @@ -260,26 +521,60 @@ fun newLinkedHashSet(elements: Iterable): LinkedHashSet { return set } +/** + * 将 Sequence 转换为新的 LinkedHashSet 实例。 + * + * @param T 元素类型 + * @param elements 输入 Sequence + * @return 新创建的 LinkedHashSet + */ fun newLinkedHashSet(elements: Sequence): LinkedHashSet { return newLinkedHashSet(elements.toSet()) } +/** + * 创建一个新的 TreeSet 实例。 + * + * @param T 元素类型,必须实现 Comparable 接口 + * @return 新创建的 TreeSet + */ fun > newTreeSet(): TreeSet { return TreeSet() } +/** + * 使用可变参数创建一个新的 TreeSet 实例。 + * + * @param T 元素类型,必须实现 Comparable 接口 + * @param elements 可变参数列表 + * @return 新创建的 TreeSet + */ fun > newTreeSet(vararg elements: T): TreeSet { val set = newTreeSet() set.addAll(elements.asList()) return set } +/** + * 将集合转换为新的 TreeSet 实例。 + * + * @param T 元素类型,必须实现 Comparable 接口 + * @param elements 输入集合 + * @return 新创建的 TreeSet + */ fun > newTreeSet(elements: Collection): TreeSet { val set = newTreeSet() set.addAll(elements) return set } +/** + * 将 Iterable 转换为新的 TreeSet 实例。 + * + * @param T 元素类型,必须实现 Comparable 接口 + * @param elements 输入 Iterable + * @return 新创建的 TreeSet + */ fun > newTreeSet(elements: Iterable): TreeSet { val set = newTreeSet() for (element in elements) { @@ -288,65 +583,160 @@ fun > newTreeSet(elements: Iterable): TreeSet { return set } +/** + * 将 Sequence 转换为新的 TreeSet 实例。 + * + * @param T 元素类型,必须实现 Comparable 接口 + * @param elements 输入 Sequence + * @return 新创建的 TreeSet + */ fun > newTreeSet(elements: Sequence): TreeSet { return newTreeSet(elements.toSet()) } +/** + * 将字节数组转换为 ArrayList。 + * + * @param elements 输入字节数组 + * @return 转换后的 ArrayList + */ fun newArrayLists(elements: ByteArray): ArrayList { return ArrayList(elements.toList()) } +/** + * 将短整型数组转换为 ArrayList。 + * + * @param elements 输入短整型数组 + * @return 转换后的 ArrayList + */ fun newArrayLists(elements: ShortArray): ArrayList { return ArrayList(elements.toList()) } +/** + * 将整型数组转换为 ArrayList。 + * + * @param elements 输入整型数组 + * @return 转换后的 ArrayList + */ fun newArrayLists(elements: IntArray): ArrayList { return ArrayList(elements.toList()) } +/** + * 将长整型数组转换为 ArrayList。 + * + * @param elements 输入长整型数组 + * @return 转换后的 ArrayList + */ fun newArrayLists(elements: LongArray): ArrayList { return ArrayList(elements.toList()) } +/** + * 将浮点数组转换为 ArrayList。 + * + * @param elements 输入浮点数组 + * @return 转换后的 ArrayList + */ fun newArrayLists(elements: FloatArray): ArrayList { return ArrayList(elements.toList()) } +/** + * 将双精度浮点数组转换为 ArrayList。 + * + * @param elements 输入双精度浮点数组 + * @return 转换后的 ArrayList + */ fun newArrayLists(elements: DoubleArray): ArrayList { return ArrayList(elements.toList()) } +/** + * 将布尔数组转换为 ArrayList。 + * + * @param elements 输入布尔数组 + * @return 转换后的 ArrayList + */ fun newArrayLists(elements: BooleanArray): ArrayList { return ArrayList(elements.toList()) } +/** + * 将字符数组转换为 ArrayList。 + * + * @param elements 输入字符数组 + * @return 转换后的 ArrayList + */ fun newArrayLists(elements: CharArray): ArrayList { return ArrayList(elements.toList()) } +/** + * 创建一个新的 CopyOnWriteArrayList 实例。 + * + * @param T 元素类型 + * @return 新创建的 CopyOnWriteArrayList + */ fun newCopyOnWriteArrayList(): java.util.concurrent.CopyOnWriteArrayList { return java.util.concurrent.CopyOnWriteArrayList() } +/** + * 使用可变参数创建一个新的 CopyOnWriteArrayList 实例。 + * + * @param T 元素类型 + * @param elements 可变参数列表 + * @return 新创建的 CopyOnWriteArrayList + */ fun newCopyOnWriteArrayList(vararg elements: T): java.util.concurrent.CopyOnWriteArrayList { return java.util.concurrent.CopyOnWriteArrayList(elements.asList()) } +/** + * 将集合转换为新的 CopyOnWriteArrayList 实例。 + * + * @param T 元素类型 + * @param elements 输入集合 + * @return 新创建的 CopyOnWriteArrayList + */ fun newCopyOnWriteArrayList(elements: Collection): java.util.concurrent.CopyOnWriteArrayList { return java.util.concurrent.CopyOnWriteArrayList(elements) } +/** + * 创建一个新的 Stack 实例。 + * + * @param T 元素类型 + * @return 新创建的 Stack + */ fun newStack(): Stack { return Stack() } +/** + * 使用可变参数创建一个新的 Stack 实例。 + * + * @param T 元素类型 + * @param elements 可变参数列表 + * @return 新创建的 Stack + */ fun newStack(vararg elements: T): Stack { val stack = newStack() stack.addAll(elements.asList()) return stack } +/** + * 将集合转换为新的 Stack 实例。 + * + * @param T 元素类型 + * @param elements 输入集合 + * @return 新创建的 Stack + */ fun newStack(elements: Collection): Stack { val stack = newStack() stack.addAll(elements) @@ -354,22 +744,53 @@ fun newStack(elements: Collection): Stack { } +/** + * 创建一个新的 TreeSet 实例,并指定比较器。 + * + * @param T 元素类型 + * @param comparator 用于排序的比较器 + * @return 新创建的 TreeSet + */ fun newTreeSet(comparator: Comparator): TreeSet { return TreeSet(comparator) } +/** + * 使用可变参数创建一个新的 TreeSet 实例,并指定比较器。 + * + * @param T 元素类型 + * @param comparator 用于排序的比较器 + * @param elements 可变参数列表 + * @return 新创建的 TreeSet + */ fun newTreeSet(comparator: Comparator, vararg elements: T): TreeSet { val set = newTreeSet(comparator) set.addAll(elements.asList()) return set } +/** + * 将集合转换为新的 TreeSet 实例,并指定比较器。 + * + * @param T 元素类型 + * @param comparator 用于排序的比较器 + * @param elements 输入集合 + * @return 新创建的 TreeSet + */ fun newTreeSet(comparator: Comparator, elements: Collection): TreeSet { val set = newTreeSet(comparator) set.addAll(elements) return set } +/** + * 将 Iterable 转换为新的 TreeSet 实例,并指定比较器。 + * + * @param T 元素类型 + * @param comparator 用于排序的比较器 + * @param elements 输入 Iterable + * @return 新创建的 TreeSet + */ fun newTreeSet(comparator: Comparator, elements: Iterable): TreeSet { val set = newTreeSet(comparator) for (element in elements) { @@ -378,32 +799,71 @@ fun newTreeSet(comparator: Comparator, elements: Iterable): TreeSet return set } +/** + * 将 Sequence 转换为新的 TreeSet 实例,并指定比较器。 + * + * @param T 元素类型 + * @param comparator 用于排序的比较器 + * @param elements 输入 Sequence + * @return 新创建的 TreeSet + */ fun newTreeSet(comparator: Comparator, elements: Sequence): TreeSet { return newTreeSet(comparator, elements.toSet()) } +/** + * 将当前集合转换为新的 CopyOnWriteArrayList 实例。 + * + * @param T 元素类型 + * @return 新创建的 CopyOnWriteArrayList + */ fun Collection.newCopyOnWriteArrayLists(): java.util.concurrent.CopyOnWriteArrayList { return java.util.concurrent.CopyOnWriteArrayList(this) } +/** + * 将当前集合转换为新的 Stack 实例。 + * + * @param T 元素类型 + * @return 新创建的 Stack + */ fun Collection.newStacks(): Stack { val stack = Stack() stack.addAll(this) return stack } +/** + * 将当前集合转换为新的 TreeSet 实例。 + * + * @param T 元素类型,必须实现 Comparable 接口 + * @return 新创建的 TreeSet + */ fun Collection.newTreeSets(): TreeSet where T : Comparable { val set = TreeSet() set.addAll(this) return set } +/** + * 将当前集合转换为新的 TreeSet 实例,并指定比较器。 + * + * @param T 元素类型 + * @param comparator 用于排序的比较器 + * @return 新创建的 TreeSet + */ fun Collection.newTreeSets(comparator: Comparator): TreeSet { val set = TreeSet(comparator) set.addAll(this) return set } +/** + * 将 Byte 类型的 List 转换为字节数组。 + * + * @param list 输入的 Byte 列表 + * @return 转换后的字节数组 + */ fun toArray(list: List): ByteArray { val arr = ByteArray(list.size) for (i in list.indices) { @@ -413,6 +873,12 @@ fun toArray(list: List): ByteArray { } +/** + * 将 Short 类型的 List 转换为短整型数组。 + * + * @param list 输入的 Short 列表 + * @return 转换后的短整型数组 + */ fun toArray(list: List): ShortArray { val arr = ShortArray(list.size) for (i in list.indices) { @@ -421,6 +887,12 @@ fun toArray(list: List): ShortArray { return arr } +/** + * 将 Int 类型的 List 转换为整型数组。 + * + * @param list 输入的 Int 列表 + * @return 转换后的整型数组 + */ fun toArray(list: List): IntArray { val arr = IntArray(list.size) for (i in list.indices) { @@ -429,6 +901,12 @@ fun toArray(list: List): IntArray { return arr } +/** + * 将 Long 类型的 List 转换为长整型数组。 + * + * @param list 输入的 Long 列表 + * @return 转换后的长整型数组 + */ fun toArray(list: List): LongArray { val arr = LongArray(list.size) for (i in list.indices) { @@ -437,6 +915,12 @@ fun toArray(list: List): LongArray { return arr } +/** + * 将 Float 类型的 List 转换为浮点数组。 + * + * @param list 输入的 Float 列表 + * @return 转换后的浮点数组 + */ fun toArray(list: List): FloatArray { val arr = FloatArray(list.size) for (i in list.indices) { @@ -445,6 +929,12 @@ fun toArray(list: List): FloatArray { return arr } +/** + * 将 Double 类型的 List 转换为双精度浮点数组。 + * + * @param list 输入的 Double 列表 + * @return 转换后的双精度浮点数组 + */ fun toArray(list: List): DoubleArray { val arr = DoubleArray(list.size) for (i in list.indices) { @@ -453,6 +943,12 @@ fun toArray(list: List): DoubleArray { return arr } +/** + * 将 Boolean 类型的 List 转换为布尔数组。 + * + * @param list 输入的 Boolean 列表 + * @return 转换后的布尔数组 + */ fun toArray(list: List): BooleanArray { val arr = BooleanArray(list.size) for (i in list.indices) { @@ -461,6 +957,12 @@ fun toArray(list: List): BooleanArray { return arr } +/** + * 将 Char 类型的 List 转换为字符数组。 + * + * @param list 输入的 Char 列表 + * @return 转换后的字符数组 + */ fun toArray(list: List): CharArray { val arr = CharArray(list.size) for (i in list.indices) { @@ -468,3 +970,16 @@ fun toArray(list: List): CharArray { } return arr } + + +/** + * 将任意类型的 List 转换为数组。 + * + * @param T 元素类型 + * @param list 输入的 List + * @return 转换后的数组 + */ +fun toArray(list: List): Array { + return SuperStream.of(list) + .toArray() +} diff --git a/src/main/kotlin/com/mingliqiye/utils/concurrent/IsChanged.kt b/src/main/kotlin/com/mingliqiye/utils/concurrent/IsChanged.kt index af9c869..fcad409 100644 --- a/src/main/kotlin/com/mingliqiye/utils/concurrent/IsChanged.kt +++ b/src/main/kotlin/com/mingliqiye/utils/concurrent/IsChanged.kt @@ -16,7 +16,7 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile IsChanged.kt - * LastUpdate 2025-09-15 09:30:37 + * LastUpdate 2025-09-19 20:17:07 * UpdateUser MingLiPro */ diff --git a/src/main/kotlin/com/mingliqiye/utils/configuration/ConfigurationProp.kt b/src/main/kotlin/com/mingliqiye/utils/configuration/ConfigurationProp.kt new file mode 100644 index 0000000..37d44f6 --- /dev/null +++ b/src/main/kotlin/com/mingliqiye/utils/configuration/ConfigurationProp.kt @@ -0,0 +1,273 @@ +/* + * 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 ConfigurationProp.kt + * LastUpdate 2025-09-19 11:30:04 + * UpdateUser MingLiPro + */ + +package com.mingliqiye.utils.configuration + +/** + * 配置属性注解,用于标记配置类中的字段,支持通过命令行参数进行初始化。 + * + * @param name 配置项的名称,默认为空字符串,表示使用字段名作为配置项名称。 + * @param description 配置项的描述信息,默认为空字符串。 + * @param showHelper 是否显示帮助信息,默认为 true。 + */ +@Retention(AnnotationRetention.RUNTIME) +@Target( + AnnotationTarget.TYPE_PARAMETER, + AnnotationTarget.VALUE_PARAMETER, + AnnotationTarget.FIELD, // 添加字段支持 + AnnotationTarget.PROPERTY // 添加属性支持 +) +annotation class ConfigurationProp(val name: String = "", val description: String = "", val showHelper: Boolean = true) + +/** + * 根据字段名生成对应的 setter 方法名。 + * + * @param fieldName 字段名。 + * @return 对应的 setter 方法名。 + */ +private fun getSetterName(fieldName: String): String { + return "set" + fieldName.take(1).uppercase() + fieldName.substring(1) +} + +/** + * 根据字段名生成对应的 getter 方法名。 + * + * @param fieldName 字段名。 + * @return 对应的 getter 方法名。 + */ +private fun getGetterName(fieldName: String): String { + return "get" + fieldName.take(1).uppercase() + fieldName.substring(1) +} + +/** + * 配置初始化器,用于解析命令行参数并填充配置对象。 + */ +open class ConfigurationProps { + + companion object { + /** + * 初始化配置类实例,并根据命令行参数填充其字段。 + * + * @param clazz 配置类的 Class 对象。 + * @param args 命令行参数数组。 + * @return 初始化后的配置类实例。 + */ + @JvmStatic + fun init(clazz: Class, args: Array): T { + val mapsArgs = parseArguments(args) + val instance = clazz.getDeclaredConstructor().newInstance() + + processFields(clazz, instance, mapsArgs) + + return instance + } + + /** + * 解析命令行参数,将其转换为键值对映射。 + * + * 支持以下格式: + * - `--key=value` 或 `-k=value`:键值对形式。 + * - `--key value` 或 `-k value`:键和值分开的形式。 + * - `--flag` 或 `-f`:布尔标志形式,默认值为 "true"。 + * + * @param args 命令行参数数组。 + * @return 解析后的键值对映射。 + */ + private fun parseArguments(args: Array): Map> { + val mapsArgs = mutableMapOf>() + + var i = 0 + while (i < args.size) { + val arg = args[i] + + when { + arg.startsWith("--") -> { + // 处理 --key=value 格式 + if (arg.contains("=")) { + val (key, value) = arg.substring(2).split("=", limit = 2) + mapsArgs.getOrPut(key) { mutableListOf() }.add(value) + } + // 处理 --key value 格式 + else if (i + 1 < args.size && !args[i + 1].startsWith("-")) { + val key = arg.substring(2) + val value = args[i + 1] + mapsArgs.getOrPut(key) { mutableListOf() }.add(value) + i++ // 跳过下一个参数 + } + // 处理 --flag 格式的布尔标志 + else { + val key = arg.substring(2) + mapsArgs.getOrPut(key) { mutableListOf() }.add("true") + } + } + + arg.startsWith("-") -> { + // 处理 -k=value 格式 + if (arg.contains("=")) { + val (key, value) = arg.substring(1).split("=", limit = 2) + mapsArgs.getOrPut(key) { mutableListOf() }.add(value) + } + // 处理 -k value 格式 + else if (i + 1 < args.size && !args[i + 1].startsWith("-")) { + val key = arg.substring(1) + val value = args[i + 1] + mapsArgs.getOrPut(key) { mutableListOf() }.add(value) + i++ + } + // 处理 -f 格式的布尔标志 + else { + val key = arg.substring(1) + mapsArgs.getOrPut(key) { mutableListOf() }.add("true") + } + } + } + i++ + } + + return mapsArgs + } + + /** + * 处理配置类中的字段,根据解析出的参数设置字段值。 + * + * @param clazz 配置类的 Class 对象。 + * @param instance 配置类的实例。 + * @param mapsArgs 解析后的命令行参数映射。 + */ + private fun processFields( + clazz: Class, + instance: T, + mapsArgs: Map> + ) { + val fields = clazz.declaredFields + + for (field in fields) { + val configurationProp = field.getAnnotation(ConfigurationProp::class.java) + if (configurationProp != null) { + val fieldName = configurationProp.name.ifEmpty { field.name } + val values = mapsArgs[fieldName] + + if (values != null) { + try { + val setter = clazz.getDeclaredMethod( + getSetterName(field.name), + field.type + ) + + val value = convertValue(field.type, values, configurationProp) + setter.invoke(instance, value) + } catch (e: Exception) { + println("Warning: Failed to set field ${field.name}: ${e.message}") + } + } + } + } + } + + /** + * 将字符串值转换为目标类型。 + * + * @param type 目标类型。 + * @param values 字符串值列表。 + * @param annotation 配置属性注解。 + * @return 转换后的值。 + */ + private fun convertValue( + type: Class<*>, + values: List, + annotation: ConfigurationProp + ): Any? { + val lastValue = values.lastOrNull() ?: return null + + return when (type) { + String::class.java -> lastValue + + Integer::class.java, Int::class.java -> try { + lastValue.toInt() + } catch (e: NumberFormatException) { + println("Warning: Invalid integer value '$lastValue'") + null + } + + Long::class.java, java.lang.Long::class.java -> try { + lastValue.toLong() + } catch (e: NumberFormatException) { + println("Warning: Invalid long value '$lastValue'") + null + } + + Double::class.java, java.lang.Double::class.java -> try { + lastValue.toDouble() + } catch (e: NumberFormatException) { + println("Warning: Invalid double value '$lastValue'") + null + } + + Boolean::class.java, java.lang.Boolean::class.java -> when (lastValue.lowercase()) { + "true", "1", "yes", "on" -> true + "false", "0", "no", "off" -> false + else -> { + println("Warning: Invalid boolean value '$lastValue'") + null + } + } + + List::class.java -> values + + else -> { + println("Warning: Unsupported type ${type.simpleName}") + null + } + } + } + } + + fun printHelp() { + val fields = this::class.java.declaredFields + val help = StringBuilder() + for (field in fields) { + val configurationProp = field.getAnnotation(ConfigurationProp::class.java) + if (configurationProp != null && configurationProp.showHelper) { + val fieldName = configurationProp.name.ifEmpty { field.name } + help.append("$fieldName -> 类型: ${field.type.simpleName}") + if (configurationProp.description.isNotEmpty()) { + help.append(" 描述: ${configurationProp.description}") + } + help.append("\n") + } + } + println(help) + } + + val fields: Map + get() { + val fields = this::class.java.declaredFields + val fieldValues = mutableMapOf() + for (field in fields) { + field.isAccessible = true + val fieldName = field.name + val fieldValue = field.get(this) + fieldValues[fieldName] = fieldValue + } + return fieldValues + } +} diff --git a/src/main/kotlin/com/mingliqiye/utils/dto/DtoUtils.kt b/src/main/kotlin/com/mingliqiye/utils/dto/DtoUtils.kt new file mode 100644 index 0000000..344161f --- /dev/null +++ b/src/main/kotlin/com/mingliqiye/utils/dto/DtoUtils.kt @@ -0,0 +1,146 @@ +/* + * 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 DtoUtils.kt + * LastUpdate 2025-09-19 13:38:56 + * UpdateUser MingLiPro + */ + +@file:JvmName("DtoUtils") + +package com.mingliqiye.utils.dto + +import java.lang.reflect.Field + + +/** + * 克隆一个对象,通过反射创建新实例并复制所有非静态字段值。 + * + * @param obj 要克隆的对象,必须是非空的任意类型实例。 + * @return 返回一个新的对象实例,其字段值与原对象一致。 + */ +fun clone(obj: T): T { + val clazz = obj.javaClass + val constructor = clazz.getDeclaredConstructor().apply { + isAccessible = true + } + val instance = constructor.newInstance() + + // 遍历类及其父类的所有字段进行赋值 + var currentClass: Class<*>? = clazz + while (currentClass != null) { + currentClass.declaredFields.forEach { field -> + if (!java.lang.reflect.Modifier.isStatic(field.modifiers)) { + field.isAccessible = true + field.set(instance, field.get(obj)) + } + } + currentClass = currentClass.superclass + } + + return instance +} + +/** + * 定义 DTO 拷贝行为的枚举类型。 + */ +enum class DotCopyType { + /** + * 表示使用点拷贝(.copy)方式处理字段。 + */ + DOT_COPY, + + /** + * 表示普通拷贝方式处理字段。 + */ + COPY +} + +/** + * 标注用于控制 DTO 字段拷贝行为的注解。 + * + * @param type 指定拷贝类型,默认为 COPY。 + */ +@Retention(AnnotationRetention.RUNTIME) +@Target( + AnnotationTarget.TYPE_PARAMETER, + AnnotationTarget.VALUE_PARAMETER, + AnnotationTarget.FIELD, + AnnotationTarget.PROPERTY +) +annotation class DtoCopy(val type: DotCopyType = DotCopyType.COPY) + +/** + * 将源对象转换为目标 DTO 类型的实例,并根据字段名匹配拷贝字段值。 + * + * @param obj 源对象,包含需要被拷贝的数据。 + * @param dtoClass 目标 DTO 的 Class 对象。 + * @return 返回一个新的目标 DTO 实例,字段值已从源对象拷贝。 + */ +fun toDto(obj: Any, dtoClass: Class): R { + val instance = dtoClass.getDeclaredConstructor().apply { + isAccessible = true + }.newInstance() + + val sourceFields = getAllFields(obj.javaClass) + + for (sourceField in sourceFields) { + sourceField.isAccessible = true + val fieldName = sourceField.name + val fieldValue = sourceField.get(obj) + + try { + val targetField = dtoClass.getDeclaredField(fieldName).apply { + isAccessible = true + } + if (java.lang.reflect.Modifier.isStatic(targetField.modifiers)) { + continue + } + val ta = targetField.getAnnotation(DtoCopy::class.java) + if (ta != null) { + if (ta.type == DotCopyType.DOT_COPY) { + continue + } + } + targetField.set(instance, fieldValue) + + } catch (e: NoSuchFieldException) { + continue + } catch (e: IllegalArgumentException) { + continue + } + } + + return instance +} + +/** + * 获取指定类及其所有父类中声明的所有字段。 + * + * @param clazz 起始类对象。 + * @return 包含所有字段的列表。 + */ +private fun getAllFields(clazz: Class<*>): List { + val fields = mutableListOf() + var currentClass: Class<*>? = clazz + while (currentClass != null && currentClass != Any::class.java) { + fields.addAll(currentClass.declaredFields) + currentClass = currentClass.superclass + } + return fields +} + diff --git a/src/main/kotlin/com/mingliqiye/utils/hash/HashUtils.kt b/src/main/kotlin/com/mingliqiye/utils/hash/HashUtils.kt index 4462c3e..77e52cd 100644 --- a/src/main/kotlin/com/mingliqiye/utils/hash/HashUtils.kt +++ b/src/main/kotlin/com/mingliqiye/utils/hash/HashUtils.kt @@ -16,7 +16,7 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile HashUtils.kt - * LastUpdate 2025-09-17 16:20:57 + * LastUpdate 2025-09-19 20:24:33 * UpdateUser MingLiPro */ @file:JvmName("HashUtils") @@ -24,6 +24,7 @@ package com.mingliqiye.utils.hash +import com.mingliqiye.utils.base.BASE16 import com.mingliqiye.utils.bcrypt.checkpw import com.mingliqiye.utils.bcrypt.hashpw import java.io.File @@ -70,15 +71,7 @@ fun calculateFileHash(file: File, algorithm: String): String { * @return 对应的十六进制字符串 */ private fun bytesToHex(bytes: ByteArray): String { - val hexString = StringBuilder(2 * bytes.size) - for (b in bytes) { - val hex = Integer.toHexString(0xff and b.toInt()) - if (hex.length == 1) { - hexString.append('0') - } - hexString.append(hex) - } - return hexString.toString() + return BASE16.encode(bytes) } /** diff --git a/src/main/kotlin/com/mingliqiye/utils/io/IO.kt b/src/main/kotlin/com/mingliqiye/utils/io/IO.kt new file mode 100644 index 0000000..c5fe70f --- /dev/null +++ b/src/main/kotlin/com/mingliqiye/utils/io/IO.kt @@ -0,0 +1,63 @@ +/* + * 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 IO.kt + * LastUpdate 2025-09-20 11:46:19 + * UpdateUser MingLiPro + */ + +package com.mingliqiye.utils.io + + +fun Any?.println() { + IO.println(this) +} + + +class IO { + companion object { + + @JvmStatic + fun print(vararg args: Any?) { + print(" ", *args) + } + + @JvmStatic + fun println(vararg args: Any?) { + println(" ", *args) + } + + @JvmStatic + fun println(sp: String = " ", vararg args: Any?) { + print(" ", *args) + kotlin.io.println() + } + + @JvmStatic + fun print(sp: String = " ", vararg args: Any?) { + if (args.isEmpty()) { + kotlin.io.println() + } + val sb = StringBuilder() + for (i in args.indices) { + sb.append(args[i]) + if (i < args.size - 1) sb.append(sp) + } + kotlin.io.print(sb) + } + } +} diff --git a/src/main/kotlin/com/mingliqiye/utils/Main.kt b/src/main/kotlin/com/mingliqiye/utils/main/Main.kt similarity index 82% rename from src/main/kotlin/com/mingliqiye/utils/Main.kt rename to src/main/kotlin/com/mingliqiye/utils/main/Main.kt index a3a47cc..ba602e9 100644 --- a/src/main/kotlin/com/mingliqiye/utils/Main.kt +++ b/src/main/kotlin/com/mingliqiye/utils/main/Main.kt @@ -16,18 +16,20 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile Main.kt - * LastUpdate 2025-09-18 14:39:24 + * LastUpdate 2025-09-20 13:22:11 * UpdateUser MingLiPro */ @file:JvmName("Main") -package com.mingliqiye.utils +package com.mingliqiye.utils.main import com.mingliqiye.utils.springboot.autoconfigure.AutoConfiguration -import com.mingliqiye.utils.uuid.UUID - +import com.mingliqiye.utils.stream.SuperStream fun main() { AutoConfiguration.printBanner() - println(UUID.getV7().getBase256ShortString()) + val data = SuperStream.of(Array(0) { 1 }) + + + println(data) } diff --git a/src/main/kotlin/com/mingliqiye/utils/metadata/MetaData.kt b/src/main/kotlin/com/mingliqiye/utils/metadata/MetaData.kt new file mode 100644 index 0000000..23b5c8a --- /dev/null +++ b/src/main/kotlin/com/mingliqiye/utils/metadata/MetaData.kt @@ -0,0 +1,64 @@ +/* + * 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 MetaData.kt + * LastUpdate 2025-09-20 10:45:43 + * UpdateUser MingLiPro + */ +@file:JvmName("MetaData") + +package com.mingliqiye.utils.metadata + +import com.mingliqiye.utils.resource.ResourceUtils +import java.util.stream.Collectors.toMap + +fun getMetaData(): Map { + return ResourceUtils.getStringResource("/META-INF/meta-data").split("\n").stream().map { + if (it.isBlank()) { + return@map null + } + val split = it.split("=") + if (split.size == 2) { + split[0] to split[1] + } else { + return@map null + } + }.filter { it != null }.collect(toMap({ it!!.first }, { it!!.second })) +} + +class MingliUtilsMetaData { + var buildTime: String = "" + var groupId: String = "" + var artifactId: String = "" + var version: String = "" + var buildJdkVersion: String = "" + var author: String = "" + var website: String = "" +} + +val mingliUtilsMetaData: MingliUtilsMetaData by lazy { + val metaData = getMetaData() + MingliUtilsMetaData().apply { + buildTime = metaData["buildTime"] ?: "" + groupId = metaData["groupId"] ?: "" + artifactId = metaData["artifactId"] ?: "" + version = metaData["version"] ?: "" + buildJdkVersion = metaData["buildJdkVersion"] ?: "" + author = metaData["author"] ?: "" + website = metaData["website"] ?: "" + } +} diff --git a/src/main/kotlin/com/mingliqiye/utils/resource/ResourceUtils.kt b/src/main/kotlin/com/mingliqiye/utils/resource/ResourceUtils.kt new file mode 100644 index 0000000..4aacae0 --- /dev/null +++ b/src/main/kotlin/com/mingliqiye/utils/resource/ResourceUtils.kt @@ -0,0 +1,87 @@ +/* + * 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 ResourceUtils.kt + * LastUpdate 2025-09-20 10:26:47 + * UpdateUser MingLiPro + */ +package com.mingliqiye.utils.resource + +import java.io.IOException + +class ResourceUtils { + companion object { + @JvmStatic + @Throws(IOException::class) + fun getResource(resourceName: String): ByteArray { + return getResource(resourceName, ResourceUtils::class.java) + } + + @JvmStatic + @Throws(IOException::class) + fun getResource(resourceName: String, clazz: Class<*>): ByteArray { + return clazz.getResourceAsStream(resourceName)?.use { + it.readBytes() + } ?: throw IOException("Resource not found: $resourceName") + } + + + @JvmStatic + @Throws(IOException::class) + fun getStringResource(resourceName: String): String { + return getStringResource(resourceName, ResourceUtils::class.java) + } + + + @JvmStatic + @Throws(IOException::class) + fun getStringResource(resourceName: String, clazz: Class<*>): String { + return clazz.getResourceAsStream(resourceName)?.use { + it.readBytes().toString(charset = Charsets.UTF_8) + } ?: throw IOException("Resource not found: $resourceName") + } + + + @JvmStatic + @Throws(IOException::class) + fun getStringResourceCallers(resourceName: String): String { + return getStringResource(resourceName, getCallerClass()) + } + + @JvmStatic + @Throws(IOException::class) + fun getResourceCallers(resourceName: String): ByteArray { + return getResource(resourceName, getCallerClass()) + } + + private fun getCallerClass(): Class<*> { + val stackTrace = Thread.currentThread().stackTrace + for (i in 2 until stackTrace.size) { + val className = stackTrace[i].className + try { + val clazz = Class.forName(className) + if (clazz != ResourceUtils::class.java && clazz != Companion::class.java) { + return clazz + } + } catch (e: ClassNotFoundException) { + continue + } + } + return ResourceUtils::class.java + } + } +} diff --git a/src/main/kotlin/com/mingliqiye/utils/security/AesUtils.kt b/src/main/kotlin/com/mingliqiye/utils/security/AesUtils.kt index 87bdab5..d3b7263 100644 --- a/src/main/kotlin/com/mingliqiye/utils/security/AesUtils.kt +++ b/src/main/kotlin/com/mingliqiye/utils/security/AesUtils.kt @@ -16,7 +16,7 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile AesUtils.kt - * LastUpdate 2025-09-15 22:32:50 + * LastUpdate 2025-09-19 20:18:09 * UpdateUser MingLiPro */ @@ -51,10 +51,4 @@ fun encryptAesGcmNoPadding(src: String, key: String, iv: ByteArray): ByteArray { return encryptAesGcmNoPadding(src.toByteArray(), key.toByteArray(), iv) } -fun main() { - val iv = getRandomBytes(16) - println(encryptAesGcmNoPadding("mingliqiye", "key", iv)) -} - - diff --git a/src/main/kotlin/com/mingliqiye/utils/springboot/autoconfigure/AutoConfiguration.kt b/src/main/kotlin/com/mingliqiye/utils/springboot/autoconfigure/AutoConfiguration.kt index f50987e..cdc1520 100644 --- a/src/main/kotlin/com/mingliqiye/utils/springboot/autoconfigure/AutoConfiguration.kt +++ b/src/main/kotlin/com/mingliqiye/utils/springboot/autoconfigure/AutoConfiguration.kt @@ -16,7 +16,7 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile AutoConfiguration.kt - * LastUpdate 2025-09-15 22:20:25 + * LastUpdate 2025-09-20 10:47:00 * UpdateUser MingLiPro */ @@ -34,7 +34,7 @@ import java.io.IOException @org.springframework.boot.autoconfigure.AutoConfiguration @ComponentScan( - "com.mingliqiye.utils.bean.springboot", + "com.mingliqiye.utils.springboot.bean", "com.mingliqiye.utils.springboot.converters" ) open class AutoConfiguration { @@ -54,10 +54,7 @@ open class AutoConfiguration { fun printBanner() { val bannerBuilder = StringBuilder(banner) try { - val inputStream = AutoConfiguration::class.java.getResourceAsStream("/META-INF/meta-data") - if (inputStream == null) { - return - } + val inputStream = AutoConfiguration::class.java.getResourceAsStream("/META-INF/meta-data") ?: return inputStream.use { stream -> var readlen: Int val buffer = ByteArray(1024) diff --git a/src/main/kotlin/com/mingliqiye/utils/bean/springboot/SpringBeanUtils.kt b/src/main/kotlin/com/mingliqiye/utils/springboot/bean/SpringBeanUtils.kt similarity index 97% rename from src/main/kotlin/com/mingliqiye/utils/bean/springboot/SpringBeanUtils.kt rename to src/main/kotlin/com/mingliqiye/utils/springboot/bean/SpringBeanUtils.kt index 96f1a46..44ae843 100644 --- a/src/main/kotlin/com/mingliqiye/utils/bean/springboot/SpringBeanUtils.kt +++ b/src/main/kotlin/com/mingliqiye/utils/springboot/bean/SpringBeanUtils.kt @@ -16,11 +16,11 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile SpringBeanUtils.kt - * LastUpdate 2025-09-15 22:32:50 + * LastUpdate 2025-09-19 20:07:08 * UpdateUser MingLiPro */ -package com.mingliqiye.utils.bean.springboot +package com.mingliqiye.utils.springboot.bean import org.springframework.beans.BeansException import org.springframework.context.ApplicationContext diff --git a/src/main/kotlin/com/mingliqiye/utils/stream/SuperStream.kt b/src/main/kotlin/com/mingliqiye/utils/stream/SuperStream.kt deleted file mode 100644 index d21c95e..0000000 --- a/src/main/kotlin/com/mingliqiye/utils/stream/SuperStream.kt +++ /dev/null @@ -1,122 +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 SuperStream.kt - * LastUpdate 2025-09-15 17:17:48 - * UpdateUser MingLiPro - */ -@file:JvmName("Colls") - -package com.mingliqiye.utils.stream - - -import java.util.stream.Collector -import java.util.stream.Collectors -import java.util.stream.Stream - - -class SuperStream private constructor(val stream: Stream) : Stream by stream { - companion object { - @JvmStatic - fun of(stream: Stream): SuperStream { - return SuperStream(stream) - } - - @JvmStatic - fun of(collection: Collection): SuperStream { - return SuperStream(collection.stream()) - } - - @JvmStatic - fun , K, V> of(map: T): SuperStream> { - return of(map.entries) - } - - @JvmStatic - fun of(vararg array: T): SuperStream { - return of(array.toList()) - } - - @JvmStatic - fun of(iterator: Iterator): SuperStream { - val data = ArrayList(20) - while (iterator.hasNext()) { - data.add(iterator.next()) - } - return of(data) - } - } -} - -interface Gettable { - fun get(): T -} - -interface KeyGettable : Gettable { - - fun getKey(): T - override fun get(): T { - return getKey() - } -} - -interface IdGettable : Gettable { - fun getId(): T - override fun get(): T { - return getId() - } -} - -fun getThis(t: T): T { - return t -} - -fun toMapValueThis(valueMapper: java.util.function.Function): Collector> { - return Collectors.toMap( - java.util.function.Function { it }, - valueMapper - ) as Collector> -} - -fun toMap(keyMapper: java.util.function.Function): Collector> { - return Collectors.toMap( - keyMapper, - java.util.function.Function { it }, - ) as Collector> -} - -fun toMapGet(): Collector, *, Map>> { - return Collectors.toMap( - java.util.function.Function, K> { it.get() }, - java.util.function.Function, Gettable> { it }, - ) as Collector, *, Map>> -} - -fun toMap(): Collector, *, Map> { - return Collectors.toMap( - { entry: Map.Entry -> entry.key }, - { entry: Map.Entry -> entry.value } - ) as Collector, *, Map> -} - -fun toList(): Collector> { - return Collectors.toList() -} - -fun toSet(): Collector> { - return Collectors.toSet() -} diff --git a/src/main/kotlin/com/mingliqiye/utils/uuid/UUID.kt b/src/main/kotlin/com/mingliqiye/utils/uuid/UUID.kt index 088f5a0..a01b58c 100644 --- a/src/main/kotlin/com/mingliqiye/utils/uuid/UUID.kt +++ b/src/main/kotlin/com/mingliqiye/utils/uuid/UUID.kt @@ -16,7 +16,7 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile UUID.kt - * LastUpdate 2025-09-18 14:39:00 + * LastUpdate 2025-09-19 20:22:27 * UpdateUser MingLiPro */