generator) {
- return IterableElementsWrapper.super.toArray(generator);
- }
-}
\ No newline at end of file
diff --git a/core/src/main/java/run/soeasy/framework/core/collection/factory/CollectionFactory.java b/core/src/main/java/run/soeasy/framework/core/collection/CollectionFactory.java
similarity index 98%
rename from core/src/main/java/run/soeasy/framework/core/collection/factory/CollectionFactory.java
rename to core/src/main/java/run/soeasy/framework/core/collection/CollectionFactory.java
index f9d7bf041..daf648cc6 100644
--- a/core/src/main/java/run/soeasy/framework/core/collection/factory/CollectionFactory.java
+++ b/core/src/main/java/run/soeasy/framework/core/collection/CollectionFactory.java
@@ -1,4 +1,4 @@
-package run.soeasy.framework.core.collection.factory;
+package run.soeasy.framework.core.collection;
import java.util.Collection;
import java.util.Collections;
diff --git a/core/src/main/java/run/soeasy/framework/core/collection/CollectionRegistry.java b/core/src/main/java/run/soeasy/framework/core/collection/CollectionRegistry.java
new file mode 100644
index 000000000..a9e7f6438
--- /dev/null
+++ b/core/src/main/java/run/soeasy/framework/core/collection/CollectionRegistry.java
@@ -0,0 +1,118 @@
+package run.soeasy.framework.core.collection;
+
+import java.util.Collection;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
+
+import run.soeasy.framework.core.exchange.Operation;
+import run.soeasy.framework.core.exchange.Registry;
+
+/**
+ * 集合型注册中心接口(集成Collection与Registry能力)
+ * 核心能力:
+ * 1. 基于Collection的增删能力实现注册/注销语义,支持操作回滚;
+ * 2. 重置操作清空整个集合,返回标准化Operation结果;
+ * 3. 所有操作结果适配Operation接口规范(成功/失败/回滚)。
+ *
+ * @author soeasy.run
+ * @param 注册元素类型
+ */
+public interface CollectionRegistry extends Collection, Registry {
+
+ /**
+ * 注册元素(添加到集合),支持回滚(回滚逻辑:移除该元素)
+ * @param element 待注册元素(非null)
+ * @return Operation 操作结果:
+ * - 成功:元素添加成功,支持回滚(移除元素);
+ * - 失败:元素为null/添加失败/抛出异常(含失败原因)。
+ */
+ @Override
+ default Operation register(E element) {
+ // 空值校验:封装为异常传给failure
+ if (element == null) {
+ return Operation.failure(new RuntimeException("Register failed: element is null"));
+ }
+ try {
+ // 复用Collection的add方法实现注册
+ boolean added = add(element);
+ if (added) {
+ // 注册成功:添加回滚逻辑(移除当前元素)
+ return Operation.success(() -> deregister(element).isSuccess());
+ } else {
+ // 添加失败:封装失败原因
+ return Operation.failure(new RuntimeException(
+ "Register failed: element already exists or add rejected, element=" + element));
+ }
+ } catch (Exception e) {
+ // 捕获运行时异常(如UnsupportedOperationException、ClassCastException等)
+ return Operation.failure(e);
+ }
+ }
+
+ /**
+ * 注销元素(从集合移除),支持回滚(回滚逻辑:重新添加该元素)
+ * @param element 待注销元素(非null)
+ * @return Operation 操作结果:
+ * - 成功:元素移除成功,支持回滚(重新添加);
+ * - 失败:元素为null/元素不存在/移除失败/抛出异常(含失败原因)。
+ */
+ @Override
+ default Operation deregister(E element) {
+ // 空值校验:封装为异常传给failure
+ if (element == null) {
+ return Operation.failure(new RuntimeException("Deregister failed: element is null"));
+ }
+ try {
+ // 复用Collection的remove方法实现注销
+ boolean removed = remove(element);
+ if (removed) {
+ // 注销成功:添加回滚逻辑(重新添加当前元素)
+ return Operation.success(() -> register(element).isSuccess());
+ } else {
+ // 移除失败:封装失败原因
+ return Operation.failure(new RuntimeException(
+ "Deregister failed: element not found or remove rejected, element=" + element));
+ }
+ } catch (Exception e) {
+ // 捕获运行时异常
+ return Operation.failure(e);
+ }
+ }
+
+ /**
+ * 重置注册中心(清空所有元素),无回滚逻辑
+ * @return Operation 操作结果:
+ * - 成功:集合清空完成;
+ * - 失败:清空操作抛出异常(含失败原因)。
+ */
+ @Override
+ default Operation reset() {
+ try {
+ // 复用Collection的clear方法实现重置
+ clear();
+ return Operation.success(); // 无回滚的成功操作
+ } catch (Exception e) {
+ // 捕获清空时的异常(如UnsupportedOperationException)
+ return Operation.failure(e);
+ }
+ }
+
+ @Override
+ boolean isEmpty();
+
+ @Override
+ boolean contains(Object o);
+
+ @Override
+ default void forEach(Consumer super E> action) {
+ Collection.super.forEach(action);
+ }
+
+ @Override
+ default Stream stream() {
+ return Collection.super.stream();
+ }
+
+ @Override
+ Object[] toArray();
+}
\ No newline at end of file
diff --git a/core/src/main/java/run/soeasy/framework/core/collection/CollectionUtils.java b/core/src/main/java/run/soeasy/framework/core/collection/CollectionUtils.java
index 910fb702c..3f88f0468 100644
--- a/core/src/main/java/run/soeasy/framework/core/collection/CollectionUtils.java
+++ b/core/src/main/java/run/soeasy/framework/core/collection/CollectionUtils.java
@@ -14,7 +14,6 @@
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
-import java.util.ListIterator;
import java.util.Map;
import java.util.NavigableMap;
import java.util.NavigableSet;
@@ -27,8 +26,6 @@
import java.util.TreeSet;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
-import java.util.function.Function;
-import java.util.function.Predicate;
import java.util.function.ToIntFunction;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -39,142 +36,89 @@
import run.soeasy.framework.core.Assert;
import run.soeasy.framework.core.ObjectUtils;
import run.soeasy.framework.core.function.ThrowingConsumer;
+import run.soeasy.framework.core.streaming.Streamable;
import run.soeasy.framework.core.type.ReflectionUtils;
/**
- * 集合工具类 提供集合操作的各种实用方法,包括比较、过滤、转换、合并等功能
+ * 集合工具类
+ *
+ * 提供集合比较、运算、转换、创建、遍历等一站式实用方法,覆盖有序/无序集合操作、枚举集合元信息处理等场景。
*
* @author soeasy.run
*/
@UtilityClass
public class CollectionUtils {
- private static final class PreviousIterator implements Iterator {
- private final ListIterator listIterator;
-
- public PreviousIterator(ListIterator listIterator) {
- this.listIterator = listIterator;
- }
-
- public boolean hasNext() {
- return listIterator.hasPrevious();
- }
-
- public E next() {
- return listIterator.previous();
- }
-
- @Override
- public void remove() {
- listIterator.remove();
- }
- }
-
- @SuppressWarnings({ "rawtypes" })
- private static final MultiValueMap EMPTY_MULTI_VALUE_MAP = new DefaultMultiValueMap<>(Collections.emptyMap());
- private static final Field KEY_TYPE_FIELD = ReflectionUtils.findDeclaredField(EnumMap.class, "keyType").first();
private static final Field ELEMENT_TYPE_FIELD = ReflectionUtils.findDeclaredField(EnumSet.class, "elementType")
.first();
+ private static final Field KEY_TYPE_FIELD = ReflectionUtils.findDeclaredField(EnumMap.class, "keyType").first();
static {
ReflectionUtils.makeAccessible(KEY_TYPE_FIELD);
ReflectionUtils.makeAccessible(ELEMENT_TYPE_FIELD);
}
/**
- * 获取EnumMap的键类型
- *
- * @param 键类型
- * @param map EnumMap实例
- * @return 键的Class对象,非EnumMap返回null
- */
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public static Class getEnumMapKeyType(Map map) {
- Class keyType = null;
- if (map instanceof EnumMap) {
- keyType = (Class) ReflectionUtils.get(KEY_TYPE_FIELD, map);
- }
- return keyType;
- }
-
- /**
- * 获取EnumSet的元素类型
+ * 对可迭代对象中所有元素执行带异常处理的消费操作
+ *
+ * 递归遍历所有元素,确保每个元素都被消费,异常可正常抛出。
*
- * @param 元素类型
- * @param collection EnumSet实例
- * @return 元素的Class对象,非EnumSet返回null
+ * @param 元素类型
+ * @param 消费操作可能抛出的异常类型
+ * @param iterable 可迭代对象,不可为null
+ * @param consumer 消费函数,不可为null
+ * @throws E 消费过程中抛出的异常
*/
- @SuppressWarnings("unchecked")
- public static Class getEnumSetElementType(@SuppressWarnings("rawtypes") Collection collection) {
- Class elementType = null;
- if (collection instanceof EnumSet) {
- elementType = (Class) ReflectionUtils.get(ELEMENT_TYPE_FIELD, collection);
- }
- return elementType;
+ public static void acceptAll(@NonNull Iterable extends T> iterable,
+ @NonNull ThrowingConsumer super T, ? extends E> consumer) throws E {
+ acceptAll(iterable.iterator(), consumer);
}
/**
- * 比较两个集合的元素顺序
+ * 对迭代器中所有元素执行带异常处理的消费操作
+ *
+ * 递归遍历所有元素,确保每个元素都被消费,异常可正常抛出。
*
- * @param 元素类型
- * @param collection1 第一个集合
- * @param collection2 第二个集合
- * @param comparator 元素比较器
- * @return 比较结果:负数-前者小,0-相等,正数-前者大
+ * @param 元素类型
+ * @param 消费操作可能抛出的异常类型
+ * @param iterator 迭代器,不可为null
+ * @param consumer 消费函数,不可为null
+ * @throws E 消费过程中抛出的异常
*/
- public static int compare(Collection extends T> collection1, Collection extends T> collection2,
- Comparator comparator) {
- if (isEmpty(collection1)) {
- return isEmpty(collection2) ? 0 : -1;
- }
-
- if (isEmpty(collection2)) {
- return isEmpty(collection1) ? 0 : 1;
- }
-
- Iterator extends T> iterator1 = collection1.iterator();
- Iterator extends T> iterator2 = collection2.iterator();
- while (iterator1.hasNext() && iterator2.hasNext()) {
- int v = comparator.compare(iterator1.next(), iterator2.next());
- if (v != 0) {
- return v;
+ public static void acceptAll(@NonNull Iterator extends T> iterator,
+ @NonNull ThrowingConsumer super T, ? extends E> consumer) throws E {
+ if (iterator.hasNext()) {
+ try {
+ consumer.accept(iterator.next());
+ } finally {
+ acceptAll(iterator, consumer);
}
}
- return collection1.size() - collection2.size();
}
/**
- * 比较两个迭代器的元素顺序
+ * 将类转换为枚举类型
+ *
+ * 校验类是否为枚举类型,非枚举类型抛出IllegalArgumentException。
*
- * @param 元素类型
- * @param iterator1 第一个迭代器
- * @param iterator2 第二个迭代器
- * @param comparator 元素比较器
- * @return 比较结果:负数-前者小,0-相等,正数-前者大
+ * @param enumType 待转换的类
+ * @return 枚举类型Class对象
+ * @throws IllegalArgumentException 输入类不是枚举类型时抛出
*/
- public static int compare(Iterator extends T> iterator1, Iterator extends T> iterator2,
- Comparator comparator) {
- if (isEmpty(iterator1)) {
- return isEmpty(iterator2) ? 0 : -1;
- }
-
- if (isEmpty(iterator2)) {
- return isEmpty(iterator1) ? 0 : 1;
- }
-
- while (iterator1.hasNext() && iterator2.hasNext()) {
- int v = comparator.compare(iterator1.next(), iterator2.next());
- if (v != 0) {
- return v;
- }
+ @SuppressWarnings("rawtypes")
+ private static Class extends Enum> asEnumType(@NonNull Class> enumType) {
+ if (!Enum.class.isAssignableFrom(enumType)) {
+ throw new IllegalArgumentException("Supplied type is not an enum: " + enumType.getName());
}
- return iterator1.hasNext() ? 1 : (iterator2.hasNext() ? -1 : 0);
+ return enumType.asSubclass(Enum.class);
}
/**
- * 计算两个可迭代对象的补集(全集-子集)
+ * 计算两个可迭代对象的补集(全集 - 子集)
+ *
+ * 默认使用ObjectUtils.equals判断元素相等,全集为Set时返回LinkedHashSet,否则返回ArrayList。
*
* @param 元素类型
- * @param universal 全集
- * @param subaggregate 子集
+ * @param universal 全集,可为null(返回空列表)
+ * @param subaggregate 子集,可为null(返回全集拷贝)
* @return 补集元素集合
*/
public static Collection complementary(Iterable extends E> universal, Iterable extends E> subaggregate) {
@@ -196,12 +140,12 @@ public static Collection complementary(Iterable extends E> universal, I
}
/**
- * 计算两个可迭代对象的补集(全集-子集),使用自定义比较器
+ * 计算两个可迭代对象的补集(全集 - 子集),支持自定义元素比较器
*
* @param 元素类型
- * @param universal 全集
- * @param subaggregate 子集
- * @param comparator 元素比较器
+ * @param universal 全集,可为null(返回空列表)
+ * @param subaggregate 子集,可为null(返回全集拷贝)
+ * @param comparator 元素比较器,用于判断元素相等
* @return 补集元素集合
*/
public static Collection complementary(Iterable extends E> universal, Iterable extends E> subaggregate,
@@ -215,11 +159,13 @@ public static Collection complementary(Iterable extends E> universal, I
}
/**
- * 计算两个迭代器的补集(全集-子集)
+ * 计算两个迭代器的补集(全集 - 子集)
+ *
+ * 默认使用ObjectUtils.equals判断元素相等。
*
* @param 元素类型
- * @param universal 全集迭代器
- * @param subaggregate 子集迭代器
+ * @param universal 全集迭代器,可为null(返回空列表)
+ * @param subaggregate 子集迭代器,可为null(返回全集拷贝)
* @return 补集元素集合
*/
public static Collection complementary(Iterator extends E> universal, Iterator extends E> subaggregate) {
@@ -227,11 +173,11 @@ public static Collection complementary(Iterator extends E> universal, I
}
/**
- * 计算两个迭代器的补集(全集-子集),使用自定义比较器
+ * 计算两个迭代器的补集(全集 - 子集),支持自定义元素比较器
*
* @param 元素类型
- * @param universal 全集迭代器
- * @param subaggregate 子集迭代器
+ * @param universal 全集迭代器,可为null(返回空列表)
+ * @param subaggregate 子集迭代器,可为null(返回全集拷贝)
* @param comparator 元素比较器,不可为null
* @return 补集元素列表
*/
@@ -263,42 +209,191 @@ public static List complementary(Iterator extends E> universal, Iterato
}
/**
- * 检查源集合是否包含任意候选元素
+ * 创建与原集合类型最相似的空集合
+ *
+ * 适配规则:
+ *
+ * - LinkedList → 新LinkedList
+ * - List(非LinkedList)→ 新ArrayList
+ * - EnumSet → 清空后的同类型EnumSet
+ * - SortedSet → 新TreeSet(复用原比较器)
+ * - 其他 → 新LinkedHashSet
+ *
*
- * @param source 源集合
- * @param candidates 候选元素集合
- * @return 包含任意候选元素返回true,否则false
+ * @param 元素类型
+ * @param collection 原集合,不可为null
+ * @return 与原集合类型匹配的空集合
*/
- @SuppressWarnings("rawtypes")
- public static boolean containsAny(Collection source, Collection candidates) {
- if (isEmpty(source) || isEmpty(candidates)) {
- return false;
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public static Collection createApproximateCollection(Object collection) {
+ if (collection instanceof LinkedList) {
+ return new LinkedList();
+ } else if (collection instanceof List) {
+ return new ArrayList();
+ } else if (collection instanceof EnumSet) {
+ // Cast is necessary for compilation in Eclipse 4.4.1.
+ Collection enumSet = (Collection) EnumSet.copyOf((EnumSet) collection);
+ enumSet.clear();
+ return enumSet;
+ } else if (collection instanceof SortedSet) {
+ return new TreeSet(((SortedSet