/*
* 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.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 方法,支持带索引的遍历操作。
*
* 不可终止的遍历 可以使用 ForEachBreaked 类
*
* @since 3.0.4
*
* @see com.mingliqiye.utils.collection.ForEachBreaked
* @author MingLiPro
*/
public class ForEach {
/**
* 对给定的集合执行指定的操作,操作包含元素值和索引。
* 根据集合类型选择最优的遍历方式以提高性能。
*
* @param collection 要遍历的集合,可以是 List 或其他 Collection 实现
* @param action 要对每个元素执行的操作,接收元素值和索引作为参数
* @param 集合中元素的类型
*/
public static void forEach(
Collection collection,
P2Function super T, Integer> 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,
P1Function super T> 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.call(list.get(i));
}
}
// 否则使用增强 for 循环进行遍历
else {
for (T element : collection) {
action.call(element);
}
}
}
/**
* 对给定的映射执行指定的操作,操作包含键、值和索引。
* 根据映射类型选择不同的遍历策略。
*
* @param map 要遍历的映射
* @param action 要对每个键值对执行的操作,接收键、值和索引作为参数
* @param 映射中键的类型
* @param 映射中值的类型
*/
public static void forEach(
Map 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 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,
P2Function super K, ? super V> action
) {
// 参数校验:如果映射或操作为空,则直接返回
if (map == null || action == null) {
return;
}
// 遍历 TreeMap 的条目集合
if (map instanceof TreeMap) {
for (Map.Entry 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 entry : map.entrySet()) {
action.call(entry.getKey(), entry.getValue());
}
}
}
/**
* 对可变参数数组执行指定的操作,操作包含元素值和索引
*
* @param action 要对每个元素执行的操作,接收元素值和索引作为参数
* @param objects 要遍历的可变参数数组
* @param 数组中元素的类型
*/
public static void forEach(
P2Function super T, Integer> action,
T... objects
) {
forEach(Lists.newArrayList(objects), action);
}
/**
* 对数组执行指定的操作,操作包含元素值和索引
*
* @param objects 要遍历的数组
* @param action 要对每个元素执行的操作,接收元素值和索引作为参数
* @param 数组中元素的类型
*/
public static void forEach(
T[] objects,
P2Function super T, Integer> action
) {
forEach(action, objects);
}
/**
* 对数组执行指定的操作,仅处理元素值
*
* @param objects 要遍历的数组
* @param action 要对每个元素执行的操作,只接收元素值作为参数
* @param 数组中元素的类型
*/
public static void forEach(T[] objects, P1Function super T> action) {
forEach(action, objects);
}
/**
* 对可变参数数组执行指定的操作,仅处理元素值
*
* @param action 要对每个元素执行的操作,只接收元素值作为参数
* @param objects 要遍历的可变参数数组
* @param 数组中元素的类型
*/
public static void forEach(P1Function super T> action, T... objects) {
forEach(Lists.toList(objects), (t, i) -> action.call(t));
}
/**
* 对整型数组执行指定的操作,操作包含元素值和索引
*
* @param objects 要遍历的整型数组
* @param action 要对每个元素执行的操作,接收元素值和索引作为参数
*/
public static void forEach(
int[] objects,
P2Function action
) {
forEach(action, objects);
}
/**
* 对整型可变参数数组执行指定的操作,操作包含元素值和索引
*
* @param action 要对每个元素执行的操作,接收元素值和索引作为参数
* @param objects 要遍历的整型可变参数数组
*/
private static void forEach(
P2Function action,
int... objects
) {
forEach(objects, action);
}
/**
* 对整型可变参数数组执行指定的操作,仅处理元素值
*
* @param action 要对每个元素执行的操作,只接收元素值作为参数
* @param objects 要遍历的整型可变参数数组
*/
private static void forEach(P1Function action, int... objects) {
forEach(Lists.toList(objects), action);
}
/**
* 对字节数组执行指定的操作,操作包含元素值和索引
*
* @param objects 要遍历的字节数组
* @param action 要对每个元素执行的操作,接收元素值和索引作为参数
*/
public static void forEach(
byte[] objects,
P2Function action
) {
forEach(Lists.toList(objects), action);
}
/**
* 对字节可变参数数组执行指定的操作,操作包含元素值和索引
*
* @param action 要对每个元素执行的操作,接收元素值和索引作为参数
* @param objects 要遍历的字节可变参数数组
*/
private static void forEach(
P2Function action,
byte... objects
) {
forEach(objects, action);
}
/**
* 对字节可变参数数组执行指定的操作,仅处理元素值
*
* @param action 要对每个元素执行的操作,只接收元素值作为参数
* @param objects 要遍历的字节可变参数数组
*/
private static void forEach(P1Function action, byte... objects) {
forEach(Lists.toList(objects), action);
}
/**
* 对短整型数组执行指定的操作,操作包含元素值和索引
*
* @param objects 要遍历的短整型数组
* @param action 要对每个元素执行的操作,接收元素值和索引作为参数
*/
public static void forEach(
short[] objects,
P2Function action
) {
forEach(Lists.toList(objects), action);
}
/**
* 对短整型可变参数数组执行指定的操作,操作包含元素值和索引
*
* @param action 要对每个元素执行的操作,接收元素值和索引作为参数
* @param objects 要遍历的短整型可变参数数组
*/
private static void forEach(
P2Function action,
short... objects
) {
forEach(objects, action);
}
/**
* 对短整型可变参数数组执行指定的操作,仅处理元素值
*
* @param action 要对每个元素执行的操作,只接收元素值作为参数
* @param objects 要遍历的短整型可变参数数组
*/
private static void forEach(P1Function action, short... objects) {
forEach(Lists.toList(objects), action);
}
/**
* 对长整型数组执行指定的操作,操作包含元素值和索引
*
* @param objects 要遍历的长整型数组
* @param action 要对每个元素执行的操作,接收元素值和索引作为参数
*/
public static void forEach(
long[] objects,
P2Function action
) {
forEach(action, objects);
}
/**
* 对长整型可变参数数组执行指定的操作,操作包含元素值和索引
*
* @param action 要对每个元素执行的操作,接收元素值和索引作为参数
* @param objects 要遍历的长整型可变参数数组
*/
private static void forEach(
P2Function action,
long... objects
) {
forEach(Lists.toList(objects), action);
}
/**
* 对长整型可变参数数组执行指定的操作,仅处理元素值
*
* @param action 要对每个元素执行的操作,只接收元素值作为参数
* @param objects 要遍历的长整型可变参数数组
*/
private static void forEach(P1Function action, long... objects) {
forEach(Lists.toList(objects), action);
}
/**
* 对浮点数组执行指定的操作,操作包含元素值和索引
*
* @param objects 要遍历的浮点数组
* @param action 要对每个元素执行的操作,接收元素值和索引作为参数
*/
public static void forEach(
float[] objects,
P2Function action
) {
forEach(action, objects);
}
/**
* 对浮点可变参数数组执行指定的操作,操作包含元素值和索引
*
* @param action 要对每个元素执行的操作,接收元素值和索引作为参数
* @param objects 要遍历的浮点可变参数数组
*/
private static void forEach(
P2Function action,
float... objects
) {
forEach(Lists.toList(objects), action);
}
/**
* 对浮点可变参数数组执行指定的操作,仅处理元素值
*
* @param action 要对每个元素执行的操作,只接收元素值作为参数
* @param objects 要遍历的浮点可变参数数组
*/
private static void forEach(P1Function action, float... objects) {
forEach(Lists.toList(objects), action);
}
/**
* 对双精度浮点数组执行指定的操作,操作包含元素值和索引
*
* @param objects 要遍历的双精度浮点数组
* @param action 要对每个元素执行的操作,接收元素值和索引作为参数
*/
public static void forEach(
double[] objects,
P2Function action
) {
forEach(action, objects);
}
/**
* 对双精度浮点可变参数数组执行指定的操作,操作包含元素值和索引
*
* @param action 要对每个元素执行的操作,接收元素值和索引作为参数
* @param objects 要遍历的双精度浮点可变参数数组
*/
private static void forEach(
P2Function action,
double... objects
) {
forEach(Lists.toList(objects), action);
}
/**
* 对双精度浮点可变参数数组执行指定的操作,仅处理元素值
*
* @param action 要对每个元素执行的操作,只接收元素值作为参数
* @param objects 要遍历的双精度浮点可变参数数组
*/
private static void forEach(P1Function action, double... objects) {
forEach(Lists.toList(objects), action);
}
/**
* 对字符数组执行指定的操作,操作包含元素值和索引
*
* @param objects 要遍历的字符数组
* @param action 要对每个元素执行的操作,接收元素值和索引作为参数
*/
public static void forEach(
char[] objects,
P2Function action
) {
forEach(action, objects);
}
/**
* 对字符可变参数数组执行指定的操作,操作包含元素值和索引
*
* @param action 要对每个元素执行的操作,接收元素值和索引作为参数
* @param objects 要遍历的字符可变参数数组
*/
private static void forEach(
P2Function action,
char... objects
) {
forEach(Lists.toList(objects), action);
}
/**
* 对字符可变参数数组执行指定的操作,仅处理元素值
*
* @param action 要对每个元素执行的操作,只接收元素值作为参数
* @param objects 要遍历的字符可变参数数组
*/
private static void forEach(P1Function action, char... objects) {
forEach(Lists.toList(objects), action);
}
/**
* 对布尔数组执行指定的操作,操作包含元素值和索引
*
* @param objects 要遍历的布尔数组
* @param action 要对每个元素执行的操作,接收元素值和索引作为参数
*/
public static void forEach(
boolean[] objects,
P2Function action
) {
forEach(objects, action);
}
/**
* 对布尔可变参数数组执行指定的操作,操作包含元素值和索引
*
* @param action 要对每个元素执行的操作,接收元素值和索引作为参数
* @param objects 要遍历的布尔可变参数数组
*/
private static void forEach(
P2Function action,
boolean... objects
) {
forEach(Lists.toList(objects), action);
}
/**
* 对布尔可变参数数组执行指定的操作,仅处理元素值
*
* @param action 要对每个元素执行的操作,只接收元素值作为参数
* @param objects 要遍历的布尔可变参数数组
*/
private static void forEach(
P1Function action,
boolean... objects
) {
forEach(Lists.toList(objects), action);
}
}