From e57281893463b23af49ec9dc427b56920efdf2f8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 30 May 2026 08:53:05 +0000 Subject: [PATCH 1/4] Add factory methods for concurrent collections and specialized Maps/Queues/Properties --- .../io/microsphere/collection/ListUtils.java | 46 +++ .../io/microsphere/collection/MapUtils.java | 184 +++++++++ .../collection/PropertiesUtils.java | 42 ++ .../io/microsphere/collection/QueueUtils.java | 381 ++++++++++++++++++ .../io/microsphere/collection/SetUtils.java | 111 +++++ 5 files changed, 764 insertions(+) diff --git a/microsphere-java-core/src/main/java/io/microsphere/collection/ListUtils.java b/microsphere-java-core/src/main/java/io/microsphere/collection/ListUtils.java index 7f155a3ec..6d3557514 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/collection/ListUtils.java +++ b/microsphere-java-core/src/main/java/io/microsphere/collection/ListUtils.java @@ -22,10 +22,12 @@ import io.microsphere.util.Utils; import java.util.ArrayList; +import java.util.Collection; import java.util.Enumeration; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -687,6 +689,50 @@ public static boolean addIfAbsent(List values, T newValue) { return values.contains(newValue) ? false : values.add(newValue); } + /** + * Creates a new empty {@link CopyOnWriteArrayList} instance. + * + *

This method provides a convenient way to create an empty copy-on-write array list. + * The returned list is thread-safe and allows for safe concurrent reads and writes.

+ * + *

Example Usage

+ *
{@code
+     *     List list = ListUtils.newCopyOnWriteArrayList();
+     *     System.out.println(list.isEmpty()); // Output: true
+     *
+     *     list.add("Hello");
+     *     System.out.println(list); // Output: [Hello]
+     * }
+ * + * @param the type of elements in the list + * @return a new, empty {@link CopyOnWriteArrayList} + */ + @Nonnull + public static CopyOnWriteArrayList newCopyOnWriteArrayList() { + return new CopyOnWriteArrayList<>(); + } + + /** + * Creates a new {@link CopyOnWriteArrayList} instance from the specified {@link Collection}. + * + *

This method converts the given {@link Collection} into a {@link CopyOnWriteArrayList}.

+ * + *

Example Usage

+ *
{@code
+     *     List original = Arrays.asList("apple", "banana", "cherry");
+     *     List list = ListUtils.newCopyOnWriteArrayList(original);
+     *     System.out.println(list); // Output: [apple, banana, cherry]
+     * }
+ * + * @param elements the collection of elements to add to the list, may be null or empty + * @param the type of elements in the collection + * @return a new {@link CopyOnWriteArrayList} containing all elements from the collection + */ + @Nonnull + public static CopyOnWriteArrayList newCopyOnWriteArrayList(Collection elements) { + return new CopyOnWriteArrayList<>(elements); + } + private ListUtils() { } } diff --git a/microsphere-java-core/src/main/java/io/microsphere/collection/MapUtils.java b/microsphere-java-core/src/main/java/io/microsphere/collection/MapUtils.java index c501019d8..4e9dd8d26 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/collection/MapUtils.java +++ b/microsphere-java-core/src/main/java/io/microsphere/collection/MapUtils.java @@ -29,6 +29,7 @@ import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; +import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentNavigableMap; @@ -1255,6 +1256,189 @@ static Map extraProperties(Map map) { return properties; } + /** + * Creates a new empty {@link ConcurrentSkipListMap} instance. + * + *

This method provides a convenient way to create an empty concurrent skip list map. + * The returned map is thread-safe and allows for efficient concurrent operations.

+ * + *

Example Usage

+ *
{@code
+     *     Map map = MapUtils.newConcurrentSkipListMap();
+     *     System.out.println(map.isEmpty()); // Output: true
+     *
+     *     map.put("key", "value");
+     *     System.out.println(map); // Output: {key=value}
+     * }
+ * + * @param the type of keys in the map + * @param the type of values in the map + * @return a new, empty {@link ConcurrentSkipListMap} + */ + @Nonnull + public static ConcurrentSkipListMap newConcurrentSkipListMap() { + return new ConcurrentSkipListMap<>(); + } + + /** + * Creates a new {@link ConcurrentSkipListMap} instance from the specified {@link Map}. + * + *

This method converts the given {@link Map} into a {@link ConcurrentSkipListMap}.

+ * + *

Example Usage

+ *
{@code
+     *     Map original = new HashMap<>();
+     *     original.put("key", "value");
+     *     Map map = MapUtils.newConcurrentSkipListMap(original);
+     *     System.out.println(map); // Output: {key=value}
+     * }
+ * + * @param map the map whose entries are to be copied, may be null or empty + * @param the type of keys in the map + * @param the type of values in the map + * @return a new {@link ConcurrentSkipListMap} containing all entries from the map + */ + @Nonnull + public static ConcurrentSkipListMap newConcurrentSkipListMap(Map map) { + return new ConcurrentSkipListMap<>(map); + } + + /** + * Creates a new empty {@link WeakHashMap} instance. + * + *

This method provides a convenient way to create an empty weak hash map. + * The returned map allows weak reference keys that can be garbage collected.

+ * + *

Example Usage

+ *
{@code
+     *     Map map = MapUtils.newWeakHashMap();
+     *     System.out.println(map.isEmpty()); // Output: true
+     *
+     *     map.put("key", "value");
+     *     System.out.println(map); // Output: {key=value}
+     * }
+ * + * @param the type of keys in the map + * @param the type of values in the map + * @return a new, empty {@link WeakHashMap} + */ + @Nonnull + public static WeakHashMap newWeakHashMap() { + return new WeakHashMap<>(); + } + + /** + * Creates a new {@link WeakHashMap} instance with the specified initial capacity. + * + *

This method provides a convenient way to create a weak hash map with a predefined initial size.

+ * + *

Example Usage

+ *
{@code
+     *     Map map = MapUtils.newWeakHashMap(16);
+     *     System.out.println(map.isEmpty()); // Output: true
+     * }
+ * + * @param initialCapacity the initial capacity of the weak hash map + * @param the type of keys in the map + * @param the type of values in the map + * @return a new, empty {@link WeakHashMap} with the specified initial capacity + */ + @Nonnull + public static WeakHashMap newWeakHashMap(int initialCapacity) { + return new WeakHashMap<>(initialCapacity); + } + + /** + * Creates a new {@link WeakHashMap} instance from the specified {@link Map}. + * + *

This method converts the given {@link Map} into a {@link WeakHashMap}.

+ * + *

Example Usage

+ *
{@code
+     *     Map original = new HashMap<>();
+     *     original.put("key", "value");
+     *     Map map = MapUtils.newWeakHashMap(original);
+     *     System.out.println(map); // Output: {key=value}
+     * }
+ * + * @param map the map whose entries are to be copied, may be null or empty + * @param the type of keys in the map + * @param the type of values in the map + * @return a new {@link WeakHashMap} containing all entries from the map + */ + @Nonnull + public static WeakHashMap newWeakHashMap(Map map) { + return new WeakHashMap<>(map); + } + + /** + * Creates a new empty {@link IdentityHashMap} instance. + * + *

This method provides a convenient way to create an empty identity hash map. + * The returned map uses reference equality instead of object equality for key comparisons.

+ * + *

Example Usage

+ *
{@code
+     *     Map map = MapUtils.newIdentityHashMap();
+     *     System.out.println(map.isEmpty()); // Output: true
+     *
+     *     map.put("key", "value");
+     *     System.out.println(map); // Output: {key=value}
+     * }
+ * + * @param the type of keys in the map + * @param the type of values in the map + * @return a new, empty {@link IdentityHashMap} + */ + @Nonnull + public static IdentityHashMap newIdentityHashMap() { + return new IdentityHashMap<>(); + } + + /** + * Creates a new {@link IdentityHashMap} instance with the specified expected maximum size. + * + *

This method provides a convenient way to create an identity hash map with a predefined initial size.

+ * + *

Example Usage

+ *
{@code
+     *     Map map = MapUtils.newIdentityHashMap(16);
+     *     System.out.println(map.isEmpty()); // Output: true
+     * }
+ * + * @param expectedMaxSize the expected maximum size of the map + * @param the type of keys in the map + * @param the type of values in the map + * @return a new, empty {@link IdentityHashMap} with the expected maximum size + */ + @Nonnull + public static IdentityHashMap newIdentityHashMap(int expectedMaxSize) { + return new IdentityHashMap<>(expectedMaxSize); + } + + /** + * Creates a new {@link IdentityHashMap} instance from the specified {@link Map}. + * + *

This method converts the given {@link Map} into an {@link IdentityHashMap}.

+ * + *

Example Usage

+ *
{@code
+     *     Map original = new HashMap<>();
+     *     original.put("key", "value");
+     *     Map map = MapUtils.newIdentityHashMap(original);
+     *     System.out.println(map); // Output: {key=value}
+     * }
+ * + * @param map the map whose entries are to be copied, may be null or empty + * @param the type of keys in the map + * @param the type of values in the map + * @return a new {@link IdentityHashMap} containing all entries from the map + */ + @Nonnull + public static IdentityHashMap newIdentityHashMap(Map map) { + return new IdentityHashMap<>(map); + } + private MapUtils() { } diff --git a/microsphere-java-core/src/main/java/io/microsphere/collection/PropertiesUtils.java b/microsphere-java-core/src/main/java/io/microsphere/collection/PropertiesUtils.java index 9c005759f..d3bbfd080 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/collection/PropertiesUtils.java +++ b/microsphere-java-core/src/main/java/io/microsphere/collection/PropertiesUtils.java @@ -102,6 +102,48 @@ private static String normalizePropertyName(String propertyNamePrefix, String pr return propertyNamePrefix == null ? propertyName : propertyNamePrefix + DOT + propertyName; } + /** + * Creates a new empty {@link Properties} instance. + * + *

This method provides a convenient way to create an empty properties object.

+ * + *

Example Usage

+ *
{@code
+     *     Properties props = PropertiesUtils.newProperties();
+     *     System.out.println(props.isEmpty()); // Output: true
+     *
+     *     props.setProperty("key", "value");
+     *     System.out.println(props); // Output: {key=value}
+     * }
+ * + * @return a new, empty {@link Properties} + */ + @Nonnull + public static Properties newProperties() { + return new Properties(); + } + + /** + * Creates a new {@link Properties} instance with the specified defaults. + * + *

This method provides a convenient way to create a properties object with default properties.

+ * + *

Example Usage

+ *
{@code
+     *     Properties defaults = new Properties();
+     *     defaults.setProperty("default.key", "default.value");
+     *     Properties props = PropertiesUtils.newProperties(defaults);
+     *     System.out.println(props.getProperty("default.key")); // Output: default.value
+     * }
+ * + * @param defaults the default properties + * @return a new {@link Properties} with the specified defaults + */ + @Nonnull + public static Properties newProperties(Properties defaults) { + return new Properties(defaults); + } + private PropertiesUtils() { } } diff --git a/microsphere-java-core/src/main/java/io/microsphere/collection/QueueUtils.java b/microsphere-java-core/src/main/java/io/microsphere/collection/QueueUtils.java index 1f83c6d00..165eb65aa 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/collection/QueueUtils.java +++ b/microsphere-java-core/src/main/java/io/microsphere/collection/QueueUtils.java @@ -22,9 +22,19 @@ import io.microsphere.util.Utils; import java.util.ArrayDeque; +import java.util.ArrayBlockingQueue; import java.util.Collection; +import java.util.Comparator; import java.util.Deque; +import java.util.DelayQueue; +import java.util.LinkedBlockingQueue; +import java.util.PriorityQueue; import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.Delayed; +import java.util.concurrent.PriorityBlockingQueue; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.LinkedTransferQueue; import static io.microsphere.collection.ReversedDeque.of; import static io.microsphere.util.ArrayUtils.length; @@ -406,6 +416,377 @@ public static ArrayDeque newArrayDeque(Collection elements) return new ArrayDeque<>(elements); } + /** + * Creates a new empty {@link PriorityQueue} instance. + * + *

This method provides a convenient way to create an empty priority queue. + * The returned queue orders elements according to their natural ordering.

+ * + *

Example Usage

+ *
{@code
+    *     Queue queue = QueueUtils.newPriorityQueue();
+    *     System.out.println(queue.isEmpty()); // Output: true
+    *
+    *     queue.add(3);
+    *     queue.add(1);
+    *     queue.add(2);
+    *     System.out.println(queue.poll()); // Output: 1
+    * }
+ * + * @param the type of elements in the queue + * @return a new, empty {@link PriorityQueue} + */ + @Nonnull + public static PriorityQueue newPriorityQueue() { + return new PriorityQueue<>(); + } + + /** + * Creates a new {@link PriorityQueue} instance with the specified initial capacity. + * + *

This method provides a convenient way to create a priority queue with a predefined initial size.

+ * + *

Example Usage

+ *
{@code
+    *     Queue queue = QueueUtils.newPriorityQueue(10);
+    *     System.out.println(queue.isEmpty()); // Output: true
+    * }
+ * + * @param initialCapacity the initial capacity of the priority queue + * @param the type of elements in the queue + * @return a new, empty {@link PriorityQueue} with the specified initial capacity + */ + @Nonnull + public static PriorityQueue newPriorityQueue(int initialCapacity) { + return new PriorityQueue<>(initialCapacity); + } + + /** + * Creates a new {@link PriorityQueue} instance with the specified comparator. + * + *

This method provides a convenient way to create a priority queue with a custom comparator.

+ * + *

Example Usage

+ *
{@code
+    *     Queue queue = QueueUtils.newPriorityQueue(Comparator.reverseOrder());
+    *     queue.add(1);
+    *     queue.add(3);
+    *     queue.add(2);
+    *     System.out.println(queue.poll()); // Output: 3
+    * }
+ * + * @param comparator the comparator to use for ordering elements + * @param the type of elements in the queue + * @return a new, empty {@link PriorityQueue} with the specified comparator + */ + @Nonnull + public static PriorityQueue newPriorityQueue(Comparator comparator) { + return new PriorityQueue<>(comparator); + } + + /** + * Creates a new {@link PriorityQueue} instance from the specified {@link Collection}. + * + *

This method converts the given {@link Collection} into a {@link PriorityQueue}.

+ * + *

Example Usage

+ *
{@code
+    *     Collection original = Arrays.asList(3, 1, 2);
+    *     Queue queue = QueueUtils.newPriorityQueue(original);
+    *     System.out.println(queue.poll()); // Output: 1
+    * }
+ * + * @param elements the collection of elements to add to the queue, may be null or empty + * @param the type of elements in the collection + * @return a new {@link PriorityQueue} containing all elements from the collection + */ + @Nonnull + public static PriorityQueue newPriorityQueue(Collection elements) { + return new PriorityQueue<>(elements); + } + + /** + * Creates a new empty {@link ConcurrentLinkedQueue} instance. + * + *

This method provides a convenient way to create an empty concurrent linked queue. + * The returned queue is thread-safe and allows for safe concurrent operations.

+ * + *

Example Usage

+ *
{@code
+    *     Queue queue = QueueUtils.newConcurrentLinkedQueue();
+    *     System.out.println(queue.isEmpty()); // Output: true
+    *
+    *     queue.add("Hello");
+    *     System.out.println(queue.poll()); // Output: Hello
+    * }
+ * + * @param the type of elements in the queue + * @return a new, empty {@link ConcurrentLinkedQueue} + */ + @Nonnull + public static ConcurrentLinkedQueue newConcurrentLinkedQueue() { + return new ConcurrentLinkedQueue<>(); + } + + /** + * Creates a new {@link ConcurrentLinkedQueue} instance from the specified {@link Collection}. + * + *

This method converts the given {@link Collection} into a {@link ConcurrentLinkedQueue}.

+ * + *

Example Usage

+ *
{@code
+    *     Collection original = Arrays.asList("a", "b", "c");
+    *     Queue queue = QueueUtils.newConcurrentLinkedQueue(original);
+    *     System.out.println(queue); // Output: [a, b, c]
+    * }
+ * + * @param elements the collection of elements to add to the queue, may be null or empty + * @param the type of elements in the collection + * @return a new {@link ConcurrentLinkedQueue} containing all elements from the collection + */ + @Nonnull + public static ConcurrentLinkedQueue newConcurrentLinkedQueue(Collection elements) { + return new ConcurrentLinkedQueue<>(elements); + } + + /** + * Creates a new empty {@link LinkedBlockingQueue} instance. + * + *

This method provides a convenient way to create an empty linked blocking queue. + * The returned queue is thread-safe and allows for blocking operations.

+ * + *

Example Usage

+ *
{@code
+    *     Queue queue = QueueUtils.newLinkedBlockingQueue();
+    *     System.out.println(queue.isEmpty()); // Output: true
+    *
+    *     queue.add("Hello");
+    *     System.out.println(queue.poll()); // Output: Hello
+    * }
+ * + * @param the type of elements in the queue + * @return a new, empty {@link LinkedBlockingQueue} + */ + @Nonnull + public static LinkedBlockingQueue newLinkedBlockingQueue() { + return new LinkedBlockingQueue<>(); + } + + /** + * Creates a new {@link LinkedBlockingQueue} instance with the specified capacity. + * + *

This method provides a convenient way to create a linked blocking queue with a predefined capacity.

+ * + *

Example Usage

+ *
{@code
+    *     Queue queue = QueueUtils.newLinkedBlockingQueue(10);
+    *     System.out.println(queue.isEmpty()); // Output: true
+    * }
+ * + * @param capacity the capacity of the linked blocking queue + * @param the type of elements in the queue + * @return a new, empty {@link LinkedBlockingQueue} with the specified capacity + */ + @Nonnull + public static LinkedBlockingQueue newLinkedBlockingQueue(int capacity) { + return new LinkedBlockingQueue<>(capacity); + } + + /** + * Creates a new {@link LinkedBlockingQueue} instance from the specified {@link Collection}. + * + *

This method converts the given {@link Collection} into a {@link LinkedBlockingQueue}.

+ * + *

Example Usage

+ *
{@code
+    *     Collection original = Arrays.asList("a", "b", "c");
+    *     Queue queue = QueueUtils.newLinkedBlockingQueue(original);
+    *     System.out.println(queue); // Output: [a, b, c]
+    * }
+ * + * @param elements the collection of elements to add to the queue, may be null or empty + * @param the type of elements in the collection + * @return a new {@link LinkedBlockingQueue} containing all elements from the collection + */ + @Nonnull + public static LinkedBlockingQueue newLinkedBlockingQueue(Collection elements) { + return new LinkedBlockingQueue<>(elements); + } + + /** + * Creates a new empty {@link ArrayBlockingQueue} instance with the specified capacity. + * + *

This method provides a convenient way to create an empty array blocking queue with a predefined capacity.

+ * + *

Example Usage

+ *
{@code
+    *     Queue queue = QueueUtils.newArrayBlockingQueue(10);
+    *     System.out.println(queue.isEmpty()); // Output: true
+    *
+    *     queue.add("Hello");
+    *     System.out.println(queue.poll()); // Output: Hello
+    * }
+ * + * @param capacity the capacity of the array blocking queue + * @param the type of elements in the queue + * @return a new, empty {@link ArrayBlockingQueue} with the specified capacity + */ + @Nonnull + public static ArrayBlockingQueue newArrayBlockingQueue(int capacity) { + return new ArrayBlockingQueue<>(capacity); + } + + /** + * Creates a new {@link ArrayBlockingQueue} instance from the specified {@link Collection}. + * + *

This method converts the given {@link Collection} into an {@link ArrayBlockingQueue}.

+ * + *

Example Usage

+ *
{@code
+    *     Collection original = Arrays.asList("a", "b", "c");
+    *     Queue queue = QueueUtils.newArrayBlockingQueue(10, original);
+    *     System.out.println(queue); // Output: [a, b, c]
+    * }
+ * + * @param capacity the capacity of the array blocking queue + * @param elements the collection of elements to add to the queue, may be null or empty + * @param the type of elements in the collection + * @return a new {@link ArrayBlockingQueue} containing all elements from the collection + */ + @Nonnull + public static ArrayBlockingQueue newArrayBlockingQueue(int capacity, Collection elements) { + return new ArrayBlockingQueue<>(capacity, false, elements); + } + + /** + * Creates a new empty {@link PriorityBlockingQueue} instance. + * + *

This method provides a convenient way to create an empty priority blocking queue. + * The returned queue is thread-safe and orders elements according to their natural ordering.

+ * + *

Example Usage

+ *
{@code
+    *     Queue queue = QueueUtils.newPriorityBlockingQueue();
+    *     System.out.println(queue.isEmpty()); // Output: true
+    *
+    *     queue.add(3);
+    *     queue.add(1);
+    *     System.out.println(queue.poll()); // Output: 1
+    * }
+ * + * @param the type of elements in the queue + * @return a new, empty {@link PriorityBlockingQueue} + */ + @Nonnull + public static PriorityBlockingQueue newPriorityBlockingQueue() { + return new PriorityBlockingQueue<>(); + } + + /** + * Creates a new {{@link PriorityBlockingQueue} instance from the specified {@link Collection}. + * + *

This method converts the given {@link Collection} into a {@link PriorityBlockingQueue}.

+ * + *

Example Usage

+ *
{@code
+    *     Collection original = Arrays.asList(3, 1, 2);
+    *     Queue queue = QueueUtils.newPriorityBlockingQueue(original);
+    *     System.out.println(queue.poll()); // Output: 1
+    * }
+ * + * @param elements the collection of elements to add to the queue, may be null or empty + * @param the type of elements in the collection + * @return a new {@link PriorityBlockingQueue} containing all elements from the collection + */ + @Nonnull + public static PriorityBlockingQueue newPriorityBlockingQueue(Collection elements) { + return new PriorityBlockingQueue<>(elements); + } + + /** + * Creates a new empty {@link DelayQueue} instance. + * + *

This method provides a convenient way to create an empty delay queue. + * The returned queue is an unbounded queue where elements can only be retrieved after their delay expires.

+ * + *

Example Usage

+ *
{@code
+    *     Queue queue = QueueUtils.newDelayQueue();
+    *     System.out.println(queue.isEmpty()); // Output: true
+    * }
+ * + * @param the type of elements in the queue, must be of type Delayed + * @return a new, empty {@link DelayQueue} + */ + @Nonnull + public static DelayQueue newDelayQueue() { + return new DelayQueue<>(); + } + + /** + * Creates a new empty {@link SynchronousQueue} instance. + * + *

This method provides a convenient way to create an empty synchronous queue. + * The returned queue is a blocking queue with zero capacity where each put operation must wait for a get operation.

+ * + *

Example Usage

+ *
{@code
+    *     Queue queue = QueueUtils.newSynchronousQueue();
+    *     System.out.println(queue.isEmpty()); // Output: true
+    * }
+ * + * @param the type of elements in the queue + * @return a new, empty {@link SynchronousQueue} + */ + @Nonnull + public static SynchronousQueue newSynchronousQueue() { + return new SynchronousQueue<>(); + } + + /** + * Creates a new empty {@link LinkedTransferQueue} instance. + * + *

This method provides a convenient way to create an empty linked transfer queue. + * The returned queue is an unbounded queue for use with producers and consumers that may arrive and depart dynamically.

+ * + *

Example Usage

+ *
{@code
+    *     Queue queue = QueueUtils.newLinkedTransferQueue();
+    *     System.out.println(queue.isEmpty()); // Output: true
+    *
+    *     queue.add("Hello");
+    *     System.out.println(queue.poll()); // Output: Hello
+    * }
+ * + * @param the type of elements in the queue + * @return a new, empty {@link LinkedTransferQueue} + */ + @Nonnull + public static LinkedTransferQueue newLinkedTransferQueue() { + return new LinkedTransferQueue<>(); + } + + /** + * Creates a new {@link LinkedTransferQueue} instance from the specified {@link Collection}. + * + *

This method converts the given {@link Collection} into a {@link LinkedTransferQueue}.

+ * + *

Example Usage

+ *
{@code
+    *     Collection original = Arrays.asList("a", "b", "c");
+    *     Queue queue = QueueUtils.newLinkedTransferQueue(original);
+    *     System.out.println(queue); // Output: [a, b, c]
+    * }
+ * + * @param elements the collection of elements to add to the queue, may be null or empty + * @param the type of elements in the collection + * @return a new {@link LinkedTransferQueue} containing all elements from the collection + */ + @Nonnull + public static LinkedTransferQueue newLinkedTransferQueue(Collection elements) { + return new LinkedTransferQueue<>(elements); + } + private QueueUtils() { } } diff --git a/microsphere-java-core/src/main/java/io/microsphere/collection/SetUtils.java b/microsphere-java-core/src/main/java/io/microsphere/collection/SetUtils.java index 2a0db6cbf..9a76d5f50 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/collection/SetUtils.java +++ b/microsphere-java-core/src/main/java/io/microsphere/collection/SetUtils.java @@ -30,6 +30,8 @@ import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; +import java.util.concurrent.CopyOnWriteArraySet; +import java.util.concurrent.ConcurrentSkipListSet; import static io.microsphere.collection.CollectionUtils.size; import static io.microsphere.collection.MapUtils.FIXED_LOAD_FACTOR; @@ -774,6 +776,115 @@ public static TreeSet newTreeSet(SortedSet sortedSet) { return new TreeSet<>(sortedSet); } + /** + * Creates a new empty {@link CopyOnWriteArraySet} instance. + * + *

This method provides a convenient way to create an empty copy-on-write array set. + * The returned set is thread-safe and allows for safe concurrent reads and writes.

+ * + *

Example Usage

+ *
{@code
+    *     Set set = SetUtils.newCopyOnWriteArraySet();
+    *     System.out.println(set.isEmpty()); // Output: true
+    *
+    *     set.add("Hello");
+    *     System.out.println(set); // Output: [Hello]
+    * }
+ * + * @param the type of elements in the set + * @return a new, empty {@link CopyOnWriteArraySet} + */ + @Nonnull + public static CopyOnWriteArraySet newCopyOnWriteArraySet() { + return new CopyOnWriteArraySet<>(); + } + + /** + * Creates a new {@link CopyOnWriteArraySet} instance from the specified {@link Collection}. + * + *

This method converts the given {@link Collection} into a {@link CopyOnWriteArraySet}.

+ * + *

Example Usage

+ *
{@code
+    *     Set original = Arrays.asList("apple", "banana", "cherry");
+    *     Set set = SetUtils.newCopyOnWriteArraySet(original);
+    *     System.out.println(set); // Output: [apple, banana, cherry]
+    * }
+ * + * @param elements the collection of elements to add to the set, may be null or empty + * @param the type of elements in the collection + * @return a new {@link CopyOnWriteArraySet} containing all elements from the collection + */ + @Nonnull + public static CopyOnWriteArraySet newCopyOnWriteArraySet(Collection elements) { + return new CopyOnWriteArraySet<>(elements); + } + + /** + * Creates a new empty {@link ConcurrentSkipListSet} instance. + * + *

This method provides a convenient way to create an empty concurrent skip list set. + * The returned set is thread-safe and allows for efficient concurrent operations.

+ * + *

Example Usage

+ *
{@code
+    *     Set set = SetUtils.newConcurrentSkipListSet();
+    *     System.out.println(set.isEmpty()); // Output: true
+    *
+    *     set.add("Hello");
+    *     System.out.println(set); // Output: [Hello]
+    * }
+ * + * @param the type of elements in the set + * @return a new, empty {@link ConcurrentSkipListSet} + */ + @Nonnull + public static ConcurrentSkipListSet newConcurrentSkipListSet() { + return new ConcurrentSkipListSet<>(); + } + + /** + * Creates a new {@link ConcurrentSkipListSet} instance from the specified {@link Collection}. + * + *

This method converts the given {@link Collection} into a {@link ConcurrentSkipListSet}.

+ * + *

Example Usage

+ *
{@code
+    *     Set original = Arrays.asList("apple", "banana", "cherry");
+    *     Set set = SetUtils.newConcurrentSkipListSet(original);
+    *     System.out.println(set); // Output: [apple, banana, cherry]
+    * }
+ * + * @param elements the collection of elements to add to the set, may be null or empty + * @param the type of elements in the collection + * @return a new {@link ConcurrentSkipListSet} containing all elements from the collection + */ + @Nonnull + public static ConcurrentSkipListSet newConcurrentSkipListSet(Collection elements) { + return new ConcurrentSkipListSet<>(elements); + } + + /** + * Creates a new {@link ConcurrentSkipListSet} instance from the specified {@link SortedSet}. + * + *

This method converts the given {@link SortedSet} into a {@link ConcurrentSkipListSet}.

+ * + *

Example Usage

+ *
{@code
+    *     SortedSet original = new TreeSet<>(Arrays.asList("apple", "banana", "cherry"));
+    *     Set set = SetUtils.newConcurrentSkipListSet(original);
+    *     System.out.println(set); // Output: [apple, banana, cherry]
+    * }
+ * + * @param sortedSet the sorted set whose elements are to be copied, may be null or empty + * @param the type of elements in the sorted set + * @return a new {@link ConcurrentSkipListSet} containing all elements from the sorted set + */ + @Nonnull + public static ConcurrentSkipListSet newConcurrentSkipListSet(SortedSet sortedSet) { + return new ConcurrentSkipListSet<>(sortedSet); + } + private SetUtils() { } } From 948c3f055783ac1fd38fe5f4e69c5075e12fd27b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 30 May 2026 08:57:52 +0000 Subject: [PATCH 2/4] Add tests for new factory methods in collection utilities --- .../microsphere/collection/ListUtilsTest.java | 41 ++-- .../microsphere/collection/MapUtilsTest.java | 81 ++++++++ .../collection/PropertiesUtilsTest.java | 25 +++ .../collection/QueueUtilsTest.java | 185 ++++++++++++++++++ .../microsphere/collection/SetUtilsTest.java | 66 +++++++ 5 files changed, 382 insertions(+), 16 deletions(-) diff --git a/microsphere-java-core/src/test/java/io/microsphere/collection/ListUtilsTest.java b/microsphere-java-core/src/test/java/io/microsphere/collection/ListUtilsTest.java index 5887d323a..7f0036f54 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/collection/ListUtilsTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/collection/ListUtilsTest.java @@ -1,19 +1,3 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ package io.microsphere.collection; import io.microsphere.Loggable; @@ -27,6 +11,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Set; +import java.util.concurrent.CopyOnWriteArrayList; import static io.microsphere.AbstractTestCase.TEST_NULL_ENUMERATION; import static io.microsphere.AbstractTestCase.TEST_NULL_ITERABLE; @@ -38,6 +23,7 @@ import static io.microsphere.collection.ListUtils.isList; import static io.microsphere.collection.ListUtils.last; import static io.microsphere.collection.ListUtils.newArrayList; +import static io.microsphere.collection.ListUtils.newCopyOnWriteArrayList; import static io.microsphere.collection.ListUtils.newLinkedList; import static io.microsphere.collection.ListUtils.of; import static io.microsphere.collection.ListUtils.ofArrayList; @@ -52,6 +38,7 @@ import static java.util.Collections.singleton; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -255,4 +242,26 @@ void testAddIfAbsent() { assertFalse(addIfAbsent(values, "A")); assertTrue(addIfAbsent(values, "B")); } + + @Test + void testNewCopyOnWriteArrayListEmpty() { + CopyOnWriteArrayList list = newCopyOnWriteArrayList(); + assertNotNull(list); + assertTrue(list.isEmpty()); + assertEquals(0, list.size()); + } + + @Test + void testNewCopyOnWriteArrayListWithCollection() { + Collection source = asList("a", "b", "c"); + CopyOnWriteArrayList list = newCopyOnWriteArrayList(source); + assertNotNull(list); + assertEquals(3, list.size()); + assertEquals("a", list.get(0)); + assertEquals("b", list.get(1)); + assertEquals("c", list.get(2)); + assertTrue(list.contains("a")); + assertTrue(list.contains("b")); + assertTrue(list.contains("c")); + } } diff --git a/microsphere-java-core/src/test/java/io/microsphere/collection/MapUtilsTest.java b/microsphere-java-core/src/test/java/io/microsphere/collection/MapUtilsTest.java index f99422e6a..78758120d 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/collection/MapUtilsTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/collection/MapUtilsTest.java @@ -24,6 +24,7 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.TreeMap; +import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentSkipListMap; import java.util.function.Function; @@ -39,9 +40,12 @@ import static io.microsphere.collection.MapUtils.isNotEmpty; import static io.microsphere.collection.MapUtils.nestedMap; import static io.microsphere.collection.MapUtils.newConcurrentHashMap; +import static io.microsphere.collection.MapUtils.newConcurrentSkipListMap; import static io.microsphere.collection.MapUtils.newHashMap; +import static io.microsphere.collection.MapUtils.newIdentityHashMap; import static io.microsphere.collection.MapUtils.newLinkedHashMap; import static io.microsphere.collection.MapUtils.newTreeMap; +import static io.microsphere.collection.MapUtils.newWeakHashMap; import static io.microsphere.collection.MapUtils.of; import static io.microsphere.collection.MapUtils.ofEntry; import static io.microsphere.collection.MapUtils.ofMap; @@ -57,6 +61,7 @@ import static java.util.Collections.unmodifiableMap; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -447,4 +452,80 @@ private void assertNewMap(Class mapClass, Map map) { assertEquals(0, map.size()); assertTrue(map.isEmpty()); } + + @Test + void testNewConcurrentSkipListMapEmpty() { + ConcurrentSkipListMap map = newConcurrentSkipListMap(); + assertNotNull(map); + assertTrue(map.isEmpty()); + assertEquals(0, map.size()); + } + + @Test + void testNewConcurrentSkipListMapWithMap() { + Map source = ofMap("c", 3, "a", 1, "b", 2); + ConcurrentSkipListMap map = newConcurrentSkipListMap(source); + assertNotNull(map); + assertEquals(3, map.size()); + assertEquals(1, map.get("a")); + assertEquals(2, map.get("b")); + assertEquals(3, map.get("c")); + // ConcurrentSkipListMap maintains sorted order by key + Object[] keys = map.keySet().toArray(); + assertEquals("a", keys[0]); + assertEquals("b", keys[1]); + assertEquals("c", keys[2]); + } + + @Test + void testNewWeakHashMapEmpty() { + WeakHashMap map = newWeakHashMap(); + assertNotNull(map); + assertTrue(map.isEmpty()); + assertEquals(0, map.size()); + } + + @Test + void testNewWeakHashMapWithCapacity() { + WeakHashMap map = newWeakHashMap(16); + assertNotNull(map); + assertTrue(map.isEmpty()); + } + + @Test + void testNewWeakHashMapWithMap() { + Map source = ofMap("a", 1, "b", 2, "c", 3); + WeakHashMap map = newWeakHashMap(source); + assertNotNull(map); + assertEquals(3, map.size()); + assertEquals(1, map.get("a")); + assertEquals(2, map.get("b")); + assertEquals(3, map.get("c")); + } + + @Test + void testNewIdentityHashMapEmpty() { + IdentityHashMap map = newIdentityHashMap(); + assertNotNull(map); + assertTrue(map.isEmpty()); + assertEquals(0, map.size()); + } + + @Test + void testNewIdentityHashMapWithExpectedMaxSize() { + IdentityHashMap map = newIdentityHashMap(16); + assertNotNull(map); + assertTrue(map.isEmpty()); + } + + @Test + void testNewIdentityHashMapWithMap() { + Map source = ofMap("a", 1, "b", 2, "c", 3); + IdentityHashMap map = newIdentityHashMap(source); + assertNotNull(map); + assertEquals(3, map.size()); + assertEquals(1, map.get("a")); + assertEquals(2, map.get("b")); + assertEquals(3, map.get("c")); + } } diff --git a/microsphere-java-core/src/test/java/io/microsphere/collection/PropertiesUtilsTest.java b/microsphere-java-core/src/test/java/io/microsphere/collection/PropertiesUtilsTest.java index 608244626..0f4b71c8b 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/collection/PropertiesUtilsTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/collection/PropertiesUtilsTest.java @@ -19,14 +19,18 @@ import org.junit.jupiter.api.Test; import java.util.Map; +import java.util.Properties; import static io.microsphere.collection.MapUtils.ofMap; import static io.microsphere.collection.PropertiesUtils.flatProperties; +import static io.microsphere.collection.PropertiesUtils.newProperties; import static java.util.Collections.emptyList; import static java.util.Collections.emptyMap; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * {@link PropertiesUtils} Test @@ -56,4 +60,25 @@ void testFlatPropertiesOnEmptyMap() { void testFlatPropertiesOnNull() { assertNull(flatProperties(null)); } + + @Test + void testNewPropertiesEmpty() { + Properties props = newProperties(); + assertNotNull(props); + assertTrue(props.isEmpty()); + assertEquals(0, props.size()); + } + + @Test + void testNewPropertiesWithDefaults() { + Properties defaults = new Properties(); + defaults.setProperty("key1", "value1"); + defaults.setProperty("key2", "value2"); + + Properties props = newProperties(defaults); + assertNotNull(props); + assertEquals("value1", props.getProperty("key1")); + assertEquals("value2", props.getProperty("key2")); + assertTrue(props.isEmpty()); // Properties from defaults are not in the main properties + } } diff --git a/microsphere-java-core/src/test/java/io/microsphere/collection/QueueUtilsTest.java b/microsphere-java-core/src/test/java/io/microsphere/collection/QueueUtilsTest.java index eec75a0d6..3e6543630 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/collection/QueueUtilsTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/collection/QueueUtilsTest.java @@ -2,13 +2,23 @@ import org.junit.jupiter.api.Test; +import java.util.ArrayBlockingQueue; import java.util.ArrayDeque; import java.util.Collection; +import java.util.Comparator; +import java.util.DelayQueue; import java.util.Deque; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedBlockingQueue; import java.util.NoSuchElementException; +import java.util.PriorityQueue; import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.Delayed; +import java.util.concurrent.LinkedTransferQueue; +import java.util.concurrent.PriorityBlockingQueue; +import java.util.concurrent.SynchronousQueue; import static io.microsphere.collection.EmptyDeque.INSTANCE; import static io.microsphere.collection.ListUtils.newLinkedList; @@ -19,7 +29,15 @@ import static io.microsphere.collection.QueueUtils.emptyQueue; import static io.microsphere.collection.QueueUtils.isDeque; import static io.microsphere.collection.QueueUtils.isQueue; +import static io.microsphere.collection.QueueUtils.newArrayBlockingQueue; import static io.microsphere.collection.QueueUtils.newArrayDeque; +import static io.microsphere.collection.QueueUtils.newConcurrentLinkedQueue; +import static io.microsphere.collection.QueueUtils.newDelayQueue; +import static io.microsphere.collection.QueueUtils.newLinkedBlockingQueue; +import static io.microsphere.collection.QueueUtils.newLinkedTransferQueue; +import static io.microsphere.collection.QueueUtils.newPriorityBlockingQueue; +import static io.microsphere.collection.QueueUtils.newPriorityQueue; +import static io.microsphere.collection.QueueUtils.newSynchronousQueue; import static io.microsphere.collection.QueueUtils.ofQueue; import static io.microsphere.collection.QueueUtils.reversedDeque; import static io.microsphere.collection.QueueUtils.singletonDeque; @@ -267,4 +285,171 @@ void testNewArrayDequeWithSet() { assertTrue(deque.contains("c")); } + @Test + void testNewPriorityQueueEmpty() { + PriorityQueue queue = newPriorityQueue(); + assertNotNull(queue); + assertTrue(queue.isEmpty()); + assertEquals(0, queue.size()); + } + + @Test + void testNewPriorityQueueWithCapacity() { + PriorityQueue queue = newPriorityQueue(10); + assertNotNull(queue); + assertTrue(queue.isEmpty()); + } + + @Test + void testNewPriorityQueueWithComparator() { + Comparator reverseComparator = (a, b) -> b.compareTo(a); + PriorityQueue queue = newPriorityQueue(reverseComparator); + queue.add(3); + queue.add(1); + queue.add(2); + assertEquals(3, queue.poll()); // Reverse order + assertEquals(2, queue.poll()); + assertEquals(1, queue.poll()); + } + + @Test + void testNewPriorityQueueWithCollection() { + Collection source = asList(3, 1, 2); + PriorityQueue queue = newPriorityQueue(source); + assertNotNull(queue); + assertEquals(3, queue.size()); + assertEquals(1, queue.poll()); // Natural order + assertEquals(2, queue.poll()); + assertEquals(3, queue.poll()); + } + + @Test + void testNewConcurrentLinkedQueueEmpty() { + ConcurrentLinkedQueue queue = newConcurrentLinkedQueue(); + assertNotNull(queue); + assertTrue(queue.isEmpty()); + assertEquals(0, queue.size()); + } + + @Test + void testNewConcurrentLinkedQueueWithCollection() { + Collection source = asList("a", "b", "c"); + ConcurrentLinkedQueue queue = newConcurrentLinkedQueue(source); + assertNotNull(queue); + assertEquals(3, queue.size()); + assertTrue(queue.contains("a")); + assertTrue(queue.contains("b")); + assertTrue(queue.contains("c")); + } + + @Test + void testNewLinkedBlockingQueueEmpty() { + LinkedBlockingQueue queue = newLinkedBlockingQueue(); + assertNotNull(queue); + assertTrue(queue.isEmpty()); + assertEquals(0, queue.size()); + } + + @Test + void testNewLinkedBlockingQueueWithCapacity() { + LinkedBlockingQueue queue = newLinkedBlockingQueue(5); + assertNotNull(queue); + assertTrue(queue.isEmpty()); + } + + @Test + void testNewLinkedBlockingQueueWithCollection() { + Collection source = asList("a", "b", "c"); + LinkedBlockingQueue queue = newLinkedBlockingQueue(source); + assertNotNull(queue); + assertEquals(3, queue.size()); + assertEquals("a", queue.poll()); + assertEquals("b", queue.poll()); + assertEquals("c", queue.poll()); + } + + @Test + void testNewArrayBlockingQueueWithCapacity() { + ArrayBlockingQueue queue = newArrayBlockingQueue(10); + assertNotNull(queue); + assertTrue(queue.isEmpty()); + } + + @Test + void testNewArrayBlockingQueueWithCollection() { + Collection source = asList("a", "b", "c"); + ArrayBlockingQueue queue = newArrayBlockingQueue(10, source); + assertNotNull(queue); + assertEquals(3, queue.size()); + assertTrue(queue.contains("a")); + assertTrue(queue.contains("b")); + assertTrue(queue.contains("c")); + } + + @Test + void testNewPriorityBlockingQueueEmpty() { + PriorityBlockingQueue queue = newPriorityBlockingQueue(); + assertNotNull(queue); + assertTrue(queue.isEmpty()); + assertEquals(0, queue.size()); + } + + @Test + void testNewPriorityBlockingQueueWithCollection() { + Collection source = asList(3, 1, 2); + PriorityBlockingQueue queue = newPriorityBlockingQueue(source); + assertNotNull(queue); + assertEquals(3, queue.size()); + assertEquals(1, queue.poll()); // Natural order + assertEquals(2, queue.poll()); + assertEquals(3, queue.poll()); + } + + @Test + void testNewDelayQueueEmpty() { + DelayQueue queue = newDelayQueue(); + assertNotNull(queue); + assertTrue(queue.isEmpty()); + assertEquals(0, queue.size()); + } + + @Test + void testNewSynchronousQueueEmpty() { + SynchronousQueue queue = newSynchronousQueue(); + assertNotNull(queue); + assertTrue(queue.isEmpty()); + assertEquals(0, queue.size()); + } + + @Test + void testNewLinkedTransferQueueEmpty() { + LinkedTransferQueue queue = newLinkedTransferQueue(); + assertNotNull(queue); + assertTrue(queue.isEmpty()); + assertEquals(0, queue.size()); + } + + @Test + void testNewLinkedTransferQueueWithCollection() { + Collection source = asList("a", "b", "c"); + LinkedTransferQueue queue = newLinkedTransferQueue(source); + assertNotNull(queue); + assertEquals(3, queue.size()); + assertTrue(queue.contains("a")); + assertTrue(queue.contains("b")); + assertTrue(queue.contains("c")); + } + + // Test helper class for DelayQueue testing + static class TestDelayed implements Delayed { + @Override + public long getDelay(java.util.concurrent.TimeUnit unit) { + return 0; + } + + @Override + public int compareTo(Delayed o) { + return 0; + } + } } diff --git a/microsphere-java-core/src/test/java/io/microsphere/collection/SetUtilsTest.java b/microsphere-java-core/src/test/java/io/microsphere/collection/SetUtilsTest.java index 4fd57574f..2ef53092c 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/collection/SetUtilsTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/collection/SetUtilsTest.java @@ -9,13 +9,18 @@ import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; +import java.util.SortedSet; import java.util.TreeSet; +import java.util.concurrent.ConcurrentSkipListSet; +import java.util.concurrent.CopyOnWriteArraySet; import static io.microsphere.AbstractTestCase.TEST_NULL_STRING_ARRAY; import static io.microsphere.collection.CollectionUtils.toIterable; import static io.microsphere.collection.EnumerationUtils.ofEnumeration; import static io.microsphere.collection.MapUtils.FIXED_LOAD_FACTOR; import static io.microsphere.collection.SetUtils.isSet; +import static io.microsphere.collection.SetUtils.newConcurrentSkipListSet; +import static io.microsphere.collection.SetUtils.newCopyOnWriteArraySet; import static io.microsphere.collection.SetUtils.newFixedHashSet; import static io.microsphere.collection.SetUtils.newFixedLinkedHashSet; import static io.microsphere.collection.SetUtils.newHashSet; @@ -26,8 +31,10 @@ import static java.util.Collections.emptyEnumeration; import static java.util.Collections.emptyList; import static java.util.Collections.emptySet; +import static java.util.Arrays.asList; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -214,6 +221,65 @@ void testNewTreeSetWithSortedSet() { assertEquals("z", elements[2]); } + @Test + void testNewCopyOnWriteArraySetEmpty() { + CopyOnWriteArraySet set = newCopyOnWriteArraySet(); + assertNotNull(set); + assertTrue(set.isEmpty()); + assertEquals(0, set.size()); + } + + @Test + void testNewCopyOnWriteArraySetWithCollection() { + Collection source = asList("a", "b", "c"); + CopyOnWriteArraySet set = newCopyOnWriteArraySet(source); + assertNotNull(set); + assertEquals(3, set.size()); + assertTrue(set.contains("a")); + assertTrue(set.contains("b")); + assertTrue(set.contains("c")); + } + + @Test + void testNewConcurrentSkipListSetEmpty() { + ConcurrentSkipListSet set = newConcurrentSkipListSet(); + assertNotNull(set); + assertTrue(set.isEmpty()); + assertEquals(0, set.size()); + } + + @Test + void testNewConcurrentSkipListSetWithCollection() { + Collection source = asList("c", "a", "b"); + ConcurrentSkipListSet set = newConcurrentSkipListSet(source); + assertNotNull(set); + assertEquals(3, set.size()); + assertTrue(set.contains("a")); + assertTrue(set.contains("b")); + assertTrue(set.contains("c")); + // ConcurrentSkipListSet maintains sorted order + Object[] elements = set.toArray(); + assertEquals("a", elements[0]); + assertEquals("b", elements[1]); + assertEquals("c", elements[2]); + } + + @Test + void testNewConcurrentSkipListSetWithSortedSet() { + SortedSet sourceSortedSet = new TreeSet<>(asList("z", "y", "x")); + ConcurrentSkipListSet set = newConcurrentSkipListSet(sourceSortedSet); + assertNotNull(set); + assertEquals(3, set.size()); + assertTrue(set.contains("x")); + assertTrue(set.contains("y")); + assertTrue(set.contains("z")); + // ConcurrentSkipListSet maintains sorted order + Object[] elements = set.toArray(); + assertEquals("x", elements[0]); + assertEquals("y", elements[1]); + assertEquals("z", elements[2]); + } + private void assertSet(Set set) { assertEquals(3, set.size()); assertTrue(set.contains("a")); From abe85657aa7e6a283c569cfca3a90a481d4e4318 Mon Sep 17 00:00:00 2001 From: Mercy Ma Date: Sat, 30 May 2026 17:08:19 +0800 Subject: [PATCH 3/4] Fix imports for concurrent queue classes Move queue implementations to the correct package: import ArrayBlockingQueue, DelayQueue, LinkedBlockingQueue, and LinkedTransferQueue from java.util.concurrent (remove incorrect java.util.ArrayBlockingQueue). Reorder/cleanup imports for consistency and to fix compilation issues referencing the wrong packages. --- .../main/java/io/microsphere/collection/QueueUtils.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/microsphere-java-core/src/main/java/io/microsphere/collection/QueueUtils.java b/microsphere-java-core/src/main/java/io/microsphere/collection/QueueUtils.java index 165eb65aa..4226816f5 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/collection/QueueUtils.java +++ b/microsphere-java-core/src/main/java/io/microsphere/collection/QueueUtils.java @@ -22,19 +22,19 @@ import io.microsphere.util.Utils; import java.util.ArrayDeque; -import java.util.ArrayBlockingQueue; import java.util.Collection; import java.util.Comparator; import java.util.Deque; -import java.util.DelayQueue; -import java.util.LinkedBlockingQueue; import java.util.PriorityQueue; import java.util.Queue; +import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.DelayQueue; import java.util.concurrent.Delayed; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.LinkedTransferQueue; import java.util.concurrent.PriorityBlockingQueue; import java.util.concurrent.SynchronousQueue; -import java.util.concurrent.LinkedTransferQueue; import static io.microsphere.collection.ReversedDeque.of; import static io.microsphere.util.ArrayUtils.length; From b103676fb777971a6daf7c5222c9b80ba66b3dc8 Mon Sep 17 00:00:00 2001 From: Mercy Ma Date: Sat, 30 May 2026 17:15:27 +0800 Subject: [PATCH 4/4] Fix imports for concurrent queues in test Correct import statements in QueueUtilsTest: move ArrayBlockingQueue, DelayQueue and LinkedBlockingQueue imports to java.util.concurrent and tidy related imports. This fixes incorrect package references and prevents compilation issues in the test file. --- .../test/java/io/microsphere/collection/QueueUtilsTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/microsphere-java-core/src/test/java/io/microsphere/collection/QueueUtilsTest.java b/microsphere-java-core/src/test/java/io/microsphere/collection/QueueUtilsTest.java index 3e6543630..73bdefa18 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/collection/QueueUtilsTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/collection/QueueUtilsTest.java @@ -2,20 +2,20 @@ import org.junit.jupiter.api.Test; -import java.util.ArrayBlockingQueue; import java.util.ArrayDeque; import java.util.Collection; import java.util.Comparator; -import java.util.DelayQueue; import java.util.Deque; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedBlockingQueue; import java.util.NoSuchElementException; import java.util.PriorityQueue; import java.util.Queue; +import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.DelayQueue; import java.util.concurrent.Delayed; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedTransferQueue; import java.util.concurrent.PriorityBlockingQueue; import java.util.concurrent.SynchronousQueue;