From 496c3e624843dba8db1608f82843dfca6517f46f Mon Sep 17 00:00:00 2001 From: minglipro Date: Thu, 18 Sep 2025 09:22:55 +0800 Subject: [PATCH 01/10] =?UTF-8?q?=E6=9B=B4=E6=96=B0List.join=E6=96=B9?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/mingliqiye/utils/string/StringUtils.kt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/com/mingliqiye/utils/string/StringUtils.kt b/src/main/kotlin/com/mingliqiye/utils/string/StringUtils.kt index efd54fa..e850672 100644 --- a/src/main/kotlin/com/mingliqiye/utils/string/StringUtils.kt +++ b/src/main/kotlin/com/mingliqiye/utils/string/StringUtils.kt @@ -172,6 +172,13 @@ fun split(str: String, separator: String): List { } fun List.join(separator: String): String { - return this.joinToString(separator) + val sb = StringBuilder() + for (i in this.indices) { + sb.append(this[i]) + if (i != this.size - 1) { + sb.append(separator) + } + } + return sb.toString() } From 42a33024957ab1745547f8add3b2b888b411b0b6 Mon Sep 17 00:00:00 2001 From: minglipro Date: Thu, 18 Sep 2025 09:23:19 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20String.join=20?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/mingliqiye/utils/string/StringUtils.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/kotlin/com/mingliqiye/utils/string/StringUtils.kt b/src/main/kotlin/com/mingliqiye/utils/string/StringUtils.kt index e850672..a685e84 100644 --- a/src/main/kotlin/com/mingliqiye/utils/string/StringUtils.kt +++ b/src/main/kotlin/com/mingliqiye/utils/string/StringUtils.kt @@ -182,3 +182,13 @@ fun List.join(separator: String): String { return sb.toString() } +fun String.join(list: List, getstring: (T) -> String = { it.toString() }): String { + val sb = StringBuilder() + for (i in list.indices) { + sb.append(getstring(list[i])) + if (i != list.size - 1) { + sb.append(this) + } + } + return sb.toString() +} From c90c1d590b1f752cc5a36de8e1c6df79908b375d Mon Sep 17 00:00:00 2001 From: minglipro Date: Thu, 18 Sep 2025 09:24:43 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20List.join=20?= =?UTF-8?q?=E4=B8=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/mingliqiye/utils/string/StringUtils.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/com/mingliqiye/utils/string/StringUtils.kt b/src/main/kotlin/com/mingliqiye/utils/string/StringUtils.kt index a685e84..b42bde0 100644 --- a/src/main/kotlin/com/mingliqiye/utils/string/StringUtils.kt +++ b/src/main/kotlin/com/mingliqiye/utils/string/StringUtils.kt @@ -171,7 +171,7 @@ fun split(str: String, separator: String): List { return str.split(separator) } -fun List.join(separator: String): String { +fun List.join(separator: String, getstring: (T) -> String = { it.toString() }): String { val sb = StringBuilder() for (i in this.indices) { sb.append(this[i]) From 4b187f37741772d787f4798c8245cd6f1c86291d Mon Sep 17 00:00:00 2001 From: minglipro Date: Thu, 18 Sep 2025 09:28:06 +0800 Subject: [PATCH 04/10] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20String.join=20?= =?UTF-8?q?=E7=9A=84=E6=96=87=E6=A1=A3=20=E6=B7=BB=E5=8A=A0=20List.join=20?= =?UTF-8?q?=E7=9A=84=E6=96=87=E6=A1=A3=20=E6=B7=BB=E5=8A=A0=20split=20?= =?UTF-8?q?=E7=9A=84=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mingliqiye/utils/string/StringUtils.kt | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/mingliqiye/utils/string/StringUtils.kt b/src/main/kotlin/com/mingliqiye/utils/string/StringUtils.kt index b42bde0..18c387b 100644 --- a/src/main/kotlin/com/mingliqiye/utils/string/StringUtils.kt +++ b/src/main/kotlin/com/mingliqiye/utils/string/StringUtils.kt @@ -16,7 +16,7 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile StringUtils.kt - * LastUpdate 2025-09-17 21:09:10 + * LastUpdate 2025-09-18 09:26:41 * UpdateUser MingLiPro */ @file:JvmName("StringUtils") @@ -166,15 +166,28 @@ fun String.stringBuilder(): java.lang.StringBuilder { return StringBuilder(this) } - +/** + * 将字符串按照指定分隔符进行分割 + * @param str 需要分割的字符串 + * @param separator 分割符 + * @return 分割后的字符串列表 + */ fun split(str: String, separator: String): List { return str.split(separator) } +/** + * 将列表中的元素使用指定分隔符连接成字符串 + * @param separator 连接分隔符 + * @param getstring 转换函数,将列表元素转换为字符串,默认使用toString()方法 + * @return 连接后的字符串 + */ fun List.join(separator: String, getstring: (T) -> String = { it.toString() }): String { + // 使用StringBuilder构建结果字符串 val sb = StringBuilder() for (i in this.indices) { sb.append(this[i]) + // 除了最后一个元素外,都在后面添加分隔符 if (i != this.size - 1) { sb.append(separator) } @@ -182,13 +195,22 @@ fun List.join(separator: String, getstring: (T) -> String = { it.toString return sb.toString() } +/** + * 使用当前字符串作为分隔符,将列表中的元素连接成字符串 + * @param list 需要连接的元素列表 + * @param getstring 转换函数,将列表元素转换为字符串,默认使用toString()方法 + * @return 连接后的字符串 + */ fun String.join(list: List, getstring: (T) -> String = { it.toString() }): String { + // 使用StringBuilder构建结果字符串 val sb = StringBuilder() for (i in list.indices) { sb.append(getstring(list[i])) + // 除了最后一个元素外,都在后面添加当前字符串作为分隔符 if (i != list.size - 1) { sb.append(this) } } return sb.toString() } + From 23548c0c3dd99d50e41b236334cd033e60acc384 Mon Sep 17 00:00:00 2001 From: minglipro Date: Thu, 18 Sep 2025 14:43:01 +0800 Subject: [PATCH 05/10] =?UTF-8?q?refactor(Base91):=20=E6=9B=B4=E6=96=B0Bas?= =?UTF-8?q?e91=E8=A7=A3=E7=A0=81=E8=A1=A8=E5=B9=B6=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更新了Base91解码表的初始化方式,并添加了一个示例方法来演示编码和解码功能。 feat(Base256): 添加Base256编解码器 新增了Base256类,实现了Base256编解码功能,并在BaseUtils中添加了相应的实例。 refactor(BaseCodec): 增加字符串编解码方法 在BaseCodec接口中增加了对字符串进行Base64编码和解码的方法。refactor(OsPath): 简化路径处理逻辑 移除了OsPath类中不必要的方法实现,简化了路径处理逻辑。 feat(UUID): 支持Base256短字符串 在UUID类中添加了对Base256短字符串的支持,包括编码和解码方法。 --- src/main/kotlin/com/mingliqiye/utils/Main.kt | 4 +- .../com/mingliqiye/utils/base/Base256.kt | 317 ++++++++++++++++++ .../com/mingliqiye/utils/base/Base91.kt | 279 ++++++++++++++- .../com/mingliqiye/utils/base/BaseCodec.kt | 22 +- .../com/mingliqiye/utils/base/BaseUtils.kt | 10 +- .../com/mingliqiye/utils/bcrypt/BCrypt.kt | 2 +- .../com/mingliqiye/utils/logger/Loggers.kt | 4 +- .../com/mingliqiye/utils/path/OsPath.kt | 51 +-- .../kotlin/com/mingliqiye/utils/uuid/UUID.kt | 12 +- 9 files changed, 633 insertions(+), 68 deletions(-) create mode 100644 src/main/kotlin/com/mingliqiye/utils/base/Base256.kt diff --git a/src/main/kotlin/com/mingliqiye/utils/Main.kt b/src/main/kotlin/com/mingliqiye/utils/Main.kt index d03155b..a3a47cc 100644 --- a/src/main/kotlin/com/mingliqiye/utils/Main.kt +++ b/src/main/kotlin/com/mingliqiye/utils/Main.kt @@ -16,7 +16,7 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile Main.kt - * LastUpdate 2025-09-17 19:07:01 + * LastUpdate 2025-09-18 14:39:24 * UpdateUser MingLiPro */ @file:JvmName("Main") @@ -24,8 +24,10 @@ package com.mingliqiye.utils import com.mingliqiye.utils.springboot.autoconfigure.AutoConfiguration +import com.mingliqiye.utils.uuid.UUID fun main() { AutoConfiguration.printBanner() + println(UUID.getV7().getBase256ShortString()) } diff --git a/src/main/kotlin/com/mingliqiye/utils/base/Base256.kt b/src/main/kotlin/com/mingliqiye/utils/base/Base256.kt new file mode 100644 index 0000000..d9a356f --- /dev/null +++ b/src/main/kotlin/com/mingliqiye/utils/base/Base256.kt @@ -0,0 +1,317 @@ +/* + * 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 Base256.kt + * LastUpdate 2025-09-18 14:36:40 + * UpdateUser MingLiPro + */ + +package com.mingliqiye.utils.base + +/** + * Base256 字符集 256个 + * + * 256个字符 要字符集的下面复制 + * + * !#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~§±×÷←↑→↓⇒⇔∀∃∅∆∇∈∉∋∌∏∑−∓∕∗∘∙√∛∜∞∟∠∣∥∧∨∩∪∫∬∭∮∯∰∱∲∳∴∵∶∷≈≠≡≤≥≦≧≪≫≺≻⊂⊃⊆⊇⊈⊉⊊⊋⊕⊖⊗⊘⊙⊚⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩▁▂▃▄▅▆▇█▉▊▋▌▍▎▏▐░▒▓▔▕▖▗▘▙ + * + */ +class Base256 : BaseCodec { + + companion object { + val code = arrayOf( + '!', + '#', + '$', + '%', + '&', + '(', + ')', + '*', + '+', + ',', + '-', + '.', + '/', + '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + ':', + ';', + '<', + '=', + '>', + '?', + '@', + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + 'Y', + 'Z', + '[', + ']', + '^', + '_', + '`', + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + 'p', + 'q', + 'r', + 's', + 't', + 'u', + 'v', + 'w', + 'x', + 'y', + 'z', + '{', + '|', + '}', + '~', + '§', + '±', + '×', + '÷', + '←', + '↑', + '→', + '↓', + '⇒', + '⇔', + '∀', + '∃', + '∅', + '∆', + '∇', + '∈', + '∉', + '∋', + '∌', + '∏', + '∑', + '−', + '∓', + '∕', + '∗', + '∘', + '∙', + '√', + '∛', + '∜', + '∞', + '∟', + '∠', + '∣', + '∥', + '∧', + '∨', + '∩', + '∪', + '∫', + '∬', + '∭', + '∮', + '∯', + '∰', + '∱', + '∲', + '∳', + '∴', + '∵', + '∶', + '∷', + '≈', + '≠', + '≡', + '≤', + '≥', + '≦', + '≧', + '≪', + '≫', + '≺', + '≻', + '⊂', + '⊃', + '⊆', + '⊇', + '⊈', + '⊉', + '⊊', + '⊋', + '⊕', + '⊖', + '⊗', + '⊘', + '⊙', + '⊚', + '⊛', + '⊜', + '⊝', + '⊞', + '⊟', + '⊠', + '⊡', + '⊢', + '⊣', + '⊤', + '⊥', + '⊦', + '⊧', + '⊨', + '⊩', + '⊪', + '⊫', + '⊬', + '⊭', + '⊮', + '⊯', + '⋀', + '⋁', + '⋂', + '⋃', + '⋄', + '⋅', + '⋆', + '⋇', + '⋈', + '⋉', + '⋊', + '⋋', + '⋌', + '⋍', + '⋎', + '⋏', + '⋐', + '⋑', + '⋒', + '⋓', + '⋔', + '⋕', + '⋖', + '⋗', + '⋘', + '⋙', + '⋚', + '⋛', + '⋜', + '⋝', + '⋞', + '⋟', + '⋠', + '⋡', + '⋢', + '⋣', + '⋤', + '⋥', + '⋦', + '⋧', + '⋨', + '⋩', + '▁', + '▂', + '▃', + '▄', + '▅', + '▆', + '▇', + '█', + '▉', + '▊', + '▋', + '▌', + '▍', + '▎', + '▏', + '▐', + '░', + '▒', + '▓', + '▔', + '▕', + '▖', + '▗', + '▘', + '▙' + ) + val codeMap = code.mapIndexed { index, c -> c to index }.toMap() + } + + override fun encode(bytes: ByteArray): String { + val result = CharArray(bytes.size) + for (i in bytes.indices) { + val unsignedByte = bytes[i].toInt() and 0xFF + result[i] = code[unsignedByte] + } + return String(result) + } + + override fun decode(string: String): ByteArray { + val result = ByteArray(string.length) + for (i in string.indices) { + result[i] = codeMap[string[i]]!!.toByte() + } + 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 4a88e09..342b0cf 100644 --- a/src/main/kotlin/com/mingliqiye/utils/base/Base91.kt +++ b/src/main/kotlin/com/mingliqiye/utils/base/Base91.kt @@ -16,14 +16,12 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile Base91.kt - * LastUpdate 2025-09-17 10:57:36 + * LastUpdate 2025-09-18 14:42:59 * UpdateUser MingLiPro */ package com.mingliqiye.utils.base -import java.util.* - /** * Base91 编解码工具类,用于将字节数组编码为 Base91 字符串,或将 Base91 字符串解码为原始字节数组。 * @@ -49,16 +47,264 @@ class Base91 : BaseCodec { * Base91 解码表,大小为 256,用于快速查找字符对应的数值。 * 初始化时将所有元素设为 -1,表示无效字符;然后根据 ENCODING_TABLE 填充有效字符的索引。 */ - val DECODING_TABLE: IntArray = IntArray(256) - - init { - // 初始化解码表,默认值为 -1 表示该字符不在编码表中 - Arrays.fill(DECODING_TABLE, -1); - // 构建解码映射表 - for (i in 0.. = arrayOf( + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 62, + 90, + 63, + 64, + 65, + 66, + -1, + 67, + 68, + 69, + 70, + 71, + -1, + 72, + 73, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 81, + -1, + 82, + 83, + 84, + 85, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 86, + 87, + 88, + 89, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ) } /** @@ -156,3 +402,10 @@ 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/BaseCodec.kt b/src/main/kotlin/com/mingliqiye/utils/base/BaseCodec.kt index 802be9f..5ef033e 100644 --- a/src/main/kotlin/com/mingliqiye/utils/base/BaseCodec.kt +++ b/src/main/kotlin/com/mingliqiye/utils/base/BaseCodec.kt @@ -16,7 +16,7 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile BaseCodec.kt - * LastUpdate 2025-09-17 10:35:23 + * LastUpdate 2025-09-18 14:07:35 * UpdateUser MingLiPro */ @@ -150,4 +150,24 @@ interface BaseCodec { false } } + + /** + * 将字符串编码为Base64字符串 + * + * @param string 需要编码的字符串 + * @return 编码后的Base64字符串 + */ + fun encode(string: String): String { + return encode(string.toByteArray()) + } + + /** + * 将Base64字符串解码为字符串 + * + * @param string 需要解码的Base64字符串 + * @return 解码后的字符串 + */ + fun decodetoString(string: String): String { + return decode(string).toString(Charsets.UTF_8) + } } diff --git a/src/main/kotlin/com/mingliqiye/utils/base/BaseUtils.kt b/src/main/kotlin/com/mingliqiye/utils/base/BaseUtils.kt index 22c3c0e..5d7a3c3 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-17 10:54:46 + * LastUpdate 2025-09-18 14:36:40 * UpdateUser MingLiPro */ @@ -51,4 +51,12 @@ val BASE16: BaseCodec by lazy { Base16() } +/** + * Base256编解码器实例 + * 使用懒加载方式初始化Base256编解码器对象 + * 保证线程安全且只在首次访问时创建实例 + */ +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 4a1b559..65e982e 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-17 16:20:30 + * LastUpdate 2025-09-18 09:46:16 * UpdateUser MingLiPro */ diff --git a/src/main/kotlin/com/mingliqiye/utils/logger/Loggers.kt b/src/main/kotlin/com/mingliqiye/utils/logger/Loggers.kt index 4b8cfc6..e75b366 100644 --- a/src/main/kotlin/com/mingliqiye/utils/logger/Loggers.kt +++ b/src/main/kotlin/com/mingliqiye/utils/logger/Loggers.kt @@ -16,7 +16,7 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile Loggers.kt - * LastUpdate 2025-09-15 22:32:50 + * LastUpdate 2025-09-18 09:30:48 * UpdateUser MingLiPro */ @@ -416,6 +416,6 @@ class MingLiLoggerFactory { } } -val mingLiLoggerFactory = MingLiLoggerFactory() +val mingLiLoggerFactory: MingLiLoggerFactory by lazy { MingLiLoggerFactory() } diff --git a/src/main/kotlin/com/mingliqiye/utils/path/OsPath.kt b/src/main/kotlin/com/mingliqiye/utils/path/OsPath.kt index 6140b83..f88d949 100644 --- a/src/main/kotlin/com/mingliqiye/utils/path/OsPath.kt +++ b/src/main/kotlin/com/mingliqiye/utils/path/OsPath.kt @@ -16,7 +16,7 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile OsPath.kt - * LastUpdate 2025-09-15 08:59:15 + * LastUpdate 2025-09-18 09:47:43 * UpdateUser MingLiPro */ @@ -26,9 +26,8 @@ package com.mingliqiye.utils.path import java.io.File import java.net.URI -import java.nio.file.* -import java.util.* -import java.util.function.Consumer +import java.nio.file.Path +import java.nio.file.Paths class OsPath private constructor(private val path: Path) : Path by path { @@ -58,48 +57,4 @@ class OsPath private constructor(private val path: Path) : Path by path { return OsPath(Paths.get("")) } } - - override fun getParent(): Path? { - var parent = path.parent - if (parent == null) { - parent = path.toAbsolutePath().parent - } - return parent - } - - override fun toRealPath(vararg options: LinkOption): Path { - return OsPath(path.toRealPath(*options)) - } - - override fun register(watcher: WatchService, vararg events: WatchEvent.Kind<*>): WatchKey { - return path.register(watcher, *events) - } - - override fun register( - watcher: WatchService, - events: Array>, - vararg modifiers: WatchEvent.Modifier - ): WatchKey { - return path.register(watcher, events, *modifiers) - } - - override fun iterator(): MutableIterator { - return path.iterator() - } - - override fun compareTo(other: Path): Int { - return path.compareTo(other) - } - - override fun toString(): String { - return path.toString() - } - - override fun forEach(action: Consumer) { - path.forEach(action) - } - - override fun spliterator(): Spliterator { - return path.spliterator() - } } diff --git a/src/main/kotlin/com/mingliqiye/utils/uuid/UUID.kt b/src/main/kotlin/com/mingliqiye/utils/uuid/UUID.kt index d518f7f..088f5a0 100644 --- a/src/main/kotlin/com/mingliqiye/utils/uuid/UUID.kt +++ b/src/main/kotlin/com/mingliqiye/utils/uuid/UUID.kt @@ -16,12 +16,13 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile UUID.kt - * LastUpdate 2025-09-17 16:27:32 + * LastUpdate 2025-09-18 14:39:00 * UpdateUser MingLiPro */ package com.mingliqiye.utils.uuid +import com.mingliqiye.utils.base.BASE256 import com.mingliqiye.utils.base.BASE64 import com.mingliqiye.utils.base.BASE91 import com.mingliqiye.utils.random.randomByteSecure @@ -66,6 +67,11 @@ class UUID : Serializable { return UUID(BASE64.decode(baseShortString)) } + @JvmStatic + fun ofBase256ShortString(baseShortString: String): UUID { + return UUID(BASE256.decode(baseShortString)) + } + @JvmStatic fun ofBase91ShortString(baseShortString: String): UUID { return UUID(BASE91.decode(baseShortString)) @@ -656,6 +662,10 @@ class UUID : Serializable { return BASE91.encode(data) } + fun getBase256ShortString(): String { + return BASE256.encode(data) + } + /** * 提取 UUID V1 中的 MAC 地址。 * From 075dc2346a39b0e3fc8d6d107f751c035abbfb61 Mon Sep 17 00:00:00 2001 From: minglipro Date: Sat, 20 Sep 2025 14:01:36 +0800 Subject: [PATCH 06/10] =?UTF-8?q?feat(utils):=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E7=B1=BB=E5=B9=B6=E4=BC=98=E5=8C=96=E9=9B=86?= =?UTF-8?q?=E5=90=88=E6=89=A9=E5=B1=95=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 更新多个工具类的最后修改时间和用户信息 - 移除冗余的 main 函数测试代码 - 优化 ByteUtils 中流处理方法的引用- 为 Collection 扩展大量实用函数,包括转换、获取元素和创建集合实例等 - 引入 SuperStream 替代部分自定义流处理逻辑 - 调整 Spring Boot 自动配置包扫描路径- 修复资源读取时的空指针风险,使用 Kotlin 的 elvis 操作符简化代码 --- build.gradle.kts | 4 +- gradle.properties | 4 +- jdk8/build.gradle.kts | 2 +- .../utils/stream/StreamEmptyException.java} | 31 +- .../mingliqiye/utils/stream/SuperStream.java | 1135 +++++++++++++++++ .../com/mingliqiye/utils/aes/AesUtils.kt | 3 +- .../com/mingliqiye/utils/base/Base256.kt | 6 +- .../com/mingliqiye/utils/base/Base91.kt | 9 +- .../com/mingliqiye/utils/base/BaseUtils.kt | 3 +- .../com/mingliqiye/utils/bcrypt/BCrypt.kt | 3 +- .../com/mingliqiye/utils/bean/Factory.kt | 241 ---- .../com/mingliqiye/utils/bytes/ByteUtils.kt | 6 +- .../com/mingliqiye/utils/clone/CloneUtils.kt | 5 +- .../mingliqiye/utils/collection/Collection.kt | 521 +++++++- .../mingliqiye/utils/concurrent/IsChanged.kt | 2 +- .../utils/configuration/ConfigurationProp.kt | 273 ++++ .../com/mingliqiye/utils/dto/DtoUtils.kt | 146 +++ .../com/mingliqiye/utils/hash/HashUtils.kt | 13 +- src/main/kotlin/com/mingliqiye/utils/io/IO.kt | 63 + .../com/mingliqiye/utils/{ => main}/Main.kt | 12 +- .../com/mingliqiye/utils/metadata/MetaData.kt | 64 + .../utils/resource/ResourceUtils.kt | 87 ++ .../com/mingliqiye/utils/security/AesUtils.kt | 8 +- .../autoconfigure/AutoConfiguration.kt | 9 +- .../bean}/SpringBeanUtils.kt | 4 +- .../mingliqiye/utils/stream/SuperStream.kt | 122 -- .../kotlin/com/mingliqiye/utils/uuid/UUID.kt | 2 +- 27 files changed, 2333 insertions(+), 445 deletions(-) rename src/main/{kotlin/com/mingliqiye/utils/bean/annotation/ComponentBean.kt => java/com/mingliqiye/utils/stream/StreamEmptyException.java} (56%) create mode 100644 src/main/java/com/mingliqiye/utils/stream/SuperStream.java delete mode 100644 src/main/kotlin/com/mingliqiye/utils/bean/Factory.kt create mode 100644 src/main/kotlin/com/mingliqiye/utils/configuration/ConfigurationProp.kt create mode 100644 src/main/kotlin/com/mingliqiye/utils/dto/DtoUtils.kt create mode 100644 src/main/kotlin/com/mingliqiye/utils/io/IO.kt rename src/main/kotlin/com/mingliqiye/utils/{ => main}/Main.kt (82%) create mode 100644 src/main/kotlin/com/mingliqiye/utils/metadata/MetaData.kt create mode 100644 src/main/kotlin/com/mingliqiye/utils/resource/ResourceUtils.kt rename src/main/kotlin/com/mingliqiye/utils/{bean/springboot => springboot/bean}/SpringBeanUtils.kt (97%) delete mode 100644 src/main/kotlin/com/mingliqiye/utils/stream/SuperStream.kt 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 */ From 578f0a3e8924f2446c208c85fb67ff8cc1363b7f Mon Sep 17 00:00:00 2001 From: minglipro Date: Sat, 20 Sep 2025 14:05:41 +0800 Subject: [PATCH 07/10] =?UTF-8?q?fix(collection):=20=E6=8A=91=E5=88=B6?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E8=BD=AC=E6=8D=A2=E8=AD=A6=E5=91=8A=E5=B9=B6?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=87=E4=BB=B6=E6=97=B6=E9=97=B4=E6=88=B3?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=86=20Collection.kt=20=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E4=B8=AD=E7=9A=84=E7=B1=BB=E5=9E=8B=E8=BD=AC=E6=8D=A2?= =?UTF-8?q?=E8=AD=A6=E5=91=8A=E9=97=AE=E9=A2=98=EF=BC=8C=E9=80=9A=E8=BF=87?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20@Suppress("UNCHECKED=5FCAST")=20=E6=B3=A8?= =?UTF-8?q?=E8=A7=A3=E6=9D=A5=E6=8A=91=E5=88=B6=E7=BC=96=E8=AF=91=E5=99=A8?= =?UTF-8?q?=E8=AD=A6=E5=91=8A=E3=80=82=E5=90=8C=E6=97=B6=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E4=BA=86=E6=96=87=E4=BB=B6=E7=9A=84=E6=9C=80=E5=90=8E=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E6=97=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/mingliqiye/utils/collection/Collection.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/com/mingliqiye/utils/collection/Collection.kt b/src/main/kotlin/com/mingliqiye/utils/collection/Collection.kt index 0559e57..b0f0b0f 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-20 14:01:07 + * LastUpdate 2025-09-20 14:03:46 * UpdateUser MingLiPro */ @@ -47,6 +47,7 @@ inline fun Collection.toArray(): Array { * @param v 用于生成映射值的函数 * @return 转换后的 Map */ +@Suppress("UNCHECKED_CAST") inline fun Collection.toMap(noinline v: (T) -> V): Map { return this.stream().collect( SuperStream.toMap( From 5eed682aa1d567908015c8ffb62ef500c9971411 Mon Sep 17 00:00:00 2001 From: minglipro Date: Sat, 20 Sep 2025 14:22:14 +0800 Subject: [PATCH 08/10] =?UTF-8?q?feat(utils):=20=E6=B7=BB=E5=8A=A0=20MyBat?= =?UTF-8?q?is-Plus=20=E6=9F=A5=E8=AF=A2=E5=8C=85=E8=A3=85=E5=99=A8?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在 build.gradle.kts 中替换 JNA依赖为 mybatis-plus-core,并新增BaseMapperQuery 接口,提供通用的 QueryWrapper 实例创建方法,便于MyBatis-Plus 相关操作的统一封装与复用 --- build.gradle.kts | 6 +-- gradle.properties | 4 +- .../utils/mybatisplus/QueryWrapper.kt | 42 +++++++++++++++++++ 3 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 src/main/kotlin/com/mingliqiye/utils/mybatisplus/QueryWrapper.kt diff --git a/build.gradle.kts b/build.gradle.kts index ba806c4..6caf27a 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-19 09:39:33 + * LastUpdate 2025-09-20 14:16:07 * UpdateUser MingLiPro */ @@ -77,7 +77,7 @@ dependencies { compileOnly("com.google.code.gson:gson:2.13.1") compileOnly("org.mybatis:mybatis:3.5.19") compileOnly("com.alibaba.fastjson2:fastjson2:2.0.58") - compileOnly("net.java.dev.jna:jna:5.17.0") + compileOnly("com.baomidou:mybatis-plus-core:3.0.1") } @@ -213,5 +213,3 @@ tasks.processResources { ) } } - - diff --git a/gradle.properties b/gradle.properties index 62be1e0..18a795f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,13 +16,13 @@ # ProjectName mingli-utils # ModuleName mingli-utils # CurrentFile gradle.properties -# LastUpdate 2025-09-20 14:01:07 +# LastUpdate 2025-09-20 14:22:07 # UpdateUser MingLiPro # JDKVERSIONS=1.8 GROUPSID=com.mingliqiye.utils ARTIFACTID=mingli-utils -VERSIONS=4.1.6 +VERSIONS=4.1.7 signing.keyId=B22AA93B signing.password= signing.secretKeyRingFile=secret.gpg diff --git a/src/main/kotlin/com/mingliqiye/utils/mybatisplus/QueryWrapper.kt b/src/main/kotlin/com/mingliqiye/utils/mybatisplus/QueryWrapper.kt new file mode 100644 index 0000000..3c3dbf0 --- /dev/null +++ b/src/main/kotlin/com/mingliqiye/utils/mybatisplus/QueryWrapper.kt @@ -0,0 +1,42 @@ +/* + * 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 QueryWrapper.kt + * LastUpdate 2025-09-20 14:21:44 + * UpdateUser MingLiPro + */ + +package com.mingliqiye.utils.mybatisplus + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper +import com.baomidou.mybatisplus.core.mapper.BaseMapper + +/** + * BaseMapperQuery接口扩展了BaseMapper,提供了通用的查询包装器功能 + * + * @param T 实体类类型 + */ +interface BaseMapperQuery : BaseMapper { + /** + * 创建并返回一个新的QueryWrapper实例 + * + * @return QueryWrapper 返回类型化的查询包装器实例 + */ + fun queryWrapper(): QueryWrapper { + return QueryWrapper() + } +} From 683aeb2c7fb8d07e91b4540d281b406d0fd8c127 Mon Sep 17 00:00:00 2001 From: minglipro Date: Sun, 21 Sep 2025 14:37:22 +0800 Subject: [PATCH 09/10] =?UTF-8?q?```=20feat(stream):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20SuperStream=20=E7=9A=84=20toArray=20=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0-=20=E8=B0=83=E6=95=B4=20toArray=20=E6=96=B9?= =?UTF-8?q?=E6=B3=95=EF=BC=8C=E6=94=AF=E6=8C=81=E4=BC=A0=E5=85=A5=20Class?= =?UTF-8?q?=20=E5=8F=82=E6=95=B0=E4=BB=A5=E6=AD=A3=E7=A1=AE=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E6=B3=9B=E5=9E=8B=E6=95=B0=E7=BB=84=20-=20=E5=8E=9F?= =?UTF-8?q?=E6=97=A0=E5=8F=82=20toArray=20=E6=96=B9=E6=B3=95=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E8=BF=94=E5=9B=9E=20Object[]=EF=BC=8C=E9=81=BF?= =?UTF-8?q?=E5=85=8D=E7=B1=BB=E5=9E=8B=E8=BD=AC=E6=8D=A2=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=20-=20=E7=A7=BB=E9=99=A4=E5=AF=B9=20ForEach=20=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E7=B1=BB=E7=9A=84=E4=BE=9D=E8=B5=96=20-=20=E6=8F=90?= =?UTF-8?q?=E5=8D=87=E6=B5=81=E5=A4=84=E7=90=86=E4=B8=AD=E6=95=B0=E7=BB=84?= =?UTF-8?q?=E8=BD=AC=E6=8D=A2=E7=9A=84=E7=81=B5=E6=B4=BB=E6=80=A7=E4=B8=8E?= =?UTF-8?q?=E5=AE=89=E5=85=A8=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ``` ``` feat(collection): 改进 toArray 工具方法支持泛型数组创建 - 新增基于 reified 泛型的 toArray 扩展方法,自动推断数组类型 - 添加带 Class 参数的 toArray 重载方法,用于明确指定元素类型 - 处理空列表时直接返回空数组,避免后续操作异常 ``` ``` build(gradle): 升级 dokka 插件版本并更新项目依赖- 将 org.jetbrains.dokka 插件升级至 2.1.0-Beta 版本 - 添加 jna5.17.0 依赖用于本地库调用支持 - 引入 mybatis-plus-core 3.0.1 编译依赖 - 更新项目版本号从 4.1.7 至 4.1.8 ``` --- build.gradle.kts | 6 ++++-- gradle.properties | 4 ++-- .../mingliqiye/utils/stream/SuperStream.java | 20 ++++++++----------- .../mingliqiye/utils/collection/Collection.kt | 13 +++++++++--- src/main/kotlin/com/mingliqiye/utils/io/IO.kt | 12 +++++------ 5 files changed, 30 insertions(+), 25 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 6caf27a..494b3c5 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-20 14:16:07 + * LastUpdate 2025-09-20 22:30:57 * UpdateUser MingLiPro */ @@ -30,7 +30,7 @@ plugins { `java-library` `maven-publish` kotlin("jvm") version "2.2.20" - id("org.jetbrains.dokka") version "2.0.0" + id("org.jetbrains.dokka") version "2.1.0-Beta" } val GROUPSID = project.properties["GROUPSID"] as String val VERSIONS = project.properties["VERSIONS"] as String @@ -77,7 +77,9 @@ dependencies { compileOnly("com.google.code.gson:gson:2.13.1") compileOnly("org.mybatis:mybatis:3.5.19") compileOnly("com.alibaba.fastjson2:fastjson2:2.0.58") + compileOnly("com.baomidou:mybatis-plus-core:3.0.1") + compileOnly("net.java.dev.jna:jna:5.17.0") } diff --git a/gradle.properties b/gradle.properties index 18a795f..779033d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,13 +16,13 @@ # ProjectName mingli-utils # ModuleName mingli-utils # CurrentFile gradle.properties -# LastUpdate 2025-09-20 14:22:07 +# LastUpdate 2025-09-20 16:03:35 # UpdateUser MingLiPro # JDKVERSIONS=1.8 GROUPSID=com.mingliqiye.utils ARTIFACTID=mingli-utils -VERSIONS=4.1.7 +VERSIONS=4.1.8 signing.keyId=B22AA93B signing.password= signing.secretKeyRingFile=secret.gpg diff --git a/src/main/java/com/mingliqiye/utils/stream/SuperStream.java b/src/main/java/com/mingliqiye/utils/stream/SuperStream.java index d268101..1d71c41 100644 --- a/src/main/java/com/mingliqiye/utils/stream/SuperStream.java +++ b/src/main/java/com/mingliqiye/utils/stream/SuperStream.java @@ -16,14 +16,13 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile SuperStream.java - * LastUpdate 2025-09-20 13:24:35 + * LastUpdate 2025-09-21 14:22:13 * 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; @@ -887,16 +886,13 @@ public class SuperStream implements Stream { */ @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; + public T[] toArray(Class clazz) { + return stream.toArray(i -> (T[]) Array.newInstance(clazz, i)); + } + + @NotNull + public Object[] toArray() { + return stream.toArray(); } /** diff --git a/src/main/kotlin/com/mingliqiye/utils/collection/Collection.kt b/src/main/kotlin/com/mingliqiye/utils/collection/Collection.kt index b0f0b0f..9025922 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-20 14:03:46 + * LastUpdate 2025-09-21 14:36:57 * UpdateUser MingLiPro */ @@ -980,7 +980,14 @@ fun toArray(list: List): CharArray { * @param list 输入的 List * @return 转换后的数组 */ -fun toArray(list: List): Array { +inline fun toArray(list: List): Array { + if (list.isEmpty()) + return arrayOf() return SuperStream.of(list) - .toArray() + .toArray(T::class.java) +} + +fun toArray(list: List, clazz: Class): Array { + return SuperStream.of(list) + .toArray(clazz) } diff --git a/src/main/kotlin/com/mingliqiye/utils/io/IO.kt b/src/main/kotlin/com/mingliqiye/utils/io/IO.kt index c5fe70f..e288ee3 100644 --- a/src/main/kotlin/com/mingliqiye/utils/io/IO.kt +++ b/src/main/kotlin/com/mingliqiye/utils/io/IO.kt @@ -16,7 +16,7 @@ * ProjectName mingli-utils * ModuleName mingli-utils.main * CurrentFile IO.kt - * LastUpdate 2025-09-20 11:46:19 + * LastUpdate 2025-09-20 16:03:14 * UpdateUser MingLiPro */ @@ -33,22 +33,22 @@ class IO { @JvmStatic fun print(vararg args: Any?) { - print(" ", *args) + printA(" ", *args) } @JvmStatic fun println(vararg args: Any?) { - println(" ", *args) + printlnA(" ", *args) } @JvmStatic - fun println(sp: String = " ", vararg args: Any?) { - print(" ", *args) + fun printlnA(sp: String, vararg args: Any?) { + printA(" ", *args) kotlin.io.println() } @JvmStatic - fun print(sp: String = " ", vararg args: Any?) { + fun printA(sp: String = "", vararg args: Any?) { if (args.isEmpty()) { kotlin.io.println() } From ac92f62967bf8cc9da992227febb49684013fa63 Mon Sep 17 00:00:00 2001 From: minglipro Date: Sun, 21 Sep 2025 15:39:14 +0800 Subject: [PATCH 10/10] =?UTF-8?q?build(jdk8):=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=9E=84=E5=BB=BA=E8=84=9A=E6=9C=AC=E4=B8=AD=E7=9A=84=20Kotlin?= =?UTF-8?q?=20=E5=92=8C=20Dokka=20=E6=8F=92=E4=BB=B6=E7=89=88=E6=9C=AC-=20?= =?UTF-8?q?=E5=9C=A8=20`jdk8/build.gradle.kts`=20=E4=B8=AD=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E4=BA=86=20Kotlin=20JVM=20=E6=8F=92=E4=BB=B6=E5=92=8C?= =?UTF-8?q?=20Dokka=20=E6=8F=92=E4=BB=B6=20-=20=E6=9B=B4=E6=96=B0=20`build?= =?UTF-8?q?.gradle.kts`=20=E4=B8=AD=E7=9A=84=20Dokka=20=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E4=BB=8E2.1.0-Beta=20=E5=88=B02.0.0-=20=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E4=BA=86=20Gradle=20=E4=BB=BB=E5=8A=A1=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E6=96=B9=E5=BC=8F=EF=BC=8C=E4=BD=BF=E7=94=A8=E5=AD=97=E7=AC=A6?= =?UTF-8?q?=E4=B8=B2=E5=90=8D=E7=A7=B0=E6=9B=BF=E4=BB=A3=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E5=BC=95=E7=94=A8=20-=20=E5=8D=87=E7=BA=A7=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=8F=B7=E4=BB=8E=204.1.8=20=E5=88=B0=204.1.?= =?UTF-8?q?9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 9 ++++----- gradle.properties | 4 ++-- jdk8/build.gradle.kts | 4 +++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 494b3c5..5c3e672 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-20 22:30:57 + * LastUpdate 2025-09-21 15:36:59 * UpdateUser MingLiPro */ @@ -30,7 +30,7 @@ plugins { `java-library` `maven-publish` kotlin("jvm") version "2.2.20" - id("org.jetbrains.dokka") version "2.1.0-Beta" + id("org.jetbrains.dokka") version "2.0.0" } val GROUPSID = project.properties["GROUPSID"] as String val VERSIONS = project.properties["VERSIONS"] as String @@ -132,17 +132,16 @@ repositories { } mavenCentral() } - tasks.register("javaDocJar") { group = "build" archiveClassifier.set("javadoc") - dependsOn(tasks.dokkaJavadoc) + dependsOn("dokkaJavadoc") from(buildDir.resolve("dokka/javadoc")) } tasks.register("kotlinDocJar") { group = "build" archiveClassifier.set("kotlindoc") - dependsOn(tasks.dokkaHtml) + dependsOn("dokkaHtml") from(buildDir.resolve("dokka/html")) } publishing { diff --git a/gradle.properties b/gradle.properties index 779033d..12142a1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,13 +16,13 @@ # ProjectName mingli-utils # ModuleName mingli-utils # CurrentFile gradle.properties -# LastUpdate 2025-09-20 16:03:35 +# LastUpdate 2025-09-21 15:38:52 # UpdateUser MingLiPro # JDKVERSIONS=1.8 GROUPSID=com.mingliqiye.utils ARTIFACTID=mingli-utils -VERSIONS=4.1.8 +VERSIONS=4.1.9 signing.keyId=B22AA93B signing.password= signing.secretKeyRingFile=secret.gpg diff --git a/jdk8/build.gradle.kts b/jdk8/build.gradle.kts index 13c06da..13cc797 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-19 21:35:53 + * LastUpdate 2025-09-21 15:39:12 * UpdateUser MingLiPro */ @@ -24,6 +24,8 @@ plugins { id("java-library") id("maven-publish") signing + kotlin("jvm") version "2.2.20" + id("org.jetbrains.dokka") version "2.0.0" } val GROUPSID = project.properties["GROUPSID"] as String val VERSIONS = project.properties["VERSIONS"] as String