refactor(kotlin): 重构 AES 工具类并优化 Base64 编解码方法
Some checks failed
Gitea Actions Build / Build (push) Has been cancelled

- 重构 AesUtils.kt,使用 Kotlin 标准库的 encode 和 decode 方法替代自定义实现- 删除 Java 版本的 Base64Utils 类,迁移到 Kotlin 实现
- 重命名 ByteUtil.kt 为 ByteUtils.kt,统一命名风格
- 删除 Java 版本的 CloneUtil 类和 Factory 类,使用 Kotlin 实现
- 新增 Kotlin 版本的 SpringBeanUtils 工具类
This commit is contained in:
Armamem0t 2025-09-14 21:47:04 +08:00
parent fb4e103da8
commit 1fab0b02be
Signed by: minglipro
GPG Key ID: 5F355A77B22AA93B
17 changed files with 571 additions and 1015 deletions

View File

@ -1,198 +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 Base64Utils.java
* LastUpdate 2025-09-09 08:37:33
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.base64;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Base64;
/**
* Base64工具类提供对字节数组文件和字符串的Base64编码与解码功能
*/
public class Base64Utils {
// Base64编码器实例
private static final Base64.Encoder BASE_64_ENCODER = Base64.getEncoder();
// Base64解码器实例
private static final Base64.Decoder BASE_64_DECODER = Base64.getDecoder();
/**
* 对字节数组进行Base64编码
*
* @param bytes 待编码的字节数组
* @return 编码后的Base64字符串
*/
public static String encode(byte[] bytes) {
return BASE_64_ENCODER.encodeToString(bytes);
}
/**
* 对文件内容进行Base64编码
*
* @param file 待编码的文件对象
* @return 编码后的Base64字符串
* @throws RuntimeException 如果读取文件时发生IO异常
*/
public static String encode(File file) {
try {
byte[] bytes = java.nio.file.Files.readAllBytes(file.toPath());
return encode(bytes);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 根据文件路径对文件内容进行Base64编码
*
* @param filePath 文件路径
* @return 编码后的Base64字符串
*/
public static String encode(String filePath) {
return encode(new File(filePath));
}
/**
* 安全地对文件内容进行Base64编码出错时返回null
*
* @param file 待编码的文件对象
* @return 编码后的Base64字符串出错时返回null
*/
public static String encodeSafe(File file) {
try {
return encode(file);
} catch (Exception e) {
return null;
}
}
/**
* 安全地根据文件路径对文件内容进行Base64编码出错时返回null
*
* @param filePath 文件路径
* @return 编码后的Base64字符串出错时返回null
*/
public static String encodeSafe(String filePath) {
try {
return encode(filePath);
} catch (Exception e) {
return null;
}
}
/**
* 对Base64字符串进行解码
*
* @param base64 待解码的Base64字符串
* @return 解码后的字节数组
*/
public static byte[] decode(String base64) {
return BASE_64_DECODER.decode(base64);
}
/**
* 安全地对Base64字符串进行解码出错时返回null
*
* @param base64 待解码的Base64字符串
* @return 解码后的字节数组出错时返回null
*/
public static byte[] decodeSafe(String base64) {
try {
return decode(base64);
} catch (Exception e) {
return null;
}
}
/**
* 将Base64字符串解码并写入指定文件
*
* @param base64 待解码的Base64字符串
* @param file 目标文件对象
* @throws RuntimeException 如果写入文件时发生IO异常
*/
public static void decodeToFile(String base64, File file) {
try (FileOutputStream fos = new FileOutputStream(file)) {
byte[] bytes = decode(base64);
fos.write(bytes);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 将Base64字符串解码并写入指定路径的文件
*
* @param base64 待解码的Base64字符串
* @param filePath 目标文件路径
*/
public static void decodeToFile(String base64, String filePath) {
decodeToFile(base64, new File(filePath));
}
/**
* 安全地将Base64字符串解码并写入指定文件出错时返回false
*
* @param base64 待解码的Base64字符串
* @param file 目标文件对象
* @return 成功写入返回true否则返回false
*/
public static boolean decodeToFileSafe(String base64, File file) {
try {
decodeToFile(base64, file);
return true;
} catch (Exception e) {
return false;
}
}
/**
* 安全地将Base64字符串解码并写入指定路径的文件出错时返回false
*
* @param base64 待解码的Base64字符串
* @param filePath 目标文件路径
* @return 成功写入返回true否则返回false
*/
public static boolean decodeToFileSafe(String base64, String filePath) {
return decodeToFileSafe(base64, new File(filePath));
}
/**
* 对字节数组中指定范围的数据进行Base64编码
*
* @param bytes 源字节数组
* @param offset 起始偏移量
* @param length 要编码的数据长度
* @return 编码后的Base64字符串
*/
public static String encodeBytes(byte[] bytes, int offset, int length) {
byte[] data = new byte[length];
System.arraycopy(bytes, offset, data, 0, length);
return encode(data);
}
public static String encodeBytes(byte[] bytes) {
return encodeBytes(bytes, 0, bytes.length);
}
}

View File

@ -1,270 +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.java
* LastUpdate 2025-09-09 08:39:07
* UpdateUser MingLiPro
*/
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.lang.reflect.Field;
import java.net.URL;
import java.util.Enumeration;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* 类似于SpringBoot的Bean管理器
*
* @author MingLiPro
*/
public class Factory {
/**
* 存储所有已注册的Bean实例键为Bean名称值为Bean实例
*/
public static final ConcurrentMap<String, Object> BEANS =
new ConcurrentHashMap<>();
/**
* 存储按类型查找的Bean实例键为Bean的Class对象值为Bean实例
*/
private static final ConcurrentMap<Class<?>, Object> TYPE_BEANS =
new ConcurrentHashMap<>();
/**
* 私有构造函数防止外部实例化该类
*/
private Factory() {}
/**
* 自动扫描指定类所在包下的所有类并注册为Bean
*
* @param c 指定的类用于获取其所在的包
* @throws IllegalArgumentException 如果传入的类为null或位于默认包中
*/
public static void autoScan(Class<?> c) {
if (c == null) {
throw new IllegalArgumentException("Class cannot be null");
}
Package pkg = c.getPackage();
if (pkg == null) {
throw new IllegalArgumentException(
"Class is in the default package"
);
}
scan(pkg.getName());
}
/**
* 扫描指定包路径下的所有类文件并注册其中带有@ComponentBean注解的类为Bean
*
* @param basePackage 要扫描的基础包名
* @throws RuntimeException 如果在扫描过程中发生异常
*/
public static void scan(String basePackage) {
try {
String path = basePackage.replace('.', '/');
ClassLoader classLoader =
Thread.currentThread().getContextClassLoader();
Enumeration<URL> resources = null;
resources = classLoader.getResources(path);
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
File file = new File(resource.toURI());
scanDirectory(file, basePackage);
}
injectDependencies();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 递归扫描目录中的所有类文件并注册符合条件的类为Bean
*
* @param directory 当前要扫描的目录
* @param packageName 当前目录对应的包名
* @throws Exception 如果在扫描或类加载过程中发生异常
*/
private static void scanDirectory(File directory, String packageName)
throws Exception {
File[] files = directory.listFiles();
if (files == null) {
return;
}
for (File file : files) {
if (file.isDirectory()) {
scanDirectory(file, packageName + "." + file.getName());
} else if (file.getName().endsWith(".class")) {
String className =
packageName + '.' + file.getName().replace(".class", "");
registerComponent(Class.forName(className));
}
}
}
/**
* 注册一个带有@ComponentBean注解的类为Bean实例
*
* @param clazz 要注册的类
* @throws Exception 如果在实例化类或处理注解时发生异常
*/
private static void registerComponent(Class<?> clazz) throws Exception {
if (clazz.isAnnotationPresent(ComponentBean.class)) {
ComponentBean component = clazz.getAnnotation(ComponentBean.class);
String name = component.value().isEmpty()
? clazz.getName()
: component.value();
Object instance = clazz.getDeclaredConstructor().newInstance();
BEANS.put(name, instance);
TYPE_BEANS.put(clazz, instance);
for (Class<?> interfaceClass : clazz.getInterfaces()) {
TYPE_BEANS.putIfAbsent(interfaceClass, instance);
}
}
}
/**
* 对所有已注册的Bean进行依赖注入处理
*
* @throws Exception 如果在注入过程中发生异常
*/
private static void injectDependencies() throws Exception {
for (Object bean : BEANS.values()) {
for (Field field : bean.getClass().getDeclaredFields()) {
if (field.isAnnotationPresent(InjectBean.class)) {
InjectBean inject = field.getAnnotation(InjectBean.class);
Object dependency = findDependency(
field.getType(),
inject.value()
);
if (dependency == null) {
throw new IllegalStateException(
"No suitable dependency found for field " +
field.getName() +
" in class " +
bean.getClass().getName()
);
}
field.setAccessible(true);
field.set(bean, dependency);
}
}
}
}
/**
* 根据类型和名称查找对应的依赖实例
*
* @param type 依赖的类型
* @param name 依赖的名称可为空
* @return 找到的依赖实例未找到则返回null
*/
private static Object findDependency(Class<?> type, String name) {
if (!name.isEmpty()) {
return BEANS.get(name);
}
Object dependency = TYPE_BEANS.get(type);
if (dependency != null) {
return dependency;
}
for (Class<?> interfaceType : TYPE_BEANS.keySet()) {
if (type.isAssignableFrom(interfaceType)) {
return TYPE_BEANS.get(interfaceType);
}
}
return null;
}
/**
* 将一个对象添加到Bean容器中使用其类名作为键
*
* @param object 要添加的对象
* @throws RuntimeException 如果在注入依赖时发生异常
*/
public static void add(Object object) {
Class<?> clazz = object.getClass();
String name = clazz.getName();
BEANS.put(name, object);
TYPE_BEANS.put(clazz, object);
try {
injectDependencies();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 将一个对象以指定名称添加到Bean容器中
*
* @param name Bean的名称
* @param object 要添加的对象
* @throws RuntimeException 如果在注入依赖时发生异常
*/
public static void add(String name, Object object) {
BEANS.put(name, object);
TYPE_BEANS.put(object.getClass(), object);
try {
injectDependencies();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 根据类型获取对应的Bean实例
*
* @param objclass Bean的类型
* @param <T> Bean的泛型类型
* @return 对应类型的Bean实例未找到则返回null
*/
public static <T> T get(Class<T> objclass) {
return objclass.cast(TYPE_BEANS.get(objclass));
}
/**
* 根据名称和类型获取对应的Bean实例
*
* @param name Bean的名称
* @param objclass Bean的类型
* @param <T> Bean的泛型类型
* @return 对应名称和类型的Bean实例未找到则返回null
*/
public static <T> T get(String name, Class<T> objclass) {
return objclass.cast(BEANS.get(name));
}
/**
* 根据名称获取对应的Bean实例
*
* @param name Bean的名称
* @return 对应名称的Bean实例未找到则返回null
*/
public static Object get(String name) {
return BEANS.get(name);
}
}

View File

@ -1,37 +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 ComponentBean.java
* LastUpdate 2025-09-09 08:37:33
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.bean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author MingLiPro
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ComponentBean {
String value() default "";
}

View File

@ -1,37 +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 InjectBean.java
* LastUpdate 2025-09-09 08:37:34
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.bean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author MingLiPro
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface InjectBean {
String value() default "";
}

View File

@ -1,97 +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 SpringBeanUtil.java
* LastUpdate 2025-09-09 08:37:33
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.bean.springboot;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* Spring Bean工具类
* 实现ApplicationContextAware接口并加入Component注解让spring扫描到该bean
* 该类用于在普通Java类中注入bean,普通Java类中用@Autowired是无法注入bean的
* <p>
* 需要放入扫描类中
*
* @author MingLiPro
*/
@Component
public class SpringBeanUtil implements ApplicationContextAware {
/**
* 获取applicationContext
*/
@Getter
private static ApplicationContext applicationContext;
/**
* 通过bean名称获取Bean实例
*
* @param name bean名称
* @return bean实例对象
*/
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
/**
* 通过bean类型获取Bean实例
*
* @param clazz bean的Class类型
* @param <T> 泛型类型
* @return 指定类型的bean实例
*/
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
/**
* 通过bean名称和类型获取指定的Bean实例
*
* @param name bean名称
* @param clazz bean的Class类型
* @param <T> 泛型类型
* @return 指定名称和类型的bean实例
*/
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
/**
* 设置ApplicationContext上下文对象
* 当Spring容器初始化时会自动调用此方法将ApplicationContext注入到本工具类中
* 通过判断避免重复赋值确保只设置一次ApplicationContext
*
* @param applicationContext Spring应用上下文对象
* @throws BeansException bean异常
*/
@Override
public void setApplicationContext(
@NotNull ApplicationContext applicationContext
) throws BeansException {
SpringBeanUtil.applicationContext = applicationContext;
}
}

View File

@ -1,80 +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 CloneUtil.java
* LastUpdate 2025-09-09 09:32:17
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.clone;
import com.mingliqiye.utils.json.JsonApi;
import com.mingliqiye.utils.json.JsonException;
import java.io.*;
public class CloneUtil {
/**
* 对指定的可序列化对象进行深拷贝
*
* @param object 需要进行深拷贝的对象必须实现Serializable接口
* @param <T> 对象的类型必须实现Serializable接口
* @return 深拷贝后的新对象与原对象内容相同但内存地址不同
* @throws RuntimeException 当序列化或反序列化过程中发生IO异常或类未找到异常时抛出
*/
public static <T extends Serializable> T deepClone(T object) {
try {
ByteArrayOutputStream bao = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bao);
oos.writeObject(object);
ByteArrayInputStream bis = new ByteArrayInputStream(
bao.toByteArray()
);
ObjectInputStream ois = new ObjectInputStream(bis);
return (T) ois.readObject();
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
/**
* 深度克隆对象使用JSON序列化和反序列化实现
*
* @param <T> 对象类型参数
* @param object 需要克隆的对象实例
* @param jsonApi JSON序列化接口实现
* @return 克隆后的对象实例
*/
public static <T> T deepJsonClone(T object, JsonApi jsonApi) {
if (object == null) {
return null;
}
if (jsonApi == null) {
throw new IllegalArgumentException("jsonApi cannot be null");
}
try {
return (T) jsonApi.convert(object, object.getClass());
} catch (Exception e) {
throw new JsonException(
"Failed to deep clone object using JSON",
e
);
}
}
}

View File

@ -16,13 +16,16 @@
* ProjectName mingli-utils * ProjectName mingli-utils
* ModuleName mingli-utils.main * ModuleName mingli-utils.main
* CurrentFile Range.java * CurrentFile Range.java
* LastUpdate 2025-09-12 17:12:29 * LastUpdate 2025-09-14 20:23:26
* UpdateUser MingLiPro * UpdateUser MingLiPro
*/ */
package com.mingliqiye.utils.iterator; package com.mingliqiye.utils.iterator;
import kotlin.ranges.ClosedRange;
import kotlin.ranges.OpenEndRange;
import lombok.Getter; import lombok.Getter;
import lombok.val;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Iterator; import java.util.Iterator;
@ -35,7 +38,8 @@ import java.util.Iterator;
* @since 3.2.6 * @since 3.2.6
*/ */
@Getter @Getter
public class Range implements Iterable<Integer> { public class Range
implements Iterable<Integer>, ClosedRange<Integer>, OpenEndRange<Integer> {
private final int start; private final int start;
private final int end; private final int end;
@ -183,4 +187,35 @@ public class Range implements Iterable<Integer> {
} }
}; };
} }
@Override
public boolean isEmpty() {
return current < end;
}
@Override
public @NotNull Integer getEndInclusive() {
val va = end - step;
return Math.max(va, 0);
}
@Override
public boolean contains(@NotNull Integer integer) {
if (step == 0) return false;
if (step > 0) {
if (integer < start || integer > end) return false;
} else {
if (integer > start || integer < end) return false;
}
return (integer - start) % step == 0;
}
@Override
public @NotNull Integer getEndExclusive() {
return end;
}
@Override
public @NotNull Integer getStart() {
return start;
}
} }

View File

@ -16,7 +16,7 @@
* ProjectName mingli-utils * ProjectName mingli-utils
* ModuleName mingli-utils.main * ModuleName mingli-utils.main
* CurrentFile SuperStream.java * CurrentFile SuperStream.java
* LastUpdate 2025-09-09 08:37:33 * LastUpdate 2025-09-14 20:16:59
* UpdateUser MingLiPro * UpdateUser MingLiPro
*/ */
@ -25,12 +25,13 @@ package com.mingliqiye.utils.stream;
import com.mingliqiye.utils.collection.Lists; import com.mingliqiye.utils.collection.Lists;
import com.mingliqiye.utils.collection.Maps; import com.mingliqiye.utils.collection.Maps;
import com.mingliqiye.utils.stream.interfaces.Getable; import com.mingliqiye.utils.stream.interfaces.Getable;
import lombok.val;
import org.jetbrains.annotations.NotNull;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import java.util.function.*; import java.util.function.*;
import java.util.stream.*; import java.util.stream.*;
import lombok.val;
import org.jetbrains.annotations.NotNull;
/** /**
* 自定义的 SuperStream 实现类用于对集合进行流式操作 * 自定义的 SuperStream 实现类用于对集合进行流式操作

View File

@ -1,271 +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 StringUtil.java
* LastUpdate 2025-09-09 08:37:33
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.string;
import com.mingliqiye.utils.collection.Lists;
import com.mingliqiye.utils.functions.P1RFunction;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 字符串工具类提供常用的字符串处理方法
*/
public class StringUtil {
/**
* 将对象转换为字符串表示形式
*
* @param obj 需要转换的对象可以为null
* @return 如果对象为null则返回空字符串否则返回对象的字符串表示
*/
public static String toString(Object obj) {
// 如果对象为null返回空字符串否则调用对象的toString方法
return obj == null ? "" : obj.toString();
}
/**
* 格式化字符串将格式字符串中的占位符{}替换为对应的参数值<br>
* 示例输出 {} StringUtil.format("{},{},{}", "666", "{}", "777") - "666,{},777"<br>
* 示例 StringUtil.format("{},{},{},{}", "666", "{}", "777") - "666,{},777,"<br>
* 没有实际{} 会替换为 "" 空字符串
*
* @param format 格式字符串使用{}作为占位符如果为null则返回null
* @param args 用于替换占位符的参数数组
* @return 格式化后的字符串
*/
public static String format(String format, Object... args) {
if (format == null) {
return null;
}
StringBuilder sb = new StringBuilder();
int placeholderCount = 0;
int lastIndex = 0;
int len = format.length();
for (int i = 0; i < len - 1; i++) {
if (format.charAt(i) == '{' && format.charAt(i + 1) == '}') {
// 添加前面的部分
sb.append(format, lastIndex, i);
// 替换为 MessageFormat 占位符 {index}
sb.append('{').append(placeholderCount).append('}');
placeholderCount++;
i++; // 跳过 '}'
lastIndex = i + 1;
}
}
// 添加剩余部分
sb.append(format.substring(lastIndex));
// 构造实际参数数组
Object[] actualArgs;
if (args.length < placeholderCount) {
actualArgs = new String[placeholderCount];
System.arraycopy(args, 0, actualArgs, 0, args.length);
for (int i = args.length; i < placeholderCount; i++) {
actualArgs[i] = "";
}
} else {
actualArgs = args;
}
// 如果没有占位符直接返回格式化后的字符串
if (placeholderCount == 0) {
return sb.toString();
}
try {
return MessageFormat.format(
sb.toString(),
(Object[]) Lists.toStringList(actualArgs)
);
} catch (IllegalArgumentException e) {
// 返回原始格式化字符串或抛出自定义异常视业务需求而定
return sb.toString();
}
}
/**
* 判断字符串是否为空
*
* @param str 待检查的字符串
* @return 如果字符串为null或空字符串则返回true否则返回false
*/
public static boolean isEmpty(String str) {
return str == null || str.isEmpty();
}
/**
* 使用指定的分隔符将多个对象连接成一个字符串
*
* @param spec 用作分隔符的字符串
* @param objects 要连接的对象数组
* @return 使用指定分隔符连接后的字符串
*/
public static String joinOf(String spec, String... objects) {
return join(spec, Arrays.asList(objects));
}
/**
* 将字符串按照指定分隔符分割成字符串列表并移除列表开头的空字符串元素
*
* @param str 待分割的字符串
* @param separator 用作分割符的字符串
* @return 分割后的字符串列表不包含开头的空字符串元素
*/
public static List<String> split(String str, String separator) {
List<String> data = new ArrayList<>(
Arrays.asList(str.split(separator))
);
// 移除列表开头的所有空字符串元素
while (!data.isEmpty() && data.get(0).isEmpty()) {
data.remove(0);
}
return data;
}
/**
* 将列表中的元素按照指定分隔符连接成字符串
*
* @param <P> 列表元素的类型
* @param separator 分隔符用于连接各个元素
* @param list 待连接的元素列表
* @param fun 转换函数用于将列表元素转换为字符串如果为null则使用toString()方法
* @return 连接后的字符串如果列表为空或null则返回空字符串
*/
public static <P> String join(
String separator,
List<P> list,
P1RFunction<P, String> fun
) {
// 处理空列表情况
if (list == null || list.isEmpty()) {
return "";
}
// 构建结果字符串
StringBuilder sb = StringUtil.stringBuilder(list.size() * 16);
for (int i = 0; i < list.size(); i++) {
P item = list.get(i);
// 将元素转换为字符串
String itemStr = fun == null
? (item == null ? "null" : item.toString())
: fun.call(item);
// 第一个元素直接添加其他元素先添加分隔符再添加元素
if (i == 0) {
sb.append(itemStr);
} else {
sb.append(separator).append(itemStr);
}
}
return sb.toString();
}
/**
* 使用指定分隔符连接字符串列表
*
* @param separator 分隔符不能为null
* @param list 字符串列表不能为null
* @return 连接后的字符串
* @throws IllegalArgumentException 当separator或list为null时抛出
*/
public static String join(String separator, List<String> list) {
if (separator == null) {
throw new IllegalArgumentException("Separator cannot be null");
}
if (list == null) {
throw new IllegalArgumentException("List cannot be null");
}
return join(separator, list, null);
}
/**
* 创建一个新的StringBuilder实例
*
* @param i 指定StringBuilder的初始容量
* @return 返回一个新的StringBuilder对象其初始容量为指定的大小
*/
public static StringBuilder stringBuilder(int i) {
return new StringBuilder(i);
}
/**
* 将字符串转换为Unicode编码格式
*
* @param str 待转换的字符串
* @return 转换后的Unicode编码字符串每个字符都以\\u开头的十六进制形式表示
*/
public static String stringToUnicode(String str) {
StringBuilder sb = new StringBuilder();
char[] c = str.toCharArray();
for (char value : c) {
sb.append(stringToUnicode(value));
}
return sb.toString();
}
/**
* 将字符转换为Unicode转义字符串
*
* @param c 需要转换的字符
* @return 返回格式为"\\uXXXX"的Unicode转义字符串其中XXXX为字符的十六进制Unicode码点
*/
public static String stringToUnicode(char c) {
return "\\u" + String.format("%04x", (int) c);
}
/**
* 将整数转换为Unicode字符串表示形式
*
* @param c 要转换的整数表示Unicode码点
* @return 返回格式为"\\uXXXX"的Unicode字符串其中XXXX是参数c的十六进制表示
*/
public static String stringToUnicode(Integer c) {
return "\\u" + Integer.toHexString(c);
}
/**
* 将Unicode编码字符串转换为普通字符串
* 该函数接收一个包含Unicode转义序列的字符串将其解析并转换为对应的字符序列
*
* @param unicode 包含Unicode转义序列的字符串格式如"\\uXXXX"其中XXXX为十六进制数
* @return 转换后的普通字符串包含对应的Unicode字符
*/
public static String unicodeToString(String unicode) {
StringBuilder sb = new StringBuilder();
// 按照Unicode转义符分割字符串得到包含十六进制编码的数组
String[] hex = unicode.split("\\\\u");
// 从索引1开始遍历因为分割后的第一个元素是转义符前面的内容可能为空
for (int i = 1; i < hex.length; i++) {
// 将十六进制字符串转换为整数作为字符的Unicode码点
int index = Integer.parseInt(hex[i], 16);
// 将Unicode码点转换为对应字符并添加到结果中
sb.append((char) index);
}
return sb.toString();
}
}

View File

@ -16,7 +16,7 @@
* ProjectName mingli-utils * ProjectName mingli-utils
* ModuleName mingli-utils.main * ModuleName mingli-utils.main
* CurrentFile Main.kt * CurrentFile Main.kt
* LastUpdate 2025-09-12 17:11:48 * LastUpdate 2025-09-14 20:08:44
* UpdateUser MingLiPro * UpdateUser MingLiPro
*/ */
@ -29,4 +29,6 @@ import com.mingliqiye.utils.springboot.autoconfigure.AutoConfiguration
fun main() { fun main() {
AutoConfiguration.printBanner() AutoConfiguration.printBanner()
0..10
} }

View File

@ -16,7 +16,7 @@
* ProjectName mingli-utils * ProjectName mingli-utils
* ModuleName mingli-utils.main * ModuleName mingli-utils.main
* CurrentFile AesUtils.kt * CurrentFile AesUtils.kt
* LastUpdate 2025-09-14 18:19:29 * LastUpdate 2025-09-14 18:43:04
* UpdateUser MingLiPro * UpdateUser MingLiPro
*/ */
@ -25,7 +25,8 @@
package com.mingliqiye.utils.aes package com.mingliqiye.utils.aes
import com.mingliqiye.utils.base64.Base64Utils import com.mingliqiye.utils.base64.decode
import com.mingliqiye.utils.base64.encode
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets
import java.security.GeneralSecurityException import java.security.GeneralSecurityException
import java.security.MessageDigest import java.security.MessageDigest
@ -71,8 +72,8 @@ fun encrypt(sSrc: String, sKey: String?): String? {
val encrypted = cipher.doFinal( val encrypted = cipher.doFinal(
sSrc.toByteArray(StandardCharsets.UTF_8) sSrc.toByteArray(StandardCharsets.UTF_8)
) )
return Base64Utils.encode( return encode(
"${Base64Utils.encode(iv)}:${Base64Utils.encode(encrypted)}".toByteArray() "${encode(iv)}:${encode(encrypted)}".toByteArray()
) )
} }
@ -85,13 +86,13 @@ fun encrypt(sSrc: String, sKey: String?): String? {
fun decrypt(sSrc: String, sKey: String): String? { fun decrypt(sSrc: String, sKey: String): String? {
try { try {
// 分割IV和加密数据 // 分割IV和加密数据
val sSrcs = String(Base64Utils.decode(sSrc)) val sSrcs = String(decode(sSrc))
val parts: Array<String?> = sSrcs.split(":".toRegex(), limit = 2).toTypedArray() val parts: Array<String?> = sSrcs.split(":".toRegex(), limit = 2).toTypedArray()
if (parts.size != 2) { if (parts.size != 2) {
return null return null
} }
val iv = Base64Utils.decode(parts[0]) val iv = decode(parts[0]!!)
val encryptedData = Base64Utils.decode(parts[1]) val encryptedData = decode(parts[1]!!)
if (iv.size != GCM_IV_LENGTH) { if (iv.size != GCM_IV_LENGTH) {
return null return null
} }
@ -114,7 +115,7 @@ fun decrypt(sSrc: String, sKey: String): String? {
* @return SecretKeySpec对象 * @return SecretKeySpec对象
* @throws Exception 可能抛出的异常 * @throws Exception 可能抛出的异常
*/ */
@Throws(GeneralSecurityException::class) @Throws(Exception::class)
private fun createSecretKey(sKey: String): SecretKeySpec { private fun createSecretKey(sKey: String): SecretKeySpec {
val key = sKey.toByteArray(StandardCharsets.UTF_8) val key = sKey.toByteArray(StandardCharsets.UTF_8)
val md = MessageDigest.getInstance("MD5") val md = MessageDigest.getInstance("MD5")

View File

@ -0,0 +1,160 @@
/*
* 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 Base64Utils.kt
* LastUpdate 2025-09-14 18:44:22
* UpdateUser MingLiPro
*/
@file:JvmName("Base64Utils")
package com.mingliqiye.utils.base64
import java.io.File
import java.io.IOException
import java.nio.file.Path
import java.util.*
val BASE_64_ENCODER: Base64.Encoder = Base64.getEncoder()
val BASE_64_DECODER: Base64.Decoder = Base64.getDecoder()
/**
* 将字节数组编码为Base64字符串
*
* @param bytes 需要编码的字节数组
* @return 编码后的Base64字符串
*/
fun encode(bytes: ByteArray): String {
return BASE_64_ENCODER.encodeToString(bytes)
}
/**
* 将Base64字符串解码为字节数组
*
* @param string 需要解码的Base64字符串
* @return 解码后的字节数组
*/
fun decode(string: String): ByteArray {
return BASE_64_DECODER.decode(string)
}
/**
* 将文件内容编码为Base64字符串
*
* @param file 需要编码的文件
* @return 文件内容的Base64编码字符串
* @throws IOException 当文件读取失败时抛出
*/
@Throws(IOException::class)
fun encode(file: File): String {
return encode(file.readBytes())
}
/**
* 将Base64字符串解码并写入文件
*
* @param file 目标文件
* @param string 需要解码的Base64字符串
* @throws IOException 当文件写入失败时抛出
*/
@Throws(IOException::class)
fun decode(file: File, string: String) {
file.writeBytes(decode(string))
}
/**
* 安全地将文件内容编码为Base64字符串出现异常时返回null
*
* @param file 需要编码的文件
* @return 文件内容的Base64编码字符串失败时返回null
*/
fun encodeSafe(file: File): String? {
return try {
encode(file)
} catch (_: Exception) {
null
}
}
/**
* 安全地将Base64字符串解码并写入文件返回操作是否成功
*
* @param file 目标文件
* @param string 需要解码的Base64字符串
* @return 操作成功返回true失败返回false
*/
fun decodeSafe(file: File, string: String): Boolean {
return try {
decode(file, string)
true
} catch (_: Exception) {
false
}
}
/**
* 将路径对应的文件内容编码为Base64字符串
*
* @param path 需要编码的文件路径
* @return 文件内容的Base64编码字符串
* @throws IOException 当文件读取失败时抛出
*/
@Throws(IOException::class)
fun encode(path: Path): String {
return encode(path.toFile().readBytes())
}
/**
* 将Base64字符串解码并写入路径指定的文件
*
* @param path 目标文件路径
* @param string 需要解码的Base64字符串
* @throws IOException 当文件写入失败时抛出
*/
@Throws(IOException::class)
fun decode(path: Path, string: String) {
path.toFile().writeBytes(decode(string))
}
/**
* 安全地将路径对应的文件内容编码为Base64字符串出现异常时返回null
*
* @param path 需要编码的文件路径
* @return 文件内容的Base64编码字符串失败时返回null
*/
fun encodeSafe(path: Path): String? {
return try {
encode(path)
} catch (_: Exception) {
null
}
}
/**
* 安全地将Base64字符串解码并写入路径指定的文件返回操作是否成功
*
* @param path 目标文件路径
* @param string 需要解码的Base64字符串
* @return 操作成功返回true失败返回false
*/
fun decodeSafe(path: Path, string: String): Boolean {
return try {
decode(path, string)
true
} catch (_: Exception) {
false
}
}

View File

@ -0,0 +1,96 @@
/*
* 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 SpringBeanUtils.kt
* LastUpdate 2025-09-14 20:01:26
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.bean.annotation.springboot
import org.springframework.beans.BeansException
import org.springframework.context.ApplicationContext
import org.springframework.context.ApplicationContextAware
import org.springframework.stereotype.Component
/**
* Spring Bean工具类用于获取Spring容器中的Bean实例
* 实现ApplicationContextAware接口以获取Spring的应用上下文
*/
@Component
class SpringBeanUtils : ApplicationContextAware {
companion object {
@JvmStatic
private var applicationContext: ApplicationContext? = null
/**
* 根据Bean名称获取Bean实例
*
* @param name Bean的名称
* @return 指定名称的Bean实例
* @throws BeansException 当获取Bean失败时抛出
* @throws ClassCastException 当类型转换失败时抛出
*/
@JvmStatic
@Throws(BeansException::class, ClassCastException::class)
@Suppress("UNCHECKED_CAST")
fun <T> getBean(name: String): T {
return applicationContext!!.getBean(name) as T
}
/**
* 根据Bean类型获取Bean实例
*
* @param clazz Bean的类型
* @return 指定类型的Bean实例
* @throws BeansException 当获取Bean失败时抛出
*/
@JvmStatic
@Throws(BeansException::class)
fun <T> getBean(clazz: Class<T>): T {
return applicationContext!!.getBean(clazz)
}
/**
* 根据Bean名称和类型获取Bean实例
*
* @param name Bean的名称
* @param clazz Bean的类型
* @return 指定名称和类型的Bean实例
* @throws BeansException 当获取Bean失败时抛出
*/
@JvmStatic
@Throws(BeansException::class)
fun <T> getBean(name: String, clazz: Class<T>): T {
return applicationContext!!.getBean<T>(name, clazz)
}
}
/**
* 设置Spring的应用上下文
*
* @param applicationContext Spring的应用上下文
* @throws BeansException 当设置应用上下文失败时抛出
*/
@Throws(BeansException::class)
override fun setApplicationContext(applicationContext: ApplicationContext) {
SpringBeanUtils.applicationContext = applicationContext
}
}

View File

@ -15,11 +15,11 @@
* *
* ProjectName mingli-utils * ProjectName mingli-utils
* ModuleName mingli-utils.main * ModuleName mingli-utils.main
* CurrentFile ByteUtil.kt * CurrentFile ByteUtils.kt
* LastUpdate 2025-09-14 18:19:29 * LastUpdate 2025-09-14 19:28:38
* UpdateUser MingLiPro * UpdateUser MingLiPro
*/ */
@file:JvmName("ByteUtil") @file:JvmName("ByteUtils")
package com.mingliqiye.utils.bytes package com.mingliqiye.utils.bytes
@ -39,13 +39,11 @@ const val ESC_RESERVED: Byte = 0x06
/** /**
* 将字节数组转换为十六进制字符串列表 * 将字节数组转换为十六进制字符串列表
*
* @param bytes 输入的字节数组
* @return 包含每个字节对应十六进制字符串的列表 * @return 包含每个字节对应十六进制字符串的列表
*/ */
fun getByteArrayString(bytes: ByteArray): MutableList<String> { fun ByteArray.getByteArrayString(): MutableList<String> {
return SuperStream.of(Lists.toList(bytes)) return Lists.toList(this)!!.stream()
.map { a -> String.format("%02x", a!!.toInt() and 0xFF) } .map { a -> String.format("0X%02X", a!!.toInt() and 0xFF) }
.collect(SuperStream.Collectors.toList()) .collect(SuperStream.Collectors.toList())
} }

View File

@ -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 CloneUtil.kt
* LastUpdate 2025-09-14 19:53:41
* UpdateUser MingLiPro
*/
@file:JvmName("CloneUtils")
package com.mingliqiye.utils.clone
import com.mingliqiye.utils.json.JsonApi
import com.mingliqiye.utils.json.JsonException
import java.io.*
inline fun <reified T> Serializable.deepClone(): T {
return deepClone(this) as T
}
inline fun <reified T> T.deepJsonClone(jsonApi: JsonApi): T {
try {
return jsonApi.convert(this, this!!.javaClass) as T
} catch (e: Exception) {
throw JsonException(
"Failed to deep clone object using JSON",
e
)
}
}
@Suppress("UNCHECKED_CAST")
fun <T : Serializable?> deepClone(obj: T): T {
try {
val bao = ByteArrayOutputStream()
val oos = ObjectOutputStream(bao)
oos.writeObject(obj)
val bis = ByteArrayInputStream(
bao.toByteArray()
)
val ois = ObjectInputStream(bis)
return ois.readObject() as T
} catch (e: IOException) {
throw RuntimeException(e)
} catch (e: ClassNotFoundException) {
throw RuntimeException(e)
}
}

View File

@ -0,0 +1,174 @@
/*
* 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 StringUtils.kt
* LastUpdate 2025-09-14 21:46:14
* UpdateUser MingLiPro
*/
@file:JvmName("StringUtils")
package com.mingliqiye.utils.string
import com.mingliqiye.utils.logger.mingLiLoggerFactory
val log = mingLiLoggerFactory.getLogger("StringUtils")
/**
* 判断`字符串`是否为空
*
* @param str 待判断的字符串
* @return `true`: `false`: 非空
*/
fun isEmpty(str: String?): Boolean {
return str?.isEmpty() != null
}
/**
* 格式化字符串将字符串中的占位符{}替换为对应的参数值
*
* `Kotlin`语言给我老老实实用`$`
*
* @param str 需要格式化的字符串包含{}占位符 \\{} 代表一个{}
* @param args 要替换占位符的参数列表
* @return 格式化后的字符串
*/
fun format(str: String, vararg args: Any?): String {
var argIndex = 0
val result = StringBuilder()
var lastIndex = 0
// 匹配所有非转义的 {}
val pattern = Regex("(?<!\\\\)\\{}")
val matches = pattern.findAll(str)
for (match in matches) {
// 添加匹配前的文本
result.append(str, lastIndex, match.range.first)
// 替换占位符
if (argIndex < args.size) {
result.append(args[argIndex].toString())
argIndex++
}
lastIndex = match.range.last + 1
}
// 添加剩余文本
if (lastIndex < str.length) {
result.append(str, lastIndex, str.length)
}
// 处理转义的 \\{}(替换为 {}
val finalResult = result.toString().replace("\\{}", "{}")
// 检查参数数量
val placeholderCount = matches.count()
if (argIndex != args.size) {
log.warn("Placeholder count: $placeholderCount, Argument count: ${args.size}")
}
return finalResult
}
/**
* 将字符串转换为Unicode编码格式
*
* @param str 待转换的字符串
* @return 转换后的Unicode编码字符串每个字符都以\\u开头的十六进制形式表示
*/
fun stringToUnicode(str: String): String {
val sb = java.lang.StringBuilder()
val c = str.toCharArray()
for (value in c) {
sb.append(stringToUnicode(value))
}
return sb.toString()
}
/**
* 将字符转换为Unicode转义字符串
*
* @param c 需要转换的字符
* @return 返回格式为"\\uXXXX"的Unicode转义字符串其中XXXX为字符的十六进制Unicode码点
*/
fun stringToUnicode(c: Char): String {
return "\\u" + String.format("%04x", c.code)
}
/**
* 将整数转换为Unicode字符串表示形式
*
* @param c 要转换的整数表示Unicode码点
* @return 返回格式为"\\uXXXX"的Unicode字符串其中XXXX是参数c的十六进制表示
*/
fun stringToUnicode(c: Int): String {
return "\\u" + Integer.toHexString(c)
}
/**
* 将Unicode编码字符串转换为普通字符串
*
* 该函数接收一个包含Unicode转义序列的字符串将其解析并转换为对应的字符序列
*
* @param unicode 包含Unicode转义序列的字符串格式如"\\uXXXX"其中XXXX为十六进制数
* @return 转换后的普通字符串包含对应的Unicode字符
*/
fun unicodeToString(unicode: String): String {
val sb = java.lang.StringBuilder()
// 按照Unicode转义符分割字符串得到包含十六进制编码的数组
val hex: Array<String?> = unicode.split("\\\\u".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
// 从索引1开始遍历因为分割后的第一个元素是转义符前面的内容可能为空
for (i in 1..<hex.size) {
// 将十六进制字符串转换为整数作为字符的Unicode码点
val index = hex[i]!!.toInt(16)
// 将Unicode码点转换为对应字符并添加到结果中
sb.append(index.toChar())
}
return sb.toString()
}
/**
* 创建一个指定初始容量的StringBuilder实例
*
* @param i StringBuilder的初始容量
* @return 指定初始容量的StringBuilder实例
*/
fun stringBuilder(i: Int): java.lang.StringBuilder {
return StringBuilder(i)
}
/**
* 根据当前字符串创建一个StringBuilder实例
*
* @return 包含当前字符串内容的StringBuilder实例
*/
fun String.stringBuilder(): java.lang.StringBuilder {
return StringBuilder(this)
}
fun split(str: String, separator: String): List<String> {
return str.split(separator)
}
fun List<String>.join(separator: String): String {
return this.joinToString(separator)
}

View File

@ -16,10 +16,9 @@
* ProjectName mingli-utils * ProjectName mingli-utils
* ModuleName mingli-utils.main * ModuleName mingli-utils.main
* CurrentFile UUID.kt * CurrentFile UUID.kt
* LastUpdate 2025-09-12 16:57:52 * LastUpdate 2025-09-14 19:55:47
* UpdateUser MingLiPro * UpdateUser MingLiPro
*/ */
package com.mingliqiye.utils.uuid package com.mingliqiye.utils.uuid
import com.github.f4b6a3.uuid.UuidCreator import com.github.f4b6a3.uuid.UuidCreator
@ -84,6 +83,16 @@ class UUID : Serializable {
return UUID(uuid) return UUID(uuid)
} }
/**
* 从Java的UUID
* @param uuid 字符串
* @return UUID
*/
@JvmStatic
fun of(uuid: JUUID): UUID {
return UUID(uuid)
}
/** /**
* 从字节码转换到UUID * 从字节码转换到UUID
* @param array 16字节 * @param array 16字节
@ -93,6 +102,10 @@ class UUID : Serializable {
fun of(array: ByteArray): UUID { fun of(array: ByteArray): UUID {
return UUID(array) return UUID(array)
} }
fun JUUID.toMlUUID(): UUID {
return of(this)
}
} }
internal constructor(msb: Long, lsb: Long) { internal constructor(msb: Long, lsb: Long) {
@ -108,10 +121,11 @@ class UUID : Serializable {
this.uuid = JUUID(bb.getLong(), bb.getLong()) this.uuid = JUUID(bb.getLong(), bb.getLong())
} }
internal constructor(uuid: String) { constructor(uuid: String) {
this.uuid = JUUID.fromString(uuid) this.uuid = JUUID.fromString(uuid)
} }
/** /**
* 获取对应的字节码 * 获取对应的字节码
* @return 字节码 * @return 字节码
@ -242,3 +256,5 @@ class UUID : Serializable {
return uuid.hashCode() return uuid.hashCode()
} }
} }