Thread-safe concurrent collection implementations with atomic operations backed by ReadWriteLock. Provides concurrent variants of List, Map, Set, Deque, and Queue, plus tuple types (Pair, Triple, Single), sorted collection views, unmodifiable wrappers, and searchable/queryable interfaces.
Important
This library requires Java 21 or later. It is published via JitPack and is intended as a foundational dependency for other Simplified-Dev modules.
- Atomic bases -
AtomicCollection,AtomicList,AtomicSet,AtomicMap,AtomicQueue,AtomicDeque, plus the navigable basesAtomicNavigableSetandAtomicNavigableMap. Each directly implements its correspondingConcurrent*interface and is the canonical extension point for custom concurrent types. - Concurrent interfaces -
ConcurrentList,ConcurrentMap,ConcurrentSet,ConcurrentDeque, andConcurrentQueuewith thin nestedImplconstruction shims over the matchingAtomic*. - Linked variants -
ConcurrentLinkedList,ConcurrentLinkedMap,ConcurrentLinkedSetpreserving insertion order;ConcurrentLinkedMapsupports an optional eldest-entry eviction cap viawithMaxSize(int). - Tree variants -
ConcurrentTreeMapandConcurrentTreeSetfor sorted/navigable views over aTreeMap/TreeSet. - Unmodifiable wrappers - Immutable snapshots paired with a no-op lock for wait-free reads, available for every mutable variant via
toUnmodifiable().NoOpReadWriteLockisSerializableso snapshots round-trip through serialization without losing their lock semantics. - Static factories on every interface -
empty(),of(...),from(...),adopt(...)(zero-copy publication). List addswithCapacity(int); Tree variants addwithComparator(...);ConcurrentLinkedMapaddswithMaxSize(int). ReadWriteLock-based concurrency -withReadLock/withWriteLocklambda helpers onAtomicCollectionandAtomicMapwrap the lock + snapshot-invalidation pattern uniformly.- Tuple types -
Pair,Triple, andSinglewith mutable/immutable variants and streaming support (PairStream,TripleStream,SingleStream). - Searchable / Sortable interfaces - Generic query abstractions backing the search and sort surfaces.
Concurrentfactory - LegacyConcurrent.newList()/newMap()/ etc. style entry point; still supported alongside the per-interface statics.- Stream utilities -
StreamUtilfor enhanced stream operations. - Functional interfaces -
TriConsumer,TriFunction,TriPredicatefor three-argument operations.
| Requirement | Version | Notes |
|---|---|---|
| Java | 21+ | Required |
| Gradle | 9.4+ | Included via wrapper |
| Git | 2.x+ | For cloning the repository |
Add the JitPack repository and dependency to your build.gradle.kts:
repositories {
maven(url = "https://jitpack.io")
}
dependencies {
implementation("com.github.simplified-dev:collections:master-SNAPSHOT")
}Groovy DSL
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'com.github.simplified-dev:collections:master-SNAPSHOT'
}Maven
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependency>
<groupId>com.github.simplified-dev</groupId>
<artifactId>collections</artifactId>
<version>master-SNAPSHOT</version>
</dependency>Create thread-safe collections using either the per-interface static factories or the Concurrent utility:
import dev.simplified.collection.ConcurrentList;
import dev.simplified.collection.ConcurrentMap;
import dev.simplified.collection.ConcurrentSet;
import dev.simplified.collection.ConcurrentTreeMap;
// Static factories on each interface
ConcurrentList<String> list = ConcurrentList.empty();
ConcurrentList<String> seed = ConcurrentList.of("a", "b", "c");
ConcurrentMap<String, Integer> map = ConcurrentMap.from(existingMap);
ConcurrentSet<String> set = ConcurrentSet.empty();
ConcurrentTreeMap<String, Long> tree = ConcurrentTreeMap.withComparator(byPriority);
// Zero-copy publication of a single-threaded build result
ConcurrentList<String> adopted = ConcurrentList.adopt(prebuilt);
list.add("hello");
map.put("key", 42);
set.add("unique");Tip
All concurrent collections use ReadWriteLock internally, allowing multiple
concurrent readers while ensuring exclusive write access. Call
toUnmodifiable() on any mutable instance to take a wait-free immutable
snapshot backed by NoOpReadWriteLock.
Stream-friendly tuple abstractions with mutable and immutable variants:
import dev.simplified.collection.tuple.pair.Pair;
import dev.simplified.collection.tuple.pair.PairStream;
import dev.simplified.collection.tuple.triple.Triple;
// Immutable pair
Pair<String, Integer> pair = Pair.of("name", 42);
// Stream of pairs
PairStream.of(map)
.filter((key, value) -> value > 10)
.forEach((key, value) -> System.out.println(key + "=" + value));
// Triple
Triple<String, Integer, Boolean> triple = Triple.of("name", 42, true);collections/
├── src/
│ ├── main/java/dev/simplified/collection/
│ │ ├── atomic/ # AtomicCollection, AtomicList, AtomicSet, AtomicMap,
│ │ │ # AtomicQueue, AtomicDeque, AtomicNavigableSet,
│ │ │ # AtomicNavigableMap, AtomicIterator
│ │ ├── function/ # TriConsumer, TriFunction, TriPredicate
│ │ ├── query/ # Searchable, SearchFunction, Sortable, SortOrder
│ │ ├── sort/ # Graph (topological sort)
│ │ ├── tuple/
│ │ │ ├── pair/ # Pair, ImmutablePair, MutablePair, PairOptional, PairStream
│ │ │ ├── single/ # SingleStream
│ │ │ └── triple/ # Triple, ImmutableTriple, MutableTriple, TripleStream
│ │ ├── unmodifiable/ # ConcurrentUnmodifiable{Collection,List,Set,Map,Queue,Deque,
│ │ │ # LinkedList,LinkedSet,LinkedMap,TreeSet,TreeMap},
│ │ │ # NoOpReadWriteLock
│ │ ├── Concurrent.java # Factory for creating concurrent collections
│ │ ├── ConcurrentCollection.java
│ │ ├── ConcurrentList.java, ConcurrentSet.java, ConcurrentMap.java
│ │ ├── ConcurrentQueue.java, ConcurrentDeque.java
│ │ ├── ConcurrentLinkedList.java, ConcurrentLinkedSet.java, ConcurrentLinkedMap.java
│ │ ├── ConcurrentTreeSet.java, ConcurrentTreeMap.java
│ │ └── StreamUtil.java # Stream utility methods
│ ├── test/java/ # JUnit 5 tests (ConcurrentListTest, ConcurrentMapTest, etc.)
│ └── jmh/java/ # JMH benchmarks (list, map contention benchmarks)
├── build.gradle.kts
├── settings.gradle.kts
└── LICENSE.md
Build the project using the Gradle wrapper:
./gradlew build# Run standard unit tests (excludes slow tests)
./gradlew test
# Run slow integration tests (shutdown, thread leak detection)
./gradlew slowTestNote
The default test task excludes tests tagged with @Tag("slow").
Use slowTest to run long-running integration tests separately.
Run JMH benchmarks for concurrent collection performance:
./gradlew jmhBenchmarks cover list operations, map operations, and contention scenarios under concurrent access.
See CONTRIBUTING.md for development setup, code style guidelines, and how to submit a pull request.
This project is licensed under the Apache License 2.0 - see LICENSE.md for the full text.