From d58a1063c1a88c8e7a0a2559d866c014d5fa8ab8 Mon Sep 17 00:00:00 2001 From: minglipro Date: Wed, 30 Jul 2025 14:39:50 +0800 Subject: [PATCH] =?UTF-8?q?feat(utils):=20=E6=96=B0=E5=A2=9E=20Base64Utils?= =?UTF-8?q?=20=E5=B7=A5=E5=85=B7=E7=B1=BB=E5=92=8C=20ForEach=20=E5=A2=9E?= =?UTF-8?q?=E5=BC=BA=E9=81=8D=E5=8E=86=E5=B7=A5=E5=85=B7-=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=20Base64Utils=E5=B7=A5=E5=85=B7=E7=B1=BB=EF=BC=8C?= =?UTF-8?q?=E6=8F=90=E4=BE=9B=20Base64=20=E7=BC=96=E7=A0=81=E5=92=8C?= =?UTF-8?q?=E8=A7=A3=E7=A0=81=E5=8A=9F=E8=83=BD-=20=E6=96=B0=E5=A2=9E=20Fo?= =?UTF-8?q?rEach=20=E5=B7=A5=E5=85=B7=E7=B1=BB=EF=BC=8C=E5=A2=9E=E5=BC=BA?= =?UTF-8?q?=E9=9B=86=E5=90=88=E5=92=8C=E6=98=A0=E5=B0=84=E7=9A=84=E9=81=8D?= =?UTF-8?q?=E5=8E=86=E5=8A=9F=E8=83=BD=20-=20=E4=BC=98=E5=8C=96=20Collecti?= =?UTF-8?q?on=20=E5=B7=A5=E5=85=B7=E7=B1=BB=E4=B8=AD=E7=9A=84=20sublist=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 --- .../mingliqiye/utils/base64/Base64Utils.java | 172 +++++++++++++++ .../utils/collection/Collection.java | 1 - .../mingliqiye/utils/collection/ForEach.java | 201 ++++++++++++++++++ 3 files changed, 373 insertions(+), 1 deletion(-) create mode 100644 src/com/mingliqiye/utils/base64/Base64Utils.java create mode 100644 src/com/mingliqiye/utils/collection/ForEach.java diff --git a/src/com/mingliqiye/utils/base64/Base64Utils.java b/src/com/mingliqiye/utils/base64/Base64Utils.java new file mode 100644 index 0000000..4184c80 --- /dev/null +++ b/src/com/mingliqiye/utils/base64/Base64Utils.java @@ -0,0 +1,172 @@ +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); + } +} diff --git a/src/com/mingliqiye/utils/collection/Collection.java b/src/com/mingliqiye/utils/collection/Collection.java index 8c0ccbe..3ed6e1f 100644 --- a/src/com/mingliqiye/utils/collection/Collection.java +++ b/src/com/mingliqiye/utils/collection/Collection.java @@ -160,7 +160,6 @@ public class Collection { // 调整边界 fromIndex = Math.max(0, fromIndex); toIndex = Math.min(size, toIndex); - if (fromIndex >= toIndex) { return Collections.emptyList(); } diff --git a/src/com/mingliqiye/utils/collection/ForEach.java b/src/com/mingliqiye/utils/collection/ForEach.java new file mode 100644 index 0000000..4b01623 --- /dev/null +++ b/src/com/mingliqiye/utils/collection/ForEach.java @@ -0,0 +1,201 @@ +package com.mingliqiye.utils.collection; + +import java.util.*; +import java.util.Collection; +import java.util.concurrent.ConcurrentMap; + +/** + * ListsAMaps 工具类提供对集合和映射的增强遍历功能。 + * 包含多个重载的 forEach 方法,支持带索引的遍历操作。 + */ +public class ForEach { + + /** + * 对给定的集合执行指定的操作,操作包含元素值和索引。 + * 根据集合类型选择最优的遍历方式以提高性能。 + * + * @param collection 要遍历的集合,可以是 List 或其他 Collection 实现 + * @param action 要对每个元素执行的操作,接收元素值和索引作为参数 + * @param 集合中元素的类型 + */ + public static void forEach( + Collection collection, + ForEach.Consumer action + ) { + // 参数校验:如果集合或操作为空,则直接返回 + if (collection == null || action == null) { + return; + } + + // 如果集合实现了 RandomAccess 接口(如 ArrayList),使用索引访问优化性能 + if (collection instanceof RandomAccess && collection instanceof List) { + List list = (List) collection; + for (int i = 0; i < list.size(); i++) { + action.call(list.get(i), i); + } + } + // 如果是普通 List,使用迭代器遍历并手动维护索引 + else if (collection instanceof List) { + int index = 0; + Iterator it = collection.iterator(); + while (it.hasNext()) { + action.call(it.next(), index); + index++; + } + } + // 其他类型的集合使用增强 for 循环,并手动维护索引 + else { + int index = 0; + for (T element : collection) { + action.call(element, index); + index++; + } + } + } + + /** + * 对给定的集合执行指定的操作,仅处理元素值。 + * 根据集合是否实现 RandomAccess 接口选择最优的遍历方式。 + * + * @param collection 要遍历的集合 + * @param action 要对每个元素执行的操作,只接收元素值作为参数 + * @param 集合中元素的类型 + */ + public static void forEach( + Collection collection, + java.util.function.Consumer action + ) { + // 参数校验:如果集合或操作为空,则直接返回 + if (collection == null || action == null) { + return; + } + + // 如果集合实现了 RandomAccess 接口,使用索引访问提升性能 + if (collection instanceof RandomAccess) { + List list = (List) collection; + for (int i = 0; i < list.size(); i++) { + action.accept(list.get(i)); + } + } + // 否则使用增强 for 循环进行遍历 + else { + for (T element : collection) { + action.accept(element); + } + } + } + + /** + * 对给定的映射执行指定的操作,操作包含键、值和索引。 + * 根据映射类型选择不同的遍历策略。 + * + * @param map 要遍历的映射 + * @param action 要对每个键值对执行的操作,接收键、值和索引作为参数 + * @param 映射中键的类型 + * @param 映射中值的类型 + */ + public static void forEach( + Map map, + BiConsumer action + ) { + // 参数校验:如果映射或操作为空,则直接返回 + if (map == null || action == null) { + return; + } + + // 遍历 TreeMap 的条目集合并传递索引 + if (map instanceof TreeMap) { + int index = 0; + for (Map.Entry entry : map.entrySet()) { + action.call(entry.getKey(), entry.getValue(), index); + index++; + } + } + // 遍历 ConcurrentMap 或 LinkedHashMap 的条目集合并传递索引 + else if (map instanceof ConcurrentMap || map instanceof LinkedHashMap) { + int index = 0; + for (Map.Entry entry : map.entrySet()) { + action.call(entry.getKey(), entry.getValue(), index); + index++; + } + } + // 遍历其他类型映射的条目集合并传递索引 + else { + int index = 0; + for (Map.Entry entry : map.entrySet()) { + action.call(entry.getKey(), entry.getValue(), index); + index++; + } + } + } + + /** + * 对给定的映射执行指定的操作,仅处理键和值。 + * 根据映射类型选择不同的遍历策略。 + * + * @param map 要遍历的映射 + * @param action 要对每个键值对执行的操作,接收键和值作为参数 + * @param 映射中键的类型 + * @param 映射中值的类型 + */ + public static void forEach( + Map map, + java.util.function.BiConsumer action + ) { + // 参数校验:如果映射或操作为空,则直接返回 + if (map == null || action == null) { + return; + } + + // 遍历 TreeMap 的条目集合 + if (map instanceof TreeMap) { + for (Map.Entry entry : map.entrySet()) { + action.accept(entry.getKey(), entry.getValue()); + } + } + // 如果是 ConcurrentMap 或 LinkedHashMap,使用其内置的 forEach 方法 + else if (map instanceof ConcurrentMap || map instanceof LinkedHashMap) { + map.forEach(action); + } + // 遍历其他类型映射的条目集合 + else { + for (Map.Entry entry : map.entrySet()) { + action.accept(entry.getKey(), entry.getValue()); + } + } + } + + /** + * 自定义消费者接口,用于接收元素值和索引。 + * + * @param 元素类型 + */ + @FunctionalInterface + public interface Consumer { + /** + * 执行消费操作。 + * + * @param value 元素值 + * @param index 元素在集合中的索引 + */ + void call(T value, int index); + } + + /** + * 自定义二元消费者接口,用于接收键、值和索引。 + * + * @param 键类型 + * @param 值类型 + */ + @FunctionalInterface + public interface BiConsumer { + /** + * 执行消费操作。 + * + * @param key 键 + * @param value 值 + * @param index 键值对在映射中的索引 + */ + void call(K key, V value, int index); + } +}