refactor(build.gradle.kts):优化构建配置文件
All checks were successful
Gitea Actions Build / Build (push) Successful in 1m2s

- 添加 sourceSets 配置,明确主代码源目录
- 设置 Java 工具链语言版本为 8- 配置 JAR 任务的 duplicatesStrategy 为 EXCLUDE- 更新 META-INF/meta-data 处理方式
This commit is contained in:
Armamem0t 2025-09-10 23:23:37 +08:00
parent 1c49c6e151
commit bbafa86872
Signed by: minglipro
GPG Key ID: 5F355A77B22AA93B
25 changed files with 960 additions and 362 deletions

View File

@ -41,12 +41,24 @@ base {
archivesName.set(ARTIFACTID)
}
sourceSets {
main {
java {
srcDirs("src/main/java")
}
resources {
srcDirs("src/main/resources")
}
}
}
java {
withJavadocJar()
withSourcesJar()
toolchain.languageVersion.set(JavaLanguageVersion.of(8))
}
dependencies {
annotationProcessor("org.jetbrains:annotations:24.0.0")
annotationProcessor("org.projectlombok:lombok:1.18.38")
@ -79,7 +91,10 @@ tasks.withType<Javadoc> {
options.encoding = "UTF-8"
}
tasks.withType<org.gradle.jvm.tasks.Jar> {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
manifest {
attributes(
mapOf(
@ -129,6 +144,8 @@ publishing {
}
tasks.processResources {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
outputs.upToDateWhen { false }
filesMatching("META-INF/meta-data") {
expand(
mapOf(
@ -142,4 +159,3 @@ tasks.processResources {
)
}
}

View File

@ -22,4 +22,4 @@
JDKVERSIONS=1.8
GROUPSID=com.mingliqiye.utils
ARTIFACTID=mingli-utils
VERSIONS=3.0.3
VERSIONS=3.0.4

View File

@ -22,388 +22,455 @@
package com.mingliqiye.utils.collection;
import com.mingliqiye.utils.functions.P1Function;
import com.mingliqiye.utils.functions.P2Function;
import com.mingliqiye.utils.functions.P3Function;
import com.mingliqiye.utils.stream.SuperStream;
import java.util.*;
import java.util.Collection;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;
/**
* 集合和映射的增强遍历功能
* ListsAMaps 工具类提供对集合和映射的增强遍历功能
* 包含多个重载的 forEach 方法支持带索引的遍历操作
* 包含多个重载的 forEach 方法支持带索引的遍历操作<br>
*
* 不可终止的遍历 可以使用 ForEachBreaked
*
* @since 3.0.4
*
* @see com.mingliqiye.utils.collection.ForEachBreaked
* @author MingLiPro
*/
public class ForEach {
/**
* 对给定的集合执行指定的操作操作包含元素值和索引
* 根据集合类型选择最优的遍历方式以提高性能
*
* @param collection 要遍历的集合可以是 List 或其他 Collection 实现
* @param action 要对每个元素执行的操作接收元素值和索引作为参数
* @param <T> 集合中元素的类型
*/
public static <T> void forEach(
Collection<T> collection,
ForEach.Consumer<? super T> action
) {
// 参数校验如果集合或操作为空则直接返回
if (collection == null || action == null) {
return;
}
/**
* 对给定的集合执行指定的操作操作包含元素值和索引
* 根据集合类型选择最优的遍历方式以提高性能
*
* @param collection 要遍历的集合可以是 List 或其他 Collection 实现
* @param action 要对每个元素执行的操作接收元素值和索引作为参数
* @param <T> 集合中元素的类型
*/
public static <T> void forEach(Collection<T> collection, P2Function<? super T, Integer> action) {
// 参数校验如果集合或操作为空则直接返回
if (collection == null || action == null) {
return;
}
// 如果集合实现了 RandomAccess 接口 ArrayList使用索引访问优化性能
if (collection instanceof RandomAccess && collection instanceof List) {
List<T> list = (List<T>) 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<T> 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 接口 ArrayList使用索引访问优化性能
if (collection instanceof RandomAccess && collection instanceof List) {
List<T> list = (List<T>) 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<T> 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 <T> 集合中元素的类型
*/
public static <T> void forEach(
Collection<T> collection,
java.util.function.Consumer<? super T> action
) {
// 参数校验如果集合或操作为空则直接返回
if (collection == null || action == null) {
return;
}
/**
* 对给定的集合执行指定的操作仅处理元素值
* 根据集合是否实现 RandomAccess 接口选择最优的遍历方式
*
* @param collection 要遍历的集合
* @param action 要对每个元素执行的操作只接收元素值作为参数
* @param <T> 集合中元素的类型
*/
public static <T> void forEach(Collection<T> collection, P1Function<? super T> action) {
// 参数校验如果集合或操作为空则直接返回
if (collection == null || action == null) {
return;
}
// 如果集合实现了 RandomAccess 接口使用索引访问提升性能
if (collection instanceof RandomAccess) {
List<T> list = (List<T>) collection;
for (int i = 0; i < list.size(); i++) {
action.accept(list.get(i));
}
}
// 否则使用增强 for 循环进行遍历
else {
for (T element : collection) {
action.accept(element);
}
}
}
// 如果集合实现了 RandomAccess 接口使用索引访问提升性能
if (collection instanceof RandomAccess) {
List<T> list = (List<T>) collection;
for (int i = 0; i < list.size(); i++) {
action.call(list.get(i));
}
}
// 否则使用增强 for 循环进行遍历
else {
for (T element : collection) {
action.call(element);
}
}
}
/**
* 对给定的映射执行指定的操作操作包含键值和索引
* 根据映射类型选择不同的遍历策略
*
* @param map 要遍历的映射
* @param action 要对每个键值对执行的操作接收键值和索引作为参数
* @param <K> 映射中键的类型
* @param <V> 映射中值的类型
*/
public static <K, V> void forEach(
Map<K, V> map,
BiConsumer<? super K, ? super V> action
) {
// 参数校验如果映射或操作为空则直接返回
if (map == null || action == null) {
return;
}
/**
* 对给定的映射执行指定的操作操作包含键值和索引
* 根据映射类型选择不同的遍历策略
*
* @param map 要遍历的映射
* @param action 要对每个键值对执行的操作接收键值和索引作为参数
* @param <K> 映射中键的类型
* @param <V> 映射中值的类型
*/
public static <K, V> void forEach(Map<K, V> map, P3Function<? super K, ? super V, Integer> action) {
// 参数校验如果映射或操作为空则直接返回
if (map == null || action == null) {
return;
}
// 遍历 TreeMap 的条目集合并传递索引
if (map instanceof TreeMap) {
int index = 0;
for (Map.Entry<K, V> 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<K, V> entry : map.entrySet()) {
action.call(entry.getKey(), entry.getValue(), index);
index++;
}
}
// 遍历其他类型映射的条目集合并传递索引
else {
int index = 0;
for (Map.Entry<K, V> entry : map.entrySet()) {
action.call(entry.getKey(), entry.getValue(), index);
index++;
}
}
}
// 遍历 TreeMap 的条目集合并传递索引
if (map instanceof TreeMap) {
int index = 0;
for (Map.Entry<K, V> 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<K, V> entry : map.entrySet()) {
action.call(entry.getKey(), entry.getValue(), index);
index++;
}
}
// 遍历其他类型映射的条目集合并传递索引
else {
int index = 0;
for (Map.Entry<K, V> entry : map.entrySet()) {
action.call(entry.getKey(), entry.getValue(), index);
index++;
}
}
}
/**
* 对给定的映射执行指定的操作仅处理键和值
* 根据映射类型选择不同的遍历策略
*
* @param map 要遍历的映射
* @param action 要对每个键值对执行的操作接收键和值作为参数
* @param <K> 映射中键的类型
* @param <V> 映射中值的类型
*/
public static <K, V> void forEach(
Map<K, V> map,
java.util.function.BiConsumer<? super K, ? super V> action
) {
// 参数校验如果映射或操作为空则直接返回
if (map == null || action == null) {
return;
}
/**
* 对给定的映射执行指定的操作仅处理键和值
* 根据映射类型选择不同的遍历策略
*
* @param map 要遍历的映射
* @param action 要对每个键值对执行的操作接收键和值作为参数
* @param <K> 映射中键的类型
* @param <V> 映射中值的类型
*/
public static <K, V> void forEach(Map<K, V> map, P2Function<? super K, ? super V> action) {
// 参数校验如果映射或操作为空则直接返回
if (map == null || action == null) {
return;
}
// 遍历 TreeMap 的条目集合
if (map instanceof TreeMap) {
for (Map.Entry<K, V> 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<K, V> entry : map.entrySet()) {
action.accept(entry.getKey(), entry.getValue());
}
}
}
// 遍历 TreeMap 的条目集合
if (map instanceof TreeMap) {
for (Map.Entry<K, V> entry : map.entrySet()) {
action.call(entry.getKey(), entry.getValue());
}
}
// 如果是 ConcurrentMap LinkedHashMap使用其内置的 forEach 方法
else if (map instanceof ConcurrentMap || map instanceof LinkedHashMap) {
forEach(map.entrySet(), (i) -> action.call(i.getKey(), i.getValue()));
}
// 遍历其他类型映射的条目集合
else {
for (Map.Entry<K, V> entry : map.entrySet()) {
action.call(entry.getKey(), entry.getValue());
}
}
}
public static <T> void forEach(Consumer<? super T> action, T... objects) {
int i = 0;
while (i < objects.length) {
T object = objects[i];
action.call(object, i);
i++;
}
}
/**
* 对可变参数数组执行指定的操作操作包含元素值和索引
*
* @param action 要对每个元素执行的操作接收元素值和索引作为参数
* @param objects 要遍历的可变参数数组
* @param <T> 数组中元素的类型
*/
public static <T> void forEach(P2Function<? super T, Integer> action, T... objects) {
forEach(Lists.newArrayList(objects), action);
}
public static <T> void forEach(T[] objects, Consumer<? super T> action) {
forEach(action, objects);
}
/**
* 对数组执行指定的操作操作包含元素值和索引
*
* @param objects 要遍历的数组
* @param action 要对每个元素执行的操作接收元素值和索引作为参数
* @param <T> 数组中元素的类型
*/
public static <T> void forEach(T[] objects, P2Function<? super T, Integer> action) {
forEach(action, objects);
}
public static <T> void forEach(
T[] objects,
java.util.function.Consumer<? super T> action
) {
forEach(action, objects);
}
/**
* 对数组执行指定的操作仅处理元素值
*
* @param objects 要遍历的数组
* @param action 要对每个元素执行的操作只接收元素值作为参数
* @param <T> 数组中元素的类型
*/
public static <T> void forEach(T[] objects, P1Function<? super T> action) {
forEach(action, objects);
}
public static <T> void forEach(
java.util.function.Consumer<? super T> action,
T... objects
) {
forEach((t, i) -> action.accept(t), objects);
}
/**
* 对可变参数数组执行指定的操作仅处理元素值
*
* @param action 要对每个元素执行的操作只接收元素值作为参数
* @param objects 要遍历的可变参数数组
* @param <T> 数组中元素的类型
*/
public static <T> void forEach(P1Function<? super T> action, T... objects) {
forEach(Lists.toList(objects), (t, i) -> action.call(t));
}
public static void forEach(int[] objects, Consumer<Integer> action) {
forEach(action, objects);
}
/**
* 对整型数组执行指定的操作操作包含元素值和索引
*
* @param objects 要遍历的整型数组
* @param action 要对每个元素执行的操作接收元素值和索引作为参数
*/
public static void forEach(int[] objects, P2Function<Integer, Integer> action) {
forEach(action, objects);
}
private static void forEach(Consumer<Integer> action, int... objects) {
for (int i = 0; i < objects.length; i++) {
action.call(objects[i], i);
}
}
/**
* 对整型可变参数数组执行指定的操作操作包含元素值和索引
*
* @param action 要对每个元素执行的操作接收元素值和索引作为参数
* @param objects 要遍历的整型可变参数数组
*/
private static void forEach(P2Function<Integer, Integer> action, int... objects) {
forEach(objects, action);
}
private static void forEach(
java.util.function.Consumer<Integer> action,
int... objects
) {
for (Integer object : objects) {
action.accept(object);
}
}
/**
* 对整型可变参数数组执行指定的操作仅处理元素值
*
* @param action 要对每个元素执行的操作只接收元素值作为参数
* @param objects 要遍历的整型可变参数数组
*/
private static void forEach(P1Function<Integer> action, int... objects) {
forEach(Lists.toList(objects), action);
}
public static void forEach(byte[] objects, Consumer<Byte> action) {
forEach(action, objects);
}
/**
* 对字节数组执行指定的操作操作包含元素值和索引
*
* @param objects 要遍历的字节数组
* @param action 要对每个元素执行的操作接收元素值和索引作为参数
*/
public static void forEach(byte[] objects, P2Function<Byte, Integer> action) {
forEach(Lists.toList(objects), action);
}
private static void forEach(Consumer<Byte> action, byte... objects) {
for (int i = 0; i < objects.length; i++) {
action.call(objects[i], i);
}
}
/**
* 对字节可变参数数组执行指定的操作操作包含元素值和索引
*
* @param action 要对每个元素执行的操作接收元素值和索引作为参数
* @param objects 要遍历的字节可变参数数组
*/
private static void forEach(P2Function<Byte, Integer> action, byte... objects) {
forEach(objects, action);
}
private static void forEach(
java.util.function.Consumer<Byte> action,
byte... objects
) {
for (Byte object : objects) {
action.accept(object);
}
}
/**
* 对字节可变参数数组执行指定的操作仅处理元素值
*
* @param action 要对每个元素执行的操作只接收元素值作为参数
* @param objects 要遍历的字节可变参数数组
*/
private static void forEach(P1Function<Byte> action, byte... objects) {
forEach(Lists.toList(objects), action);
}
// short类型
public static void forEach(short[] objects, Consumer<Short> action) {
forEach(action, objects);
}
/**
* 对短整型数组执行指定的操作操作包含元素值和索引
*
* @param objects 要遍历的短整型数组
* @param action 要对每个元素执行的操作接收元素值和索引作为参数
*/
public static void forEach(short[] objects, P2Function<Short, Integer> action) {
forEach(Lists.toList(objects), action);
}
private static void forEach(Consumer<Short> action, short... objects) {
for (int i = 0; i < objects.length; i++) {
action.call(objects[i], i);
}
}
/**
* 对短整型可变参数数组执行指定的操作操作包含元素值和索引
*
* @param action 要对每个元素执行的操作接收元素值和索引作为参数
* @param objects 要遍历的短整型可变参数数组
*/
private static void forEach(P2Function<Short, Integer> action, short... objects) {
forEach(objects, action);
}
private static void forEach(
java.util.function.Consumer<Short> action,
short... objects
) {
for (short object : objects) {
action.accept(object);
}
}
/**
* 对短整型可变参数数组执行指定的操作仅处理元素值
*
* @param action 要对每个元素执行的操作只接收元素值作为参数
* @param objects 要遍历的短整型可变参数数组
*/
private static void forEach(P1Function<Short> action, short... objects) {
forEach(Lists.toList(objects), action);
}
// long类型
public static void forEach(long[] objects, Consumer<Long> action) {
forEach(action, objects);
}
/**
* 对长整型数组执行指定的操作操作包含元素值和索引
*
* @param objects 要遍历的长整型数组
* @param action 要对每个元素执行的操作接收元素值和索引作为参数
*/
public static void forEach(long[] objects, P2Function<Long, Integer> action) {
forEach(action, objects);
}
private static void forEach(Consumer<Long> action, long... objects) {
for (int i = 0; i < objects.length; i++) {
action.call(objects[i], i);
}
}
/**
* 对长整型可变参数数组执行指定的操作操作包含元素值和索引
*
* @param action 要对每个元素执行的操作接收元素值和索引作为参数
* @param objects 要遍历的长整型可变参数数组
*/
private static void forEach(P2Function<Long, Integer> action, long... objects) {
forEach(Lists.toList(objects), action);
}
private static void forEach(
java.util.function.Consumer<Long> action,
long... objects
) {
for (long object : objects) {
action.accept(object);
}
}
/**
* 对长整型可变参数数组执行指定的操作仅处理元素值
*
* @param action 要对每个元素执行的操作只接收元素值作为参数
* @param objects 要遍历的长整型可变参数数组
*/
private static void forEach(P1Function<Long> action, long... objects) {
forEach(Lists.toList(objects), action);
}
// float类型
public static void forEach(float[] objects, Consumer<Float> action) {
forEach(action, objects);
}
/**
* 对浮点数组执行指定的操作操作包含元素值和索引
*
* @param objects 要遍历的浮点数组
* @param action 要对每个元素执行的操作接收元素值和索引作为参数
*/
public static void forEach(float[] objects, P2Function<Float, Integer> action) {
forEach(action, objects);
}
private static void forEach(Consumer<Float> action, float... objects) {
for (int i = 0; i < objects.length; i++) {
action.call(objects[i], i);
}
}
/**
* 对浮点可变参数数组执行指定的操作操作包含元素值和索引
*
* @param action 要对每个元素执行的操作接收元素值和索引作为参数
* @param objects 要遍历的浮点可变参数数组
*/
private static void forEach(P2Function<Float, Integer> action, float... objects) {
forEach(Lists.toList(objects), action);
}
private static void forEach(
java.util.function.Consumer<Float> action,
float... objects
) {
for (float object : objects) {
action.accept(object);
}
}
/**
* 对浮点可变参数数组执行指定的操作仅处理元素值
*
* @param action 要对每个元素执行的操作只接收元素值作为参数
* @param objects 要遍历的浮点可变参数数组
*/
private static void forEach(P1Function<Float> action, float... objects) {
forEach(Lists.toList(objects), action);
}
// double类型
public static void forEach(double[] objects, Consumer<Double> action) {
forEach(action, objects);
}
/**
* 对双精度浮点数组执行指定的操作操作包含元素值和索引
*
* @param objects 要遍历的双精度浮点数组
* @param action 要对每个元素执行的操作接收元素值和索引作为参数
*/
public static void forEach(double[] objects, P2Function<Double, Integer> action) {
forEach(action, objects);
}
private static void forEach(Consumer<Double> action, double... objects) {
for (int i = 0; i < objects.length; i++) {
action.call(objects[i], i);
}
}
/**
* 对双精度浮点可变参数数组执行指定的操作操作包含元素值和索引
*
* @param action 要对每个元素执行的操作接收元素值和索引作为参数
* @param objects 要遍历的双精度浮点可变参数数组
*/
private static void forEach(P2Function<Double, Integer> action, double... objects) {
forEach(Lists.toList(objects), action);
}
private static void forEach(
java.util.function.Consumer<Double> action,
double... objects
) {
for (double object : objects) {
action.accept(object);
}
}
/**
* 对双精度浮点可变参数数组执行指定的操作仅处理元素值
*
* @param action 要对每个元素执行的操作只接收元素值作为参数
* @param objects 要遍历的双精度浮点可变参数数组
*/
private static void forEach(P1Function<Double> action, double... objects) {
forEach(Lists.toList(objects), action);
}
// char类型
public static void forEach(char[] objects, Consumer<Character> action) {
forEach(action, objects);
}
/**
* 对字符数组执行指定的操作操作包含元素值和索引
*
* @param objects 要遍历的字符数组
* @param action 要对每个元素执行的操作接收元素值和索引作为参数
*/
public static void forEach(char[] objects, P2Function<Character, Integer> action) {
forEach(action, objects);
}
private static void forEach(Consumer<Character> action, char... objects) {
for (int i = 0; i < objects.length; i++) {
action.call(objects[i], i);
}
}
/**
* 对字符可变参数数组执行指定的操作操作包含元素值和索引
*
* @param action 要对每个元素执行的操作接收元素值和索引作为参数
* @param objects 要遍历的字符可变参数数组
*/
private static void forEach(P2Function<Character, Integer> action, char... objects) {
forEach(Lists.toList(objects), action);
}
private static void forEach(
java.util.function.Consumer<Character> action,
char... objects
) {
for (char object : objects) {
action.accept(object);
}
}
/**
* 对字符可变参数数组执行指定的操作仅处理元素值
*
* @param action 要对每个元素执行的操作只接收元素值作为参数
* @param objects 要遍历的字符可变参数数组
*/
private static void forEach(P1Function<Character> action, char... objects) {
forEach(Lists.toList(objects), action);
}
// boolean类型
public static void forEach(boolean[] objects, Consumer<Boolean> action) {
forEach(action, objects);
}
/**
* 对布尔数组执行指定的操作操作包含元素值和索引
*
* @param objects 要遍历的布尔数组
* @param action 要对每个元素执行的操作接收元素值和索引作为参数
*/
public static void forEach(boolean[] objects, P2Function<Character, Integer> action) {
forEach(objects, action);
}
private static void forEach(Consumer<Boolean> action, boolean... objects) {
for (int i = 0; i < objects.length; i++) {
action.call(objects[i], i);
}
}
/**
* 对布尔可变参数数组执行指定的操作操作包含元素值和索引
*
* @param action 要对每个元素执行的操作接收元素值和索引作为参数
* @param objects 要遍历的布尔可变参数数组
*/
private static void forEach(P2Function<Boolean, Integer> action, boolean... objects) {
forEach(Lists.toList(objects), action);
}
private static void forEach(
java.util.function.Consumer<Boolean> action,
boolean... objects
) {
for (boolean object : objects) {
action.accept(object);
}
}
/**
* 对布尔可变参数数组执行指定的操作仅处理元素值
*
* @param action 要对每个元素执行的操作只接收元素值作为参数
* @param objects 要遍历的布尔可变参数数组
*/
private static void forEach(P1Function<Boolean> action, boolean... objects) {
forEach(Lists.toList(objects), action);
}
/**
* 自定义消费者接口用于接收元素值和索引
*
* @param <T> 元素类型
*/
@FunctionalInterface
public interface Consumer<T> {
/**
* 执行消费操作
*
* @param value 元素值
* @param index 元素在集合中的索引
*/
void call(T value, int index);
}
/**
* 自定义二元消费者接口用于接收键值和索引
*
* @param <K> 键类型
* @param <V> 值类型
*/
@FunctionalInterface
public interface BiConsumer<K, V> {
/**
* 执行消费操作
*
* @param key
* @param value
* @param index 键值对在映射中的索引
*/
void call(K key, V value, int index);
}
}

View File

@ -0,0 +1,515 @@
/*
* 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 ForEach.java
* LastUpdate 2025-09-09 08:37:33
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.collection;
import com.mingliqiye.utils.functions.P1RFunction;
import com.mingliqiye.utils.functions.P2RFunction;
import com.mingliqiye.utils.functions.P3RFunction;
import java.util.*;
import java.util.Collection;
import java.util.concurrent.ConcurrentMap;
/**
* ForEachBreaked 工具类提供对集合和映射的增强遍历功能支持在遍历过程中中断操作
* 包含多个重载的 forEach 方法支持带索引的遍历操作并且可以在满足条件时提前终止遍历
* <br>
*
* <p>
* return null; // 提前下一次遍历 = continue;
* <p>
* return true; // 提前终止遍历 = break;
* <p>
* return false; // 继续下一次遍历
*
* @author MingLiPro
* @since 3.0.4
*/
public class ForEachBreaked {
/**
* 对给定的集合执行指定的操作操作包含元素值和索引
* 根据集合类型选择最优的遍历方式以提高性能
* 当操作返回 true 遍历将提前终止
*
* @param collection 要遍历的集合可以是 List 或其他 Collection 实现
* @param action 要对每个元素执行的操作接收元素值和索引作为参数返回 Boolean 值决定是否继续遍历
* @param <T> 集合中元素的类型
*/
public static <T> void forEach(Collection<T> collection, P2RFunction<? super T, Integer, Boolean> action) {
// 参数校验如果集合或操作为空则直接返回
if (collection == null || action == null) {
return;
}
// 如果集合实现了 RandomAccess 接口 ArrayList使用索引访问优化性能
if (collection instanceof RandomAccess && collection instanceof List) {
List<T> list = (List<T>) collection;
for (int i = 0; i < list.size(); i++) {
if (action.call(list.get(i), i)) return;
}
}
// 如果是普通 List使用迭代器遍历并手动维护索引
else if (collection instanceof List) {
int index = 0;
Iterator<T> it = collection.iterator();
while (it.hasNext()) {
if (action.call(it.next(), index)) return;
index++;
}
}
// 其他类型的集合使用增强 for 循环并手动维护索引
else {
int index = 0;
for (T element : collection) {
if (action.call(element, index)) return;
index++;
}
}
}
/**
* 对给定的集合执行指定的操作仅处理元素值
* 根据集合是否实现 RandomAccess 接口选择最优的遍历方式
* 当操作返回 true 遍历将提前终止
*
* @param collection 要遍历的集合
* @param action 要对每个元素执行的操作只接收元素值作为参数返回 Boolean 值决定是否继续遍历
* @param <T> 集合中元素的类型
*/
public static <T> void forEach(Collection<T> collection, P1RFunction<? super T, Boolean> action) {
// 参数校验如果集合或操作为空则直接返回
if (collection == null || action == null) {
return;
}
// 如果集合实现了 RandomAccess 接口使用索引访问提升性能
if (collection instanceof RandomAccess) {
List<T> list = (List<T>) collection;
for (int i = 0; i < list.size(); i++) {
if (action.call(list.get(i))) return;
}
}
// 否则使用增强 for 循环进行遍历
else {
for (T element : collection) {
if (action.call(element)) return;
}
}
}
/**
* 对给定的映射执行指定的操作操作包含键值和索引
* 根据映射类型选择不同的遍历策略
* 当操作返回 true 遍历将提前终止
*
* @param map 要遍历的映射
* @param action 要对每个键值对执行的操作接收键值和索引作为参数返回 Boolean 值决定是否继续遍历
* @param <K> 映射中键的类型
* @param <V> 映射中值的类型
*/
public static <K, V> void forEach(Map<K, V> map, P3RFunction<? super K, ? super V, Integer, Boolean> action) {
// 参数校验如果映射或操作为空则直接返回
if (map == null || action == null) {
return;
}
// 遍历 TreeMap 的条目集合并传递索引
if (map instanceof TreeMap) {
int index = 0;
for (Map.Entry<K, V> entry : map.entrySet()) {
if (action.call(entry.getKey(), entry.getValue(), index)) return;
index++;
}
}
// 遍历 ConcurrentMap LinkedHashMap 的条目集合并传递索引
else if (map instanceof ConcurrentMap || map instanceof LinkedHashMap) {
int index = 0;
for (Map.Entry<K, V> entry : map.entrySet()) {
if (action.call(entry.getKey(), entry.getValue(), index)) return;
index++;
}
}
// 遍历其他类型映射的条目集合并传递索引
else {
int index = 0;
for (Map.Entry<K, V> entry : map.entrySet()) {
if (action.call(entry.getKey(), entry.getValue(), index)) return;
index++;
}
}
}
/**
* 对给定的映射执行指定的操作仅处理键和值
* 根据映射类型选择不同的遍历策略
* 当操作返回 true 遍历将提前终止
*
* @param map 要遍历的映射
* @param action 要对每个键值对执行的操作接收键和值作为参数返回 Boolean 值决定是否继续遍历
* @param <K> 映射中键的类型
* @param <V> 映射中值的类型
*/
public static <K, V> void forEach(Map<K, V> map, P2RFunction<? super K, ? super V, Boolean> action) {
// 参数校验如果映射或操作为空则直接返回
if (map == null || action == null) {
return;
}
// 遍历 TreeMap 的条目集合
if (map instanceof TreeMap) {
for (Map.Entry<K, V> entry : map.entrySet()) {
if (action.call(entry.getKey(), entry.getValue())) return;
}
}
// 如果是 ConcurrentMap LinkedHashMap使用其内置的 forEach 方法
else if (map instanceof ConcurrentMap || map instanceof LinkedHashMap) {
forEach(map.entrySet(), (i) -> {
if (action.call(i.getKey(), i.getValue())) return true;
return false;
});
}
// 遍历其他类型映射的条目集合
else {
for (Map.Entry<K, V> entry : map.entrySet()) {
if (action.call(entry.getKey(), entry.getValue())) return;
}
}
}
/**
* 对可变参数数组执行指定的操作操作包含元素值和索引
* 当操作返回 true 遍历将提前终止
*
* @param action 要对每个元素执行的操作接收元素值和索引作为参数返回 Boolean 值决定是否继续遍历
* @param objects 要遍历的可变参数数组
* @param <T> 数组中元素的类型
*/
public static <T> void forEach(P2RFunction<? super T, Integer, Boolean> action, T... objects) {
forEach(Lists.newArrayList(objects), action);
}
/**
* 对数组执行指定的操作操作包含元素值和索引
* 当操作返回 true 遍历将提前终止
*
* @param objects 要遍历的数组
* @param action 要对每个元素执行的操作接收元素值和索引作为参数返回 Boolean 值决定是否继续遍历
* @param <T> 数组中元素的类型
*/
public static <T> void forEach(T[] objects, P2RFunction<? super T, Integer, Boolean> action) {
forEach(action, objects);
}
/**
* 对数组执行指定的操作仅处理元素值
* 当操作返回 true 遍历将提前终止
*
* @param objects 要遍历的数组
* @param action 要对每个元素执行的操作只接收元素值作为参数返回 Boolean 值决定是否继续遍历
* @param <T> 数组中元素的类型
*/
public static <T> void forEach(T[] objects, P1RFunction<? super T, Boolean> action) {
forEach(action, objects);
}
/**
* 对可变参数数组执行指定的操作仅处理元素值
* 当操作返回 true 遍历将提前终止
*
* @param action 要对每个元素执行的操作只接收元素值作为参数返回 Boolean 值决定是否继续遍历
* @param objects 要遍历的可变参数数组
* @param <T> 数组中元素的类型
*/
public static <T> void forEach(P1RFunction<? super T, Boolean> action, T... objects) {
forEach(Lists.toList(objects), (t, i) -> {
if (action.call(t)) return true;
return false;
});
}
/**
* 对整型数组执行指定的操作操作包含元素值和索引
* 当操作返回 true 遍历将提前终止
*
* @param objects 要遍历的整型数组
* @param action 要对每个元素执行的操作接收元素值和索引作为参数返回 Boolean 值决定是否继续遍历
*/
public static void forEach(int[] objects, P2RFunction<Integer, Integer, Boolean> action) {
forEach(action, objects);
}
/**
* 对整型可变参数数组执行指定的操作操作包含元素值和索引
* 当操作返回 true 遍历将提前终止
*
* @param action 要对每个元素执行的操作接收元素值和索引作为参数返回 Boolean 值决定是否继续遍历
* @param objects 要遍历的整型可变参数数组
*/
private static void forEach(P2RFunction<Integer, Integer, Boolean> action, int... objects) {
forEach(objects, action);
}
/**
* 对整型可变参数数组执行指定的操作仅处理元素值
* 当操作返回 true 遍历将提前终止
*
* @param action 要对每个元素执行的操作只接收元素值作为参数返回 Boolean 值决定是否继续遍历
* @param objects 要遍历的整型可变参数数组
*/
private static void forEach(P1RFunction<Integer, Boolean> action, int... objects) {
forEach(Lists.toList(objects), action);
}
/**
* 对字节数组执行指定的操作操作包含元素值和索引
* 当操作返回 true 遍历将提前终止
*
* @param objects 要遍历的字节数组
* @param action 要对每个元素执行的操作接收元素值和索引作为参数返回 Boolean 值决定是否继续遍历
*/
public static void forEach(byte[] objects, P2RFunction<Byte, Integer, Boolean> action) {
forEach(Lists.toList(objects), action);
}
/**
* 对字节可变参数数组执行指定的操作操作包含元素值和索引
* 当操作返回 true 遍历将提前终止
*
* @param action 要对每个元素执行的操作接收元素值和索引作为参数返回 Boolean 值决定是否继续遍历
* @param objects 要遍历的字节可变参数数组
*/
private static void forEach(P2RFunction<Byte, Integer, Boolean> action, byte... objects) {
forEach(objects, action);
}
/**
* 对字节可变参数数组执行指定的操作仅处理元素值
* 当操作返回 true 遍历将提前终止
*
* @param action 要对每个元素执行的操作只接收元素值作为参数返回 Boolean 值决定是否继续遍历
* @param objects 要遍历的字节可变参数数组
*/
private static void forEach(P1RFunction<Byte, Boolean> action, byte... objects) {
forEach(Lists.toList(objects), action);
}
/**
* 对短整型数组执行指定的操作操作包含元素值和索引
* 当操作返回 true 遍历将提前终止
*
* @param objects 要遍历的短整型数组
* @param action 要对每个元素执行的操作接收元素值和索引作为参数返回 Boolean 值决定是否继续遍历
*/
public static void forEach(short[] objects, P2RFunction<Short, Integer, Boolean> action) {
forEach(Lists.toList(objects), action);
}
/**
* 对短整型可变参数数组执行指定的操作操作包含元素值和索引
* 当操作返回 true 遍历将提前终止
*
* @param action 要对每个元素执行的操作接收元素值和索引作为参数返回 Boolean 值决定是否继续遍历
* @param objects 要遍历的短整型可变参数数组
*/
private static void forEach(P2RFunction<Short, Integer, Boolean> action, short... objects) {
forEach(objects, action);
}
/**
* 对短整型可变参数数组执行指定的操作仅处理元素值
* 当操作返回 true 遍历将提前终止
*
* @param action 要对每个元素执行的操作只接收元素值作为参数返回 Boolean 值决定是否继续遍历
* @param objects 要遍历的短整型可变参数数组
*/
private static void forEach(P1RFunction<Short, Boolean> action, short... objects) {
forEach(Lists.toList(objects), action);
}
/**
* 对长整型数组执行指定的操作操作包含元素值和索引
* 当操作返回 true 遍历将提前终止
*
* @param objects 要遍历的长整型数组
* @param action 要对每个元素执行的操作接收元素值和索引作为参数返回 Boolean 值决定是否继续遍历
*/
public static void forEach(long[] objects, P2RFunction<Long, Integer, Boolean> action) {
forEach(action, objects);
}
/**
* 对长整型可变参数数组执行指定的操作操作包含元素值和索引
* 当操作返回 true 遍历将提前终止
*
* @param action 要对每个元素执行的操作接收元素值和索引作为参数返回 Boolean 值决定是否继续遍历
* @param objects 要遍历的长整型可变参数数组
*/
private static void forEach(P2RFunction<Long, Integer, Boolean> action, long... objects) {
forEach(Lists.toList(objects), action);
}
/**
* 对长整型可变参数数组执行指定的操作仅处理元素值
* 当操作返回 true 遍历将提前终止
*
* @param action 要对每个元素执行的操作只接收元素值作为参数返回 Boolean 值决定是否继续遍历
* @param objects 要遍历的长整型可变参数数组
*/
private static void forEach(P1RFunction<Long, Boolean> action, long... objects) {
forEach(Lists.toList(objects), action);
}
/**
* 对浮点数组执行指定的操作操作包含元素值和索引
* 当操作返回 true 遍历将提前终止
*
* @param objects 要遍历的浮点数组
* @param action 要对每个元素执行的操作接收元素值和索引作为参数返回 Boolean 值决定是否继续遍历
*/
public static void forEach(float[] objects, P2RFunction<Float, Integer, Boolean> action) {
forEach(action, objects);
}
/**
* 对浮点可变参数数组执行指定的操作操作包含元素值和索引
* 当操作返回 true 遍历将提前终止
*
* @param action 要对每个元素执行的操作接收元素值和索引作为参数返回 Boolean 值决定是否继续遍历
* @param objects 要遍历的浮点可变参数数组
*/
private static void forEach(P2RFunction<Float, Integer, Boolean> action, float... objects) {
forEach(Lists.toList(objects), action);
}
/**
* 对浮点可变参数数组执行指定的操作仅处理元素值
* 当操作返回 true 遍历将提前终止
*
* @param action 要对每个元素执行的操作只接收元素值作为参数返回 Boolean 值决定是否继续遍历
* @param objects 要遍历的浮点可变参数数组
*/
private static void forEach(P1RFunction<Float, Boolean> action, float... objects) {
forEach(Lists.toList(objects), action);
}
/**
* 对双精度浮点数组执行指定的操作操作包含元素值和索引
* 当操作返回 true 遍历将提前终止
*
* @param objects 要遍历的双精度浮点数组
* @param action 要对每个元素执行的操作接收元素值和索引作为参数返回 Boolean 值决定是否继续遍历
*/
public static void forEach(double[] objects, P2RFunction<Double, Integer, Boolean> action) {
forEach(action, objects);
}
/**
* 对双精度浮点可变参数数组执行指定的操作操作包含元素值和索引
* 当操作返回 true 遍历将提前终止
*
* @param action 要对每个元素执行的操作接收元素值和索引作为参数返回 Boolean 值决定是否继续遍历
* @param objects 要遍历的双精度浮点可变参数数组
*/
private static void forEach(P2RFunction<Double, Integer, Boolean> action, double... objects) {
forEach(Lists.toList(objects), action);
}
/**
* 对双精度浮点可变参数数组执行指定的操作仅处理元素值
* 当操作返回 true 遍历将提前终止
*
* @param action 要对每个元素执行的操作只接收元素值作为参数返回 Boolean 值决定是否继续遍历
* @param objects 要遍历的双精度浮点可变参数数组
*/
private static void forEach(P1RFunction<Double, Boolean> action, double... objects) {
forEach(Lists.toList(objects), action);
}
/**
* 对字符数组执行指定的操作操作包含元素值和索引
* 当操作返回 true 遍历将提前终止
*
* @param objects 要遍历的字符数组
* @param action 要对每个元素执行的操作接收元素值和索引作为参数返回 Boolean 值决定是否继续遍历
*/
public static void forEach(char[] objects, P2RFunction<Character, Integer, Boolean> action) {
forEach(action, objects);
}
/**
* 对字符可变参数数组执行指定的操作操作包含元素值和索引
* 当操作返回 true 遍历将提前终止
*
* @param action 要对每个元素执行的操作接收元素值和索引作为参数返回 Boolean 值决定是否继续遍历
* @param objects 要遍历的字符可变参数数组
*/
private static void forEach(P2RFunction<Character, Integer, Boolean> action, char... objects) {
forEach(Lists.toList(objects), action);
}
/**
* 对字符可变参数数组执行指定的操作仅处理元素值
* 当操作返回 true 遍历将提前终止
*
* @param action 要对每个元素执行的操作只接收元素值作为参数返回 Boolean 值决定是否继续遍历
* @param objects 要遍历的字符可变参数数组
*/
private static void forEach(P1RFunction<Character, Boolean> action, char... objects) {
forEach(Lists.toList(objects), action);
}
/**
* 对布尔数组执行指定的操作操作包含元素值和索引
* 当操作返回 true 遍历将提前终止
*
* @param objects 要遍历的布尔数组
* @param action 要对每个元素执行的操作接收元素值和索引作为参数返回 Boolean 值决定是否继续遍历
*/
public static void forEach(boolean[] objects, P2RFunction<Character, Integer, Boolean> action) {
forEach(objects, action);
}
/**
* 对布尔可变参数数组执行指定的操作操作包含元素值和索引
* 当操作返回 true 遍历将提前终止
*
* @param action 要对每个元素执行的操作接收元素值和索引作为参数返回 Boolean 值决定是否继续遍历
* @param objects 要遍历的布尔可变参数数组
*/
private static void forEach(P2RFunction<Boolean, Integer, Boolean> action, boolean... objects) {
forEach(Lists.toList(objects), action);
}
/**
* 对布尔可变参数数组执行指定的操作仅处理元素值
* 当操作返回 true 遍历将提前终止
*
* @param action 要对每个元素执行的操作只接收元素值作为参数返回 Boolean 值决定是否继续遍历
* @param objects 要遍历的布尔可变参数数组
*/
private static void forEach(P1RFunction<Boolean, Boolean> action, boolean... objects) {
forEach(Lists.toList(objects), action);
}
}

View File

@ -20,7 +20,7 @@
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.callback;
package com.mingliqiye.utils.functions;
@FunctionalInterface
public interface P10Function<P, P1, P2, P3, P4, P5, P6, P7, P8, P9> {

View File

@ -20,7 +20,7 @@
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.callback;
package com.mingliqiye.utils.functions;
@FunctionalInterface
public interface P10RFunction<P, P1, P2, P3, P4, P5, P6, P7, P8, P9, R> {

View File

@ -20,7 +20,7 @@
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.callback;
package com.mingliqiye.utils.functions;
@FunctionalInterface
public interface P1Function<P> {

View File

@ -20,7 +20,7 @@
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.callback;
package com.mingliqiye.utils.functions;
@FunctionalInterface
public interface P1RFunction<P, R> {

View File

@ -20,7 +20,7 @@
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.callback;
package com.mingliqiye.utils.functions;
@FunctionalInterface
public interface P2Function<P, P1> {

View File

@ -20,7 +20,7 @@
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.callback;
package com.mingliqiye.utils.functions;
@FunctionalInterface
public interface P2RFunction<P, P1, R> {

View File

@ -20,7 +20,7 @@
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.callback;
package com.mingliqiye.utils.functions;
@FunctionalInterface
public interface P3Function<P, P1, P2> {

View File

@ -20,7 +20,7 @@
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.callback;
package com.mingliqiye.utils.functions;
@FunctionalInterface
public interface P3RFunction<P, P1, P2, R> {

View File

@ -20,7 +20,7 @@
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.callback;
package com.mingliqiye.utils.functions;
@FunctionalInterface
public interface P4Function<P, P1, P2, P3> {

View File

@ -20,7 +20,7 @@
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.callback;
package com.mingliqiye.utils.functions;
@FunctionalInterface
public interface P4RFunction<P, P1, P2, P3, R> {

View File

@ -20,7 +20,7 @@
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.callback;
package com.mingliqiye.utils.functions;
@FunctionalInterface
public interface P5Function<P, P1, P2, P3, P4> {

View File

@ -20,7 +20,7 @@
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.callback;
package com.mingliqiye.utils.functions;
@FunctionalInterface
public interface P5RFunction<P, P1, P2, P3, P4, R> {

View File

@ -20,7 +20,7 @@
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.callback;
package com.mingliqiye.utils.functions;
@FunctionalInterface
public interface P6Function<P, P1, P2, P3, P4, P5> {

View File

@ -20,7 +20,7 @@
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.callback;
package com.mingliqiye.utils.functions;
@FunctionalInterface
public interface P6RFunction<P, P1, P2, P3, P4, P5, R> {

View File

@ -20,7 +20,7 @@
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.callback;
package com.mingliqiye.utils.functions;
@FunctionalInterface
public interface P7Function<P, P1, P2, P3, P4, P5, P6> {

View File

@ -20,7 +20,7 @@
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.callback;
package com.mingliqiye.utils.functions;
@FunctionalInterface
public interface P7RFunction<P, P1, P2, P3, P4, P5, P6, R> {

View File

@ -20,7 +20,7 @@
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.callback;
package com.mingliqiye.utils.functions;
@FunctionalInterface
public interface P8Function<P, P1, P2, P3, P4, P5, P6, P7> {

View File

@ -20,7 +20,7 @@
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.callback;
package com.mingliqiye.utils.functions;
@FunctionalInterface
public interface P8RFunction<P, P1, P2, P3, P4, P5, P6, P7, R> {

View File

@ -20,7 +20,7 @@
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.callback;
package com.mingliqiye.utils.functions;
@FunctionalInterface
public interface P9Function<P, P1, P2, P3, P4, P5, P6, P7, P8> {

View File

@ -20,7 +20,7 @@
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.callback;
package com.mingliqiye.utils.functions;
@FunctionalInterface
public interface P9RFunction<P, P1, P2, P3, P4, P5, P6, P7, P8, R> {

View File

@ -22,7 +22,7 @@
package com.mingliqiye.utils.string;
import com.mingliqiye.utils.callback.P1RFunction;
import com.mingliqiye.utils.functions.P1RFunction;
import com.mingliqiye.utils.collection.Lists;
import java.text.MessageFormat;
import java.util.ArrayList;