diff --git a/core-java-modules/core-java-collections/README.md b/core-java-modules/core-java-collections/README.md
new file mode 100644
index 0000000000..574f61ac6a
--- /dev/null
+++ b/core-java-modules/core-java-collections/README.md
@@ -0,0 +1,16 @@
+## Core Java Collections
+
+This module contains articles about Java collections
+
+### Relevant Articles:
+- [Introduction to the Java ArrayDeque](https://www.baeldung.com/java-array-deque)
+- [An Introduction to Java.util.Hashtable Class](https://www.baeldung.com/java-hash-table)
+- [Thread Safe LIFO Data Structure Implementations](https://www.baeldung.com/java-lifo-thread-safe)
+- [Time Complexity of Java Collections](https://www.baeldung.com/java-collections-complexity)
+- [A Guide to EnumMap](https://www.baeldung.com/java-enum-map)
+- [A Guide to Iterator in Java](https://www.baeldung.com/java-iterator)
+- [Defining a Char Stack in Java](https://www.baeldung.com/java-char-stack)
+- [Guide to the Java Queue Interface](https://www.baeldung.com/java-queue)
+- [An Introduction to Synchronized Java Collections](https://www.baeldung.com/java-synchronized-collections)
+- [Convert an Array of Primitives to a List](https://www.baeldung.com/java-primitive-array-to-list)
+- More articles: [[next -->]](/core-java-modules/core-java-collections-2)
diff --git a/core-java-modules/core-java-collections/pom.xml b/core-java-modules/core-java-collections/pom.xml
new file mode 100644
index 0000000000..3c5c70af82
--- /dev/null
+++ b/core-java-modules/core-java-collections/pom.xml
@@ -0,0 +1,36 @@
+
+
+ 4.0.0
+ core-java-collections
+ 0.1.0-SNAPSHOT
+ core-java-collections
+ jar
+
+
+ com.ossez.core-java-modules
+ core-java-modules
+ 0.0.2-SNAPSHOT
+
+
+
+
+
+ org.openjdk.jmh
+ jmh-core
+ ${jmh-core.version}
+
+
+ org.openjdk.jmh
+ jmh-generator-annprocess
+ ${jmh-generator.version}
+
+
+ org.apache.commons
+ commons-lang3
+ ${commons-lang3.version}
+
+
+
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-collections/src/main/java/com/ossez/charstack/CharStack.java b/core-java-modules/core-java-collections/src/main/java/com/ossez/charstack/CharStack.java
new file mode 100644
index 0000000000..24b2a6d387
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/main/java/com/ossez/charstack/CharStack.java
@@ -0,0 +1,37 @@
+package com.ossez.charstack;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+public class CharStack {
+
+ private LinkedList items;
+
+ public CharStack() {
+ this.items = new LinkedList();
+ }
+
+ public void push(Character item) {
+ items.push(item);
+ }
+
+ public Character peek() {
+ return items.getFirst();
+ }
+
+ public Character pop() {
+
+ Iterator iter = items.iterator();
+ Character item = iter.next();
+ if (item != null) {
+ iter.remove();
+ return item;
+ }
+ return null;
+ }
+
+ public int size() {
+ return items.size();
+ }
+
+}
diff --git a/core-java-modules/core-java-collections/src/main/java/com/ossez/charstack/CharStackWithArray.java b/core-java-modules/core-java-collections/src/main/java/com/ossez/charstack/CharStackWithArray.java
new file mode 100644
index 0000000000..2780db0cb2
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/main/java/com/ossez/charstack/CharStackWithArray.java
@@ -0,0 +1,48 @@
+package com.ossez.charstack;
+
+public class CharStackWithArray {
+
+ private char[] elements;
+ private int size;
+
+ public CharStackWithArray() {
+ size = 0;
+ elements = new char[4];
+ }
+
+ public int size() {
+ return size;
+ }
+
+ public char peek() {
+ if (size == 0) {
+ throw new EmptyStackException();
+ }
+ return elements[size - 1];
+ }
+
+ public char pop() {
+ if (size == 0) {
+ throw new EmptyStackException();
+ }
+
+ return elements[--size];
+ }
+
+ public void push(char item) {
+ ensureCapacity(size + 1);
+ elements[size] = item;
+ size++;
+ }
+
+ private void ensureCapacity(int newSize) {
+ char newBiggerArray[];
+
+ if (elements.length < newSize) {
+ newBiggerArray = new char[elements.length * 2];
+ System.arraycopy(elements, 0, newBiggerArray, 0, size);
+ elements = newBiggerArray;
+ }
+ }
+
+}
diff --git a/core-java-modules/core-java-collections/src/main/java/com/ossez/charstack/EmptyStackException.java b/core-java-modules/core-java-collections/src/main/java/com/ossez/charstack/EmptyStackException.java
new file mode 100644
index 0000000000..968a3ee213
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/main/java/com/ossez/charstack/EmptyStackException.java
@@ -0,0 +1,9 @@
+package com.ossez.charstack;
+
+public class EmptyStackException extends RuntimeException {
+
+ public EmptyStackException() {
+ super("Stack is empty");
+ }
+
+}
diff --git a/core-java-modules/core-java-collections/src/main/java/com/ossez/collections/convertarrayprimitives/ConvertPrimitivesArrayToList.java b/core-java-modules/core-java-collections/src/main/java/com/ossez/collections/convertarrayprimitives/ConvertPrimitivesArrayToList.java
new file mode 100644
index 0000000000..bb0fc4bf22
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/main/java/com/ossez/collections/convertarrayprimitives/ConvertPrimitivesArrayToList.java
@@ -0,0 +1,49 @@
+package com.ossez.collections.convertarrayprimitives;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import org.apache.commons.lang3.ArrayUtils;
+
+import com.google.common.primitives.Ints;
+
+public class ConvertPrimitivesArrayToList {
+
+ public static void failConvert() {
+ int[] input = new int[]{1,2,3,4};
+ // List inputAsList = Arrays.asList(input);
+ }
+
+ public static List iterateConvert(int[] input) {
+ List output = new ArrayList();
+ for (int value : input) {
+ output.add(value);
+ }
+ return output;
+ }
+
+ public static List streamConvert(int[] input) {
+ List output = Arrays.stream(input).boxed().collect(Collectors.toList());
+ return output;
+ }
+
+ public static List streamConvertIntStream(int[] input) {
+ List output = IntStream.of(input).boxed().collect(Collectors.toList());
+ return output;
+ }
+
+ public static List guavaConvert(int[] input) {
+ List output = Ints.asList(input);
+ return output;
+ }
+
+ public static List apacheCommonConvert(int[] input) {
+ Integer[] outputBoxed = ArrayUtils.toObject(input);
+ List output = Arrays.asList(outputBoxed);
+ return output;
+ }
+
+}
diff --git a/core-java-modules/core-java-collections/src/main/java/com/ossez/hashtable/Word.java b/core-java-modules/core-java-collections/src/main/java/com/ossez/hashtable/Word.java
new file mode 100644
index 0000000000..ddeeea24d8
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/main/java/com/ossez/hashtable/Word.java
@@ -0,0 +1,28 @@
+package com.ossez.hashtable;
+
+public class Word {
+ private String name;
+
+ public Word(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public boolean equals(Object o) {
+ if (o == this)
+ return true;
+ if (!(o instanceof Word))
+ return false;
+
+ Word word = (Word) o;
+ return word.getName().equals(this.name) ? true : false;
+
+ }
+
+ public int hashCode() {
+ return name.hashCode();
+ }
+}
diff --git a/core-java-modules/core-java-collections/src/main/java/com/ossez/iteratorguide/IteratorGuide.java b/core-java-modules/core-java-collections/src/main/java/com/ossez/iteratorguide/IteratorGuide.java
new file mode 100644
index 0000000000..91d4b27024
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/main/java/com/ossez/iteratorguide/IteratorGuide.java
@@ -0,0 +1,39 @@
+package com.ossez.iteratorguide;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+public class IteratorGuide {
+
+ public static void main(String[] args) {
+ List items = new ArrayList<>();
+ items.add("ONE");
+ items.add("TWO");
+ items.add("THREE");
+ Iterator iter = items.iterator();
+ while (iter.hasNext()) {
+ String next = iter.next();
+ System.out.println(next);
+ iter.remove();
+ }
+ ListIterator listIterator = items.listIterator();
+ while(listIterator.hasNext()) {
+ String nextWithIndex = items.get(listIterator.nextIndex());
+ String next = listIterator.next();
+ if( "ONE".equals(next)) {
+ listIterator.set("SWAPPED");
+ }
+ }
+ listIterator.add("FOUR");
+ while(listIterator.hasPrevious()) {
+ String previousWithIndex = items.get(listIterator.previousIndex());
+ String previous = listIterator.previous();
+ System.out.println(previous);
+ }
+ listIterator.forEachRemaining(e -> {
+ System.out.println(e);
+ });
+ }
+}
diff --git a/core-java-modules/core-java-collections/src/main/java/com/ossez/performance/CopyOnWriteBenchmark.java b/core-java-modules/core-java-collections/src/main/java/com/ossez/performance/CopyOnWriteBenchmark.java
new file mode 100644
index 0000000000..4479263d0c
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/main/java/com/ossez/performance/CopyOnWriteBenchmark.java
@@ -0,0 +1,78 @@
+package com.ossez.performance;
+
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@Warmup(iterations = 10)
+public class CopyOnWriteBenchmark {
+
+ @State(Scope.Thread)
+ public static class MyState {
+
+ CopyOnWriteArrayList employeeList = new CopyOnWriteArrayList<>();
+
+ long iterations = 100000;
+
+ Employee employee = new Employee(100L, "Harry");
+
+ int employeeIndex = -1;
+
+ @Setup(Level.Trial)
+ public void setUp() {
+ for (long i = 0; i < iterations; i++) {
+ employeeList.add(new Employee(i, "John"));
+ }
+
+ employeeList.add(employee);
+
+ employeeIndex = employeeList.indexOf(employee);
+ }
+ }
+
+ @Benchmark
+ public void testAdd(CopyOnWriteBenchmark.MyState state) {
+ state.employeeList.add(new Employee(state.iterations + 1, "John"));
+ }
+
+ @Benchmark
+ public void testAddAt(CopyOnWriteBenchmark.MyState state) {
+ state.employeeList.add((int) (state.iterations), new Employee(state.iterations, "John"));
+ }
+
+ @Benchmark
+ public boolean testContains(CopyOnWriteBenchmark.MyState state) {
+ return state.employeeList.contains(state.employee);
+ }
+
+ @Benchmark
+ public int testIndexOf(CopyOnWriteBenchmark.MyState state) {
+ return state.employeeList.indexOf(state.employee);
+ }
+
+ @Benchmark
+ public Employee testGet(CopyOnWriteBenchmark.MyState state) {
+ return state.employeeList.get(state.employeeIndex);
+ }
+
+ @Benchmark
+ public boolean testRemove(CopyOnWriteBenchmark.MyState state) {
+ return state.employeeList.remove(state.employee);
+ }
+
+
+ public static void main(String[] args) throws Exception {
+ Options options = new OptionsBuilder()
+ .include(CopyOnWriteBenchmark.class.getSimpleName()).threads(1)
+ .forks(1).shouldFailOnError(true)
+ .shouldDoGC(true)
+ .jvmArgs("-server").build();
+ new Runner(options).run();
+ }
+}
diff --git a/core-java-modules/core-java-collections/src/main/java/com/ossez/performance/Employee.java b/core-java-modules/core-java-collections/src/main/java/com/ossez/performance/Employee.java
new file mode 100644
index 0000000000..286ab79c09
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/main/java/com/ossez/performance/Employee.java
@@ -0,0 +1,55 @@
+package com.ossez.performance;
+
+public class Employee {
+
+ private Long id;
+ private String name;
+
+ public Employee(Long id, String name) {
+ this.name = name;
+ this.id = id;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Employee employee = (Employee) o;
+
+ if (!id.equals(employee.id)) return false;
+ return name.equals(employee.name);
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = id.hashCode();
+ result = 31 * result + name.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "Employee{" +
+ "id=" + id +
+ ", name='" + name + '\'' +
+ '}';
+ }
+}
diff --git a/core-java-modules/core-java-collections/src/main/java/com/ossez/performance/HashMapBenchmark.java b/core-java-modules/core-java-collections/src/main/java/com/ossez/performance/HashMapBenchmark.java
new file mode 100644
index 0000000000..f4c4a65491
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/main/java/com/ossez/performance/HashMapBenchmark.java
@@ -0,0 +1,73 @@
+package com.ossez.performance;
+
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@Warmup(iterations = 10)
+public class HashMapBenchmark {
+
+ @State(Scope.Thread)
+ public static class MyState {
+
+ Map employeeMap = new HashMap<>();
+ //LinkedHashMap employeeMap = new LinkedHashMap<>();
+ //IdentityHashMap employeeMap = new IdentityHashMap<>();
+ //WeakHashMap employeeMap = new WeakHashMap<>();
+ //ConcurrentHashMap employeeMap = new ConcurrentHashMap<>();
+ //ConcurrentSkipListMap employeeMap = new ConcurrentSkipListMap <>();
+
+ // TreeMap
+
+ long iterations = 100000;
+
+ Employee employee = new Employee(100L, "Harry");
+
+ int employeeIndex = -1;
+
+ @Setup(Level.Trial)
+ public void setUp() {
+ for (long i = 0; i < iterations; i++) {
+ employeeMap.put(i, new Employee(i, "John"));
+ }
+
+ //employeeMap.put(iterations, employee);
+ }
+ }
+
+ @Benchmark
+ public Employee testGet(HashMapBenchmark.MyState state) {
+ return state.employeeMap.get(state.iterations);
+ }
+
+ @Benchmark
+ public Employee testRemove(HashMapBenchmark.MyState state) {
+ return state.employeeMap.remove(state.iterations);
+ }
+
+ @Benchmark
+ public Employee testPut(HashMapBenchmark.MyState state) {
+ return state.employeeMap.put(state.employee.getId(), state.employee);
+ }
+
+ @Benchmark
+ public Boolean testContainsKey(HashMapBenchmark.MyState state) {
+ return state.employeeMap.containsKey(state.employee.getId());
+ }
+
+
+ public static void main(String[] args) throws Exception {
+ Options options = new OptionsBuilder()
+ .include(HashMapBenchmark.class.getSimpleName()).threads(1)
+ .forks(1).shouldFailOnError(true)
+ .shouldDoGC(true)
+ .jvmArgs("-server").build();
+ new Runner(options).run();
+ }
+}
diff --git a/core-java-modules/core-java-collections/src/main/java/com/ossez/performance/SetBenchMark.java b/core-java-modules/core-java-collections/src/main/java/com/ossez/performance/SetBenchMark.java
new file mode 100644
index 0000000000..23957e4b67
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/main/java/com/ossez/performance/SetBenchMark.java
@@ -0,0 +1,62 @@
+package com.ossez.performance;
+
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import java.util.LinkedHashSet;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@Warmup(iterations = 10)
+public class SetBenchMark {
+
+ @State(Scope.Thread)
+ public static class MyState {
+
+ //Set employeeSet = new HashSet<>();
+ LinkedHashSet employeeSet = new LinkedHashSet<>();
+ //ConcurrentSkipListSet employeeSet = new ConcurrentSkipListSet <>();
+
+ // TreeSetÂ
+
+ long iterations = 1000;
+ Employee employee = new Employee(100L, "Harry");
+
+ @Setup(Level.Trial)
+ public void setUp() {
+ for (long i = 0; i < iterations; i++) {
+ employeeSet.add(new Employee(i, "John"));
+ }
+
+ //employeeSet.add(employee);
+ }
+ }
+
+ @Benchmark
+ public boolean testAdd(SetBenchMark.MyState state) {
+ return state.employeeSet.add(state.employee);
+ }
+
+ @Benchmark
+ public Boolean testContains(SetBenchMark.MyState state) {
+ return state.employeeSet.contains(state.employee);
+ }
+
+ @Benchmark
+ public boolean testRemove(SetBenchMark.MyState state) {
+ return state.employeeSet.remove(state.employee);
+ }
+
+
+ public static void main(String[] args) throws Exception {
+ Options options = new OptionsBuilder()
+ .include(SetBenchMark.class.getSimpleName()).threads(1)
+ .forks(1).shouldFailOnError(true)
+ .shouldDoGC(true)
+ .jvmArgs("-server").build();
+ new Runner(options).run();
+ }
+}
diff --git a/core-java-modules/core-java-collections/src/main/java/com/ossez/queueInterface/CustomBaeldungQueue.java b/core-java-modules/core-java-collections/src/main/java/com/ossez/queueInterface/CustomBaeldungQueue.java
new file mode 100644
index 0000000000..65c2c09cde
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/main/java/com/ossez/queueInterface/CustomBaeldungQueue.java
@@ -0,0 +1,48 @@
+package com.ossez.queueInterface;
+
+import java.util.AbstractQueue;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+public class CustomBaeldungQueue extends AbstractQueue {
+
+ private LinkedList elements;
+
+ public CustomBaeldungQueue() {
+ this.elements = new LinkedList();
+ }
+
+ @Override
+ public Iterator iterator() {
+ return elements.iterator();
+ }
+
+ @Override
+ public int size() {
+ return elements.size();
+ }
+
+ @Override
+ public boolean offer(T t) {
+ if(t == null) return false;
+ elements.add(t);
+ return true;
+ }
+
+ @Override
+ public T poll() {
+
+ Iterator iter = elements.iterator();
+ T t = iter.next();
+ if(t != null){
+ iter.remove();
+ return t;
+ }
+ return null;
+ }
+
+ @Override
+ public T peek() {
+ return elements.getFirst();
+ }
+}
diff --git a/core-java-modules/core-java-collections/src/main/java/com/ossez/synchronizedcollections/Application.java b/core-java-modules/core-java-collections/src/main/java/com/ossez/synchronizedcollections/Application.java
new file mode 100644
index 0000000000..d1acf3daaa
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/main/java/com/ossez/synchronizedcollections/Application.java
@@ -0,0 +1,18 @@
+package com.ossez.synchronizedcollections;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.logging.Logger;
+
+public class Application {
+
+ private static final Logger LOGGER = Logger.getLogger(Application.class.getName());
+
+ public static void main(String[] args) throws InterruptedException {
+ List syncCollection = Collections.synchronizedList(Arrays.asList(1, 2, 3, 4, 5, 6));
+ synchronized (syncCollection) {
+ syncCollection.forEach((e) -> {LOGGER.info(e.toString());});
+ }
+ }
+}
diff --git a/core-java-modules/core-java-collections/src/main/java/com/ossez/thread_safe_lifo/DequeBasedSynchronizedStack.java b/core-java-modules/core-java-collections/src/main/java/com/ossez/thread_safe_lifo/DequeBasedSynchronizedStack.java
new file mode 100644
index 0000000000..4f835d6fc8
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/main/java/com/ossez/thread_safe_lifo/DequeBasedSynchronizedStack.java
@@ -0,0 +1,36 @@
+package com.ossez.thread_safe_lifo;
+
+import java.util.ArrayDeque;
+
+/**
+ * Deque Based Stack implementation.
+ */
+public class DequeBasedSynchronizedStack {
+
+ // Internal Deque which gets decorated for synchronization.
+ private ArrayDeque dequeStore = new ArrayDeque<>();
+
+ public DequeBasedSynchronizedStack(int initialCapacity) {
+ this.dequeStore = new ArrayDeque<>(initialCapacity);
+ }
+
+ public DequeBasedSynchronizedStack() {
+
+ }
+
+ public synchronized T pop() {
+ return this.dequeStore.pop();
+ }
+
+ public synchronized void push(T element) {
+ this.dequeStore.push(element);
+ }
+
+ public synchronized T peek() {
+ return this.dequeStore.peek();
+ }
+
+ public synchronized int size() {
+ return this.dequeStore.size();
+ }
+}
diff --git a/core-java-modules/core-java-collections/src/main/resources/logback.xml b/core-java-modules/core-java-collections/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-collections/src/test/java/com/ossez/arraydeque/ArrayDequeUnitTest.java b/core-java-modules/core-java-collections/src/test/java/com/ossez/arraydeque/ArrayDequeUnitTest.java
new file mode 100644
index 0000000000..a2be5eb520
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/test/java/com/ossez/arraydeque/ArrayDequeUnitTest.java
@@ -0,0 +1,50 @@
+package com.ossez.arraydeque;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+
+import static org.junit.Assert.*;
+import org.junit.Test;
+
+public class ArrayDequeUnitTest {
+
+ @Test
+ public void whenOffer_addsAtLast() {
+ final Deque deque = new ArrayDeque<>();
+
+ deque.offer("first");
+ deque.offer("second");
+
+ assertEquals("second", deque.getLast());
+ }
+
+ @Test
+ public void whenPoll_removesFirst() {
+ final Deque deque = new ArrayDeque<>();
+
+ deque.offer("first");
+ deque.offer("second");
+
+ assertEquals("first", deque.poll());
+ }
+
+ @Test
+ public void whenPush_addsAtFirst() {
+ final Deque deque = new ArrayDeque<>();
+
+ deque.push("first");
+ deque.push("second");
+
+ assertEquals("second", deque.getFirst());
+ }
+
+ @Test
+ public void whenPop_removesLast() {
+ final Deque deque = new ArrayDeque<>();
+
+ deque.push("first");
+ deque.push("second");
+
+ assertEquals("second", deque.pop());
+ }
+}
diff --git a/core-java-modules/core-java-collections/src/test/java/com/ossez/charstack/CharStackUnitTest.java b/core-java-modules/core-java-collections/src/test/java/com/ossez/charstack/CharStackUnitTest.java
new file mode 100644
index 0000000000..1b306cb5d3
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/test/java/com/ossez/charstack/CharStackUnitTest.java
@@ -0,0 +1,50 @@
+package com.ossez.charstack;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+public class CharStackUnitTest {
+
+ @Test
+ public void whenCharStackIsCreated_thenItHasSize0() {
+
+ CharStack charStack = new CharStack();
+
+ assertEquals(0, charStack.size());
+ }
+
+ @Test
+ public void givenEmptyCharStack_whenElementIsPushed_thenStackSizeisIncreased() {
+
+ CharStack charStack = new CharStack();
+
+ charStack.push('A');
+
+ assertEquals(1, charStack.size());
+ }
+
+ @Test
+ public void givenCharStack_whenElementIsPoppedFromStack_thenElementIsRemovedAndSizeChanges() {
+
+ CharStack charStack = new CharStack();
+ charStack.push('A');
+
+ char element = charStack.pop();
+
+ assertEquals('A', element);
+ assertEquals(0, charStack.size());
+ }
+
+ @Test
+ public void givenCharStack_whenElementIsPeeked_thenElementIsNotRemovedAndSizeDoesNotChange() {
+ CharStack charStack = new CharStack();
+ charStack.push('A');
+
+ char element = charStack.peek();
+
+ assertEquals('A', element);
+ assertEquals(1, charStack.size());
+ }
+
+}
diff --git a/core-java-modules/core-java-collections/src/test/java/com/ossez/charstack/CharStackUsingJavaUnitTest.java b/core-java-modules/core-java-collections/src/test/java/com/ossez/charstack/CharStackUsingJavaUnitTest.java
new file mode 100644
index 0000000000..f114dd6ea5
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/test/java/com/ossez/charstack/CharStackUsingJavaUnitTest.java
@@ -0,0 +1,53 @@
+package com.ossez.charstack;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Stack;
+
+import org.junit.jupiter.api.Test;
+
+public class CharStackUsingJavaUnitTest {
+
+ @Test
+ public void whenCharStackIsCreated_thenItHasSize0() {
+
+ Stack charStack = new Stack<>();
+
+ assertEquals(0, charStack.size());
+ }
+
+ @Test
+ public void givenEmptyCharStack_whenElementIsPushed_thenStackSizeisIncreased() {
+
+ Stack charStack = new Stack<>();
+
+ charStack.push('A');
+
+ assertEquals(1, charStack.size());
+ }
+
+ @Test
+ public void givenCharStack_whenElementIsPoppedFromStack_thenElementIsRemovedAndSizeChanges() {
+
+ Stack charStack = new Stack<>();
+ charStack.push('A');
+
+ char element = charStack.pop();
+
+ assertEquals('A', element);
+ assertEquals(0, charStack.size());
+ }
+
+ @Test
+ public void givenCharStack_whenElementIsPeeked_thenElementIsNotRemovedAndSizeDoesNotChange() {
+
+ Stack charStack = new Stack<>();
+ charStack.push('A');
+
+ char element = charStack.peek();
+
+ assertEquals('A', element);
+ assertEquals(1, charStack.size());
+ }
+
+}
diff --git a/core-java-modules/core-java-collections/src/test/java/com/ossez/charstack/CharStackWithArrayUnitTest.java b/core-java-modules/core-java-collections/src/test/java/com/ossez/charstack/CharStackWithArrayUnitTest.java
new file mode 100644
index 0000000000..d0fdf43f57
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/test/java/com/ossez/charstack/CharStackWithArrayUnitTest.java
@@ -0,0 +1,65 @@
+package com.ossez.charstack;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+public class CharStackWithArrayUnitTest {
+
+ @Test
+ public void whenCharStackIsCreated_thenItHasSize0() {
+
+ CharStackWithArray charStack = new CharStackWithArray();
+
+ assertEquals(0, charStack.size());
+ }
+
+ @Test
+ public void givenEmptyCharStack_whenElementIsPushed_thenStackSizeisIncreased() {
+
+ CharStackWithArray charStack = new CharStackWithArray();
+
+ charStack.push('A');
+
+ assertEquals(1, charStack.size());
+ }
+
+ @Test
+ public void givenEmptyCharStack_when5ElementIsPushed_thenStackSizeis() {
+
+ CharStackWithArray charStack = new CharStackWithArray();
+
+ charStack.push('A');
+ charStack.push('B');
+ charStack.push('C');
+ charStack.push('D');
+ charStack.push('E');
+
+ assertEquals(5, charStack.size());
+ }
+
+ @Test
+ public void givenCharStack_whenElementIsPoppedFromStack_thenElementIsRemovedAndSizeChanges() {
+
+ CharStackWithArray charStack = new CharStackWithArray();
+ charStack.push('A');
+
+ char element = charStack.pop();
+
+ assertEquals('A', element);
+ assertEquals(0, charStack.size());
+ }
+
+ @Test
+ public void givenCharStack_whenElementIsPeeked_thenElementIsNotRemovedAndSizeDoesNotChange() {
+
+ CharStackWithArray charStack = new CharStackWithArray();
+ charStack.push('A');
+
+ char element = charStack.peek();
+
+ assertEquals('A', element);
+ assertEquals(1, charStack.size());
+ }
+
+}
diff --git a/core-java-modules/core-java-collections/src/test/java/com/ossez/collections/convertarrayprimitives/ConvertPrimitivesArrayToListUnitTest.java b/core-java-modules/core-java-collections/src/test/java/com/ossez/collections/convertarrayprimitives/ConvertPrimitivesArrayToListUnitTest.java
new file mode 100644
index 0000000000..ec4474fa61
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/test/java/com/ossez/collections/convertarrayprimitives/ConvertPrimitivesArrayToListUnitTest.java
@@ -0,0 +1,35 @@
+package com.ossez.collections.convertarrayprimitives;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+
+import org.junit.Test;
+
+public class ConvertPrimitivesArrayToListUnitTest {
+
+ @Test
+ public void givenArrayWithPrimitives_whenIterativeConvert_thenArrayGetsConverted() {
+ assertEquals(Arrays.asList(1,2,3,4), ConvertPrimitivesArrayToList.iterateConvert(new int[]{1,2,3,4}));
+ }
+
+ @Test
+ public void givenArrayWithPrimitives_whenStreamConvert_thenArrayGetsConverted() {
+ assertEquals(Arrays.asList(1,2,3,4), ConvertPrimitivesArrayToList.streamConvert(new int[]{1,2,3,4}));
+ }
+
+ @Test
+ public void givenArrayWithPrimitives_whenIntStreamConvert_thenArrayGetsConverted() {
+ assertEquals(Arrays.asList(1,2,3,4), ConvertPrimitivesArrayToList.streamConvertIntStream(new int[]{1,2,3,4}));
+ }
+
+ @Test
+ public void givenArrayWithPrimitives_whenGuavaConvert_thenArrayGetsConverted() {
+ assertEquals(Arrays.asList(1,2,3,4), ConvertPrimitivesArrayToList.guavaConvert(new int[]{1,2,3,4}));
+ }
+
+ @Test
+ public void givenArrayWithPrimitives_whenApacheCommonConvert_thenArrayGetsConverted() {
+ assertEquals(Arrays.asList(1,2,3,4), ConvertPrimitivesArrayToList.apacheCommonConvert(new int[]{1,2,3,4}));
+ }
+}
diff --git a/core-java-modules/core-java-collections/src/test/java/com/ossez/enummap/DummyEnum.java b/core-java-modules/core-java-collections/src/test/java/com/ossez/enummap/DummyEnum.java
new file mode 100644
index 0000000000..614e818352
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/test/java/com/ossez/enummap/DummyEnum.java
@@ -0,0 +1,13 @@
+package com.ossez.enummap;
+
+/**
+ * This enum is used for benchmarking, therefore has many values.
+ */
+public enum DummyEnum {
+ CCC_000,
+ CCC_001,CCC_002,CCC_003,CCC_004,CCC_005,CCC_006,CCC_007,CCC_008,CCC_009,CCC_010,
+ CCC_011,CCC_012,CCC_013,CCC_014,CCC_015,CCC_016,CCC_017,CCC_018,CCC_019,CCC_020,
+ CCC_021,CCC_022,CCC_023,CCC_024,CCC_025,CCC_026,CCC_027,CCC_028,CCC_029,CCC_030,
+ CCC_031,CCC_032,CCC_033,CCC_034,CCC_035,CCC_036,CCC_037,CCC_038,CCC_039,CCC_040,
+ CCC_041,CCC_042,CCC_043,CCC_044,CCC_045,CCC_046,CCC_047,CCC_048,CCC_049,
+}
diff --git a/core-java-modules/core-java-collections/src/test/java/com/ossez/enummap/EnumMapBenchmarkLiveTest.java b/core-java-modules/core-java-collections/src/test/java/com/ossez/enummap/EnumMapBenchmarkLiveTest.java
new file mode 100644
index 0000000000..5de9563b39
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/test/java/com/ossez/enummap/EnumMapBenchmarkLiveTest.java
@@ -0,0 +1,119 @@
+package com.ossez.enummap;
+
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode({ Mode.AverageTime })
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+public class EnumMapBenchmarkLiveTest {
+
+ @State(Scope.Thread)
+ public static class BenchmarkState {
+ EnumMap enumMap = new EnumMap<>(DummyEnum.class);
+ HashMap hashMap = new HashMap<>();
+ TreeMap treeMap = new TreeMap<>();
+ int len = DummyEnum.values().length;
+ Random random = new Random();
+ int randomIndex;
+
+ @Setup(Level.Trial)
+ public void setUp() {
+ DummyEnum[] values = DummyEnum.values();
+ for (int i = 0; i < len; i++) {
+ enumMap.put(values[i], values[i].toString());
+ hashMap.put(values[i], values[i].toString());
+ treeMap.put(values[i], values[i].toString());
+ }
+ }
+
+ @Setup(Level.Invocation)
+ public void additionalSetup() {
+ randomIndex = random.nextInt(len);
+ }
+
+ }
+
+ @Benchmark
+ public int benchmark01_EnumMapPut(BenchmarkState s) {
+ s.enumMap.put(DummyEnum.values()[s.randomIndex], DummyEnum.values()[s.randomIndex].toString());
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark01_HashMapPut(BenchmarkState s) {
+ s.hashMap.put(DummyEnum.values()[s.randomIndex], DummyEnum.values()[s.randomIndex].toString());
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark01_TreeMapPut(BenchmarkState s) {
+ s.treeMap.put(DummyEnum.values()[s.randomIndex], DummyEnum.values()[s.randomIndex].toString());
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark02_EnumMapGet(BenchmarkState s) {
+ s.enumMap.get(DummyEnum.values()[s.randomIndex]);
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark02_HashMapGet(BenchmarkState s) {
+ s.hashMap.get(DummyEnum.values()[s.randomIndex]);
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark02_TreeMapGet(BenchmarkState s) {
+ s.treeMap.get(DummyEnum.values()[s.randomIndex]);
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark03_EnumMapContainsKey(BenchmarkState s) {
+ s.enumMap.containsKey(DummyEnum.values()[s.randomIndex]);
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark03_HashMapContainsKey(BenchmarkState s) {
+ s.hashMap.containsKey(DummyEnum.values()[s.randomIndex]);
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark03_TreeMapContainsKey(BenchmarkState s) {
+ s.treeMap.containsKey(DummyEnum.values()[s.randomIndex]);
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark04_EnumMapContainsValue(BenchmarkState s) {
+ s.enumMap.containsValue(DummyEnum.values()[s.randomIndex].toString());
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark04_HashMapContainsValue(BenchmarkState s) {
+ s.hashMap.containsValue(DummyEnum.values()[s.randomIndex].toString());
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark04_TreeMapContainsValue(BenchmarkState s) {
+ s.treeMap.containsValue(DummyEnum.values()[s.randomIndex].toString());
+ return ++s.randomIndex;
+ }
+
+ public static void main(String[] args) throws Exception {
+ Options options = new OptionsBuilder().include(EnumMapBenchmarkLiveTest.class.getSimpleName()).threads(1).forks(0).shouldFailOnError(true).shouldDoGC(false).jvmArgs("-server").build();
+ new Runner(options).run();
+ }
+}
diff --git a/core-java-modules/core-java-collections/src/test/java/com/ossez/enummap/EnumMapUnitTest.java b/core-java-modules/core-java-collections/src/test/java/com/ossez/enummap/EnumMapUnitTest.java
new file mode 100644
index 0000000000..80e8273a39
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/test/java/com/ossez/enummap/EnumMapUnitTest.java
@@ -0,0 +1,144 @@
+package com.ossez.enummap;
+
+import org.junit.Test;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+import static java.util.AbstractMap.SimpleEntry;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+
+public class EnumMapUnitTest {
+ public enum DayOfWeek {
+ MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
+ }
+
+ @Test
+ public void whenContructedWithEnumType_ThenOnlyAcceptThatAsKey() {
+ Map dayMap = new EnumMap<>(DayOfWeek.class);
+ assertThatCode(
+ () -> dayMap.put(TimeUnit.NANOSECONDS, "NANOSECONDS"))
+ .isInstanceOf(ClassCastException.class);
+ }
+
+ @Test
+ public void whenConstructedWithEnumMap_ThenSameKeyTypeAndInitialMappings() {
+ EnumMap activityMap = new EnumMap<>(DayOfWeek.class);
+ activityMap.put(DayOfWeek.MONDAY, "Soccer");
+ activityMap.put(DayOfWeek.TUESDAY, "Basketball");
+
+ EnumMap activityMapCopy = new EnumMap<>(activityMap);
+ assertThat(activityMapCopy.size()).isEqualTo(2);
+ assertThat(activityMapCopy.get(DayOfWeek.MONDAY))
+ .isEqualTo("Soccer");
+ assertThat(activityMapCopy.get(DayOfWeek.TUESDAY))
+ .isEqualTo("Basketball");
+ }
+
+ @Test
+ public void givenEmptyMap_whenConstructedWithMap_ThenException() {
+ HashMap ordinaryMap = new HashMap();
+ assertThatCode(() -> new EnumMap(ordinaryMap))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("Specified map is empty");
+ }
+
+ @Test
+ public void givenMapWithEntries_whenConstructedWithMap_ThenSucceed() {
+ HashMap ordinaryMap = new HashMap<>();
+ ordinaryMap.put(DayOfWeek.MONDAY, "Soccer");
+ ordinaryMap.put(DayOfWeek.TUESDAY, "Basketball");
+ EnumMap enumMap = new EnumMap<>(ordinaryMap);
+ assertThat(enumMap.size()).isEqualTo(2);
+ assertThat(enumMap.get(DayOfWeek.MONDAY)).isEqualTo("Soccer");
+ assertThat(enumMap.get(DayOfWeek.TUESDAY)).isEqualTo("Basketball");
+ }
+
+ @Test
+ public void givenMapWithMultiTypeEntries_whenConstructedWithMap_ThenException() {
+ HashMap ordinaryMap = new HashMap<>();
+ ordinaryMap.put(DayOfWeek.MONDAY, "Soccer");
+ ordinaryMap.put(TimeUnit.MILLISECONDS, "Other enum type");
+ assertThatCode(() -> new EnumMap(ordinaryMap))
+ .isInstanceOf(ClassCastException.class);
+ }
+
+ @Test
+ public void whenPut_thenGet() {
+ Map activityMap = new EnumMap(DayOfWeek.class);
+ activityMap.put(DayOfWeek.WEDNESDAY, "Hiking");
+ activityMap.put(DayOfWeek.THURSDAY, null);
+ assertThat(activityMap.get(DayOfWeek.WEDNESDAY)).isEqualTo("Hiking");
+ assertThat(activityMap.get(DayOfWeek.THURSDAY)).isNull();
+ }
+
+ @Test
+ public void givenMapping_whenContains_thenTrue() {
+ EnumMap activityMap = new EnumMap(DayOfWeek.class);
+ assertThat(activityMap.containsKey(DayOfWeek.WEDNESDAY)).isFalse();
+ assertThat(activityMap.containsValue("Hiking")).isFalse();
+ activityMap.put(DayOfWeek.WEDNESDAY, "Hiking");
+ assertThat(activityMap.containsKey(DayOfWeek.WEDNESDAY)).isTrue();
+ assertThat(activityMap.containsValue("Hiking")).isTrue();
+
+ assertThat(activityMap.containsKey(DayOfWeek.SATURDAY)).isFalse();
+ assertThat(activityMap.containsValue(null)).isFalse();
+ activityMap.put(DayOfWeek.SATURDAY, null);
+ assertThat(activityMap.containsKey(DayOfWeek.SATURDAY)).isTrue();
+ assertThat(activityMap.containsValue(null)).isTrue();
+ }
+
+ @Test
+ public void whenRemove_thenRemoved() {
+ EnumMap activityMap = new EnumMap(DayOfWeek.class);
+
+ activityMap.put(DayOfWeek.MONDAY, "Soccer");
+ assertThat(activityMap.remove(DayOfWeek.MONDAY)).isEqualTo("Soccer");
+ assertThat(activityMap.containsKey(DayOfWeek.MONDAY)).isFalse();
+
+ activityMap.put(DayOfWeek.MONDAY, "Soccer");
+ assertThat(activityMap.remove(DayOfWeek.MONDAY, "Hiking")).isEqualTo(false);
+ assertThat(activityMap.remove(DayOfWeek.MONDAY, "Soccer")).isEqualTo(true);
+ }
+
+ @Test
+ public void whenSubView_thenSubViewOrdered() {
+ EnumMap activityMap = new EnumMap(DayOfWeek.class);
+ activityMap.put(DayOfWeek.THURSDAY, "Karate");
+ activityMap.put(DayOfWeek.WEDNESDAY, "Hiking");
+ activityMap.put(DayOfWeek.MONDAY, "Soccer");
+
+ Collection values = activityMap.values();
+ assertThat(values).containsExactly("Soccer", "Hiking", "Karate");
+
+ Set keys = activityMap.keySet();
+ assertThat(keys)
+ .containsExactly(DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY,DayOfWeek.THURSDAY);
+
+ assertThat(activityMap.entrySet())
+ .containsExactly(
+ new SimpleEntry(DayOfWeek.MONDAY, "Soccer"),
+ new SimpleEntry(DayOfWeek.WEDNESDAY, "Hiking"),
+ new SimpleEntry(DayOfWeek.THURSDAY, "Karate"));
+ }
+
+ @Test
+ public void givenSubView_whenChange_thenReflected() {
+ EnumMap activityMap = new EnumMap(DayOfWeek.class);
+ activityMap.put(DayOfWeek.THURSDAY, "Karate");
+ activityMap.put(DayOfWeek.WEDNESDAY, "Hiking");
+ activityMap.put(DayOfWeek.MONDAY, "Soccer");
+
+ Collection values = activityMap.values();
+ assertThat(values).containsExactly("Soccer", "Hiking", "Karate");
+
+ activityMap.put(DayOfWeek.TUESDAY, "Basketball");
+ assertThat(values)
+ .containsExactly("Soccer", "Basketball", "Hiking", "Karate");
+
+ values.remove("Hiking");
+ assertThat(activityMap.containsKey(DayOfWeek.WEDNESDAY)).isFalse();
+ assertThat(activityMap.size()).isEqualTo(3);
+ }
+}
diff --git a/core-java-modules/core-java-collections/src/test/java/com/ossez/hashtable/HashtableUnitTest.java b/core-java-modules/core-java-collections/src/test/java/com/ossez/hashtable/HashtableUnitTest.java
new file mode 100644
index 0000000000..7e83b5af47
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/test/java/com/ossez/hashtable/HashtableUnitTest.java
@@ -0,0 +1,274 @@
+package com.ossez.hashtable;
+
+import java.util.ConcurrentModificationException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+
+import static org.junit.Assert.*;
+import static org.hamcrest.Matchers.*;
+import org.junit.Test;
+
+public class HashtableUnitTest {
+
+ @Test
+ public void whenPutAndGet_thenReturnsValue() {
+ Hashtable table = new Hashtable();
+
+ Word word = new Word("cat");
+ table.put(word, "an animal");
+
+ String definition = table.get(word);
+
+ assertEquals("an animal", definition);
+
+ definition = table.remove(word);
+
+ assertEquals("an animal", definition);
+ }
+
+ @Test
+ public void whenThesameInstanceOfKey_thenReturnsValue() {
+ Hashtable table = new Hashtable();
+ Word word = new Word("cat");
+ table.put(word, "an animal");
+ String extracted = table.get(word);
+ assertEquals("an animal", extracted);
+ }
+
+ @Test
+ public void whenEqualsOverridden_thenReturnsValue() {
+ Hashtable table = new Hashtable();
+ Word word = new Word("cat");
+ table.put(word, "an animal");
+ String extracted = table.get(new Word("cat"));
+ assertEquals("an animal", extracted);
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void whenNullKey_thenException() {
+ Hashtable table = new Hashtable();
+ table.put(null, "an animal");
+ }
+
+ @Test(expected = ConcurrentModificationException.class)
+ public void whenIterate_thenFailFast() {
+
+ Hashtable table = new Hashtable();
+ table.put(new Word("cat"), "an animal");
+ table.put(new Word("dog"), "another animal");
+
+ Iterator it = table.keySet().iterator();
+ System.out.println("iterator created");
+
+ table.remove(new Word("dog"));
+ System.out.println("element removed");
+
+ while (it.hasNext()) {
+ Word key = it.next();
+ System.out.println(table.get(key));
+ }
+ }
+
+ @Test
+ public void whenEnumerate_thenNotFailFast() {
+
+ Hashtable table = new Hashtable();
+ table.put(new Word("1"), "one");
+ table.put(new Word("2"), "two");
+ table.put(new Word("3"), "three");
+ table.put(new Word("4"), "four");
+ table.put(new Word("5"), "five");
+ table.put(new Word("6"), "six");
+ table.put(new Word("7"), "seven");
+ table.put(new Word("8"), "eight");
+
+ Enumeration enumKey = table.keys();
+ System.out.println("Enumeration created");
+ table.remove(new Word("1"));
+ System.out.println("element removed");
+ while (enumKey.hasMoreElements()) {
+ Word key = enumKey.nextElement();
+ System.out.println(table.get(key));
+ }
+ }
+
+ @Test
+ public void whenAddElements_thenIterationOrderUnpredicable() {
+
+ Hashtable table = new Hashtable();
+ table.put(new Word("1"), "one");
+ table.put(new Word("2"), "two");
+ table.put(new Word("3"), "three");
+ table.put(new Word("4"), "four");
+ table.put(new Word("5"), "five");
+ table.put(new Word("6"), "six");
+ table.put(new Word("7"), "seven");
+ table.put(new Word("8"), "eight");
+
+ Iterator> it = table.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry entry = it.next();
+ System.out.println(entry.getValue());
+ }
+ }
+
+ @Test
+ public void whenGetOrDefault_thenDefaultGot() {
+
+ Hashtable table = new Hashtable();
+ table.put(new Word("cat"), "a small domesticated carnivorous mammal");
+ Word key = new Word("dog");
+ String definition;
+
+ // old way
+ /* if (table.containsKey(key)) {
+ definition = table.get(key);
+ } else {
+ definition = "not found";
+ }*/
+
+ // new way
+ definition = table.getOrDefault(key, "not found");
+
+ assertThat(definition, is("not found"));
+ }
+
+ @Test
+ public void whenPutifAbsent_thenNotRewritten() {
+
+ Hashtable table = new Hashtable();
+ table.put(new Word("cat"), "a small domesticated carnivorous mammal");
+
+ String definition = "an animal";
+ // old way
+ /* if (!table.containsKey(new Word("cat"))) {
+ table.put(new Word("cat"), definition);
+ }*/
+ // new way
+ table.putIfAbsent(new Word("cat"), definition);
+
+ assertThat(table.get(new Word("cat")), is("a small domesticated carnivorous mammal"));
+ }
+
+ @Test
+ public void whenRemovePair_thenCheckKeyAndValue() {
+
+ Hashtable table = new Hashtable();
+ table.put(new Word("cat"), "a small domesticated carnivorous mammal");
+
+ // old way
+ /* if (table.get(new Word("cat")).equals("an animal")) {
+ table.remove(new Word("cat"));
+ }*/
+
+ // new way
+ boolean result = table.remove(new Word("cat"), "an animal");
+
+ assertThat(result, is(false));
+ }
+
+ @Test
+ public void whenReplacePair_thenValueChecked() {
+
+ Hashtable table = new Hashtable();
+ table.put(new Word("cat"), "a small domesticated carnivorous mammal");
+
+ String definition = "an animal";
+
+ // old way
+ /* if (table.containsKey(new Word("cat")) && table.get(new Word("cat")).equals("a small domesticated carnivorous mammal")) {
+ table.put(new Word("cat"), definition);
+ }*/
+ // new way
+ table.replace(new Word("cat"), "a small domesticated carnivorous mammal", definition);
+
+ assertThat(table.get(new Word("cat")), is("an animal"));
+
+ }
+
+ @Test
+ public void whenKeyIsAbsent_thenNotRewritten() {
+
+ Hashtable table = new Hashtable();
+ table.put(new Word("cat"), "a small domesticated carnivorous mammal");
+
+ // old way
+ /* if (!table.containsKey(cat)) {
+ String definition = "an animal";// calculate
+ table.put(new Word("cat"), definition);
+ }
+ */
+ // new way
+
+ table.computeIfAbsent(new Word("cat"), key -> "an animal");
+ assertThat(table.get(new Word("cat")), is("a small domesticated carnivorous mammal"));
+
+ }
+
+ @Test
+ public void whenKeyIsPresent_thenComputeIfPresent() {
+
+ Hashtable table = new Hashtable();
+ table.put(new Word("cat"), "a small domesticated carnivorous mammal");
+
+ Word cat = new Word("cat");
+ // old way
+ /* if (table.containsKey(cat)) {
+ String concatination = cat.getName() + " - " + table.get(cat);
+ table.put(cat, concatination);
+ }*/
+
+ // new way
+ table.computeIfPresent(cat, (key, value) -> key.getName() + " - " + value);
+
+ assertThat(table.get(cat), is("cat - a small domesticated carnivorous mammal"));
+
+ }
+
+ @Test
+ public void whenCompute_thenForAllKeys() {
+
+ Hashtable table = new Hashtable();
+ String[] animals = { "cat", "dog", "dog", "cat", "bird", "mouse", "mouse" };
+ for (String animal : animals) {
+ table.compute(animal, (key, value) -> (value == null ? 1 : value + 1));
+ }
+ assertThat(table.values(), hasItems(2, 2, 2, 1));
+
+ }
+
+ @Test
+ public void whenInsteadOfCompute_thenMerge() {
+
+ Hashtable table = new Hashtable();
+ String[] animals = { "cat", "dog", "dog", "cat", "bird", "mouse", "mouse" };
+ for (String animal : animals) {
+ table.merge(animal, 1, (oldValue, value) -> (oldValue + value));
+ }
+ assertThat(table.values(), hasItems(2, 2, 2, 1));
+ }
+
+ @Test
+ public void whenForeach_thenIterate() {
+
+ Hashtable table = new Hashtable();
+ table.put(new Word("cat"), "a small domesticated carnivorous mammal");
+ table.put(new Word("dog"), "another animal");
+ table.forEach((k, v) -> System.out.println(k.getName() + " - " + v)
+
+ );
+ }
+
+ @Test
+ public void whenReplaceall_thenNoIterationNeeded() {
+
+ Hashtable table = new Hashtable();
+ table.put(new Word("cat"), "a small domesticated carnivorous mammal");
+ table.put(new Word("dog"), "another animal");
+ table.replaceAll((k, v) -> k.getName() + " - " + v);
+
+ assertThat(table.values(), hasItems("cat - a small domesticated carnivorous mammal", "dog - another animal"));
+ }
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-collections/src/test/java/com/ossez/queueInterface/CustomBaeldungQueueUnitTest.java b/core-java-modules/core-java-collections/src/test/java/com/ossez/queueInterface/CustomBaeldungQueueUnitTest.java
new file mode 100644
index 0000000000..e57127aa49
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/test/java/com/ossez/queueInterface/CustomBaeldungQueueUnitTest.java
@@ -0,0 +1,30 @@
+package com.ossez.queueInterface;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class CustomBaeldungQueueUnitTest {
+
+ private CustomBaeldungQueue customQueue;
+
+ @Before
+ public void setUp() throws Exception {
+ customQueue = new CustomBaeldungQueue<>();
+ }
+
+ @Test
+ public void givenQueueWithTwoElements_whenElementsRetrieved_checkRetrievalCorrect() {
+
+ customQueue.add(7);
+ customQueue.add(5);
+
+ int first = customQueue.poll();
+ int second = customQueue.poll();
+
+ assertEquals(7, first);
+ assertEquals(5, second);
+
+ }
+}
diff --git a/core-java-modules/core-java-collections/src/test/java/com/ossez/queueInterface/PriorityQueueUnitTest.java b/core-java-modules/core-java-collections/src/test/java/com/ossez/queueInterface/PriorityQueueUnitTest.java
new file mode 100644
index 0000000000..6313ec1952
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/test/java/com/ossez/queueInterface/PriorityQueueUnitTest.java
@@ -0,0 +1,53 @@
+package com.ossez.queueInterface;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.PriorityQueue;
+
+import static org.junit.Assert.assertEquals;
+
+public class PriorityQueueUnitTest {
+
+
+
+ @Test
+ public void givenIntegerQueue_whenIntegersOutOfOrder_checkRetrievalOrderIsNatural() {
+
+ PriorityQueue integerQueue = new PriorityQueue<>();
+
+ integerQueue.add(9);
+ integerQueue.add(2);
+ integerQueue.add(4);
+
+ int first = integerQueue.poll();
+ int second = integerQueue.poll();
+ int third = integerQueue.poll();
+
+ assertEquals(2, first);
+ assertEquals(4, second);
+ assertEquals(9, third);
+
+
+ }
+
+ @Test
+ public void givenStringQueue_whenStringsAddedOutOfNaturalOrder_checkRetrievalOrderNatural() {
+
+ PriorityQueue stringQueue = new PriorityQueue<>();
+
+ stringQueue.add("banana");
+ stringQueue.add("apple");
+ stringQueue.add("cherry");
+
+ String first = stringQueue.poll();
+ String second = stringQueue.poll();
+ String third = stringQueue.poll();
+
+ assertEquals("apple", first);
+ assertEquals("banana", second);
+ assertEquals("cherry", third);
+
+
+ }
+}
diff --git a/core-java-modules/core-java-collections/src/test/java/com/ossez/stack_tests/MultithreadingCorrectnessStackUnitTest.java b/core-java-modules/core-java-collections/src/test/java/com/ossez/stack_tests/MultithreadingCorrectnessStackUnitTest.java
new file mode 100644
index 0000000000..f9f2a7e33a
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/test/java/com/ossez/stack_tests/MultithreadingCorrectnessStackUnitTest.java
@@ -0,0 +1,101 @@
+package com.ossez.stack_tests;
+
+import com.ossez.thread_safe_lifo.DequeBasedSynchronizedStack;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.ArrayDeque;
+import java.util.concurrent.ConcurrentLinkedDeque;
+
+import static java.util.stream.IntStream.range;
+
+/**
+ * Correctness tests for Stack in multi threaded environment.
+ */
+public class MultithreadingCorrectnessStackUnitTest {
+
+ @Test
+ public void givenSynchronizedDeque_whenExecutedParallel_thenWorkRight() {
+
+ DequeBasedSynchronizedStack deque = new DequeBasedSynchronizedStack<>();
+
+ // Serial execution of push on ConcurrentLinkedQueue will always result in correct execution.
+ range(1, 10000).forEach(value -> deque.push(value));
+
+ int sum = 0;
+ while(deque.peek() != null) {
+ sum += deque.pop();
+ }
+
+ Assert.assertEquals(49995000, sum);
+
+ // Parallel execution of push on ConcurrentLinkedQueue will always result in correct execution.
+ range(1, 10000).parallel().forEach(value -> deque.push(value));
+
+ sum = 0;
+ while(deque.peek() != null) {
+ sum += deque.pop();
+ }
+
+ Assert.assertEquals(49995000, sum);
+ }
+
+ @Test
+ public void givenConcurrentLinkedQueue_whenExecutedParallel_thenWorkRight() {
+
+ ConcurrentLinkedDeque deque = new ConcurrentLinkedDeque<>();
+
+ // Serial execution of push on ConcurrentLinkedQueue will always result in correct execution.
+ range(1, 10000).forEach(value -> deque.push(value));
+
+ int sum = 0;
+ while(deque.peek() != null) {
+ sum += deque.pop();
+ }
+
+ Assert.assertEquals(49995000, sum);
+
+ // Parallel execution of push on ConcurrentLinkedQueue will always result in correct execution.
+ range(1, 10000).parallel().forEach(value -> deque.push(value));
+
+ sum = 0;
+ while(deque.peek() != null) {
+ sum += deque.pop();
+ }
+
+ Assert.assertEquals(49995000, sum);
+ }
+
+ @Test
+ public void givenArrayDeque_whenExecutedParallel_thenShouldFail() {
+
+ ArrayDeque deque = new ArrayDeque<>();
+
+ // Serial execution of push on ArrayDeque will always result in correct execution.
+ range(1, 10000).forEach(value -> deque.push(value));
+
+ int sum = 0;
+ while(deque.peek() != null) {
+ sum += deque.pop();
+ }
+
+ Assert.assertEquals(49995000, sum);
+
+ // Parallel execution of push on ArrayDeque will not result in correct execution.
+ range(1, 10000).parallel().forEach(value -> deque.push(value));
+
+ sum = 0;
+ while(deque.peek() != null) {
+ sum += deque.pop();
+ }
+
+ // This shouldn't happen.
+ if(sum == 49995000) {
+ System.out.println("Something wrong in the environment, Please try some big value and check");
+ // To safe-guard build without test failures.
+ return;
+ }
+
+ Assert.assertNotEquals(49995000, sum);
+ }
+}
diff --git a/core-java-modules/core-java-collections/src/test/java/com/ossez/stack_tests/StackUnitTest.java b/core-java-modules/core-java-collections/src/test/java/com/ossez/stack_tests/StackUnitTest.java
new file mode 100644
index 0000000000..2df7c9f0f0
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/test/java/com/ossez/stack_tests/StackUnitTest.java
@@ -0,0 +1,56 @@
+package com.ossez.stack_tests;
+
+import com.ossez.thread_safe_lifo.DequeBasedSynchronizedStack;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Stack;
+import java.util.concurrent.ConcurrentLinkedDeque;
+
+/**
+ * These tests are to understand the Stack implementation in Java Collections.
+ */
+public class StackUnitTest {
+
+ @Test
+ public void givenStack_whenPushPopPeek_thenWorkRight() {
+ Stack namesStack = new Stack<>();
+
+ namesStack.push("Bill Gates");
+ namesStack.push("Elon Musk");
+
+ Assert.assertEquals("Elon Musk", namesStack.peek());
+ Assert.assertEquals("Elon Musk", namesStack.pop());
+ Assert.assertEquals("Bill Gates", namesStack.pop());
+
+ Assert.assertEquals(0, namesStack.size());
+ }
+
+ @Test
+ public void givenSynchronizedDeque_whenPushPopPeek_thenWorkRight() {
+ DequeBasedSynchronizedStack namesStack = new DequeBasedSynchronizedStack<>();
+
+ namesStack.push("Bill Gates");
+ namesStack.push("Elon Musk");
+
+ Assert.assertEquals("Elon Musk", namesStack.peek());
+ Assert.assertEquals("Elon Musk", namesStack.pop());
+ Assert.assertEquals("Bill Gates", namesStack.pop());
+
+ Assert.assertEquals(0, namesStack.size());
+ }
+
+ @Test
+ public void givenConcurrentLinkedDeque_whenPushPopPeek_thenWorkRight() {
+ ConcurrentLinkedDeque namesStack = new ConcurrentLinkedDeque<>();
+
+ namesStack.push("Bill Gates");
+ namesStack.push("Elon Musk");
+
+ Assert.assertEquals("Elon Musk", namesStack.peek());
+ Assert.assertEquals("Elon Musk", namesStack.pop());
+ Assert.assertEquals("Bill Gates", namesStack.pop());
+
+ Assert.assertEquals(0, namesStack.size());
+ }
+}
diff --git a/core-java-modules/core-java-collections/src/test/java/com/ossez/synchronizedcollections/SynchronizedCollectionUnitTest.java b/core-java-modules/core-java-collections/src/test/java/com/ossez/synchronizedcollections/SynchronizedCollectionUnitTest.java
new file mode 100644
index 0000000000..f3b6f73995
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/test/java/com/ossez/synchronizedcollections/SynchronizedCollectionUnitTest.java
@@ -0,0 +1,28 @@
+package com.ossez.synchronizedcollections;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class SynchronizedCollectionUnitTest {
+
+ @Test
+ public void givenSynchronizedCollection_whenTwoThreadsAddElements_thenCorrectCollectionSize() throws InterruptedException {
+ Collection syncCollection = Collections.synchronizedCollection(new ArrayList<>());
+
+ Runnable listOperations = () -> {
+ syncCollection.addAll(Arrays.asList(1, 2, 3, 4, 5, 6));
+ };
+ Thread thread1 = new Thread(listOperations);
+ Thread thread2 = new Thread(listOperations);
+ thread1.start();
+ thread2.start();
+ thread1.join();
+ thread2.join();
+
+ assertThat(syncCollection.size()).isEqualTo(12);
+ }
+}
diff --git a/core-java-modules/core-java-collections/src/test/java/com/ossez/synchronizedcollections/SynchronizedListUnitTest.java b/core-java-modules/core-java-collections/src/test/java/com/ossez/synchronizedcollections/SynchronizedListUnitTest.java
new file mode 100644
index 0000000000..8c6d0df831
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/test/java/com/ossez/synchronizedcollections/SynchronizedListUnitTest.java
@@ -0,0 +1,51 @@
+package com.ossez.synchronizedcollections;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import org.junit.Test;
+import static org.assertj.core.api.Assertions.*;
+
+public class SynchronizedListUnitTest {
+
+ @Test
+ public void givenSynchronizedList_whenTwoThreadsAddElements_thenCorrectListSize() throws InterruptedException {
+ List syncList = Collections.synchronizedList(new ArrayList<>());
+
+ Runnable listOperations = () -> {
+ syncList.addAll(Arrays.asList(1, 2, 3, 4, 5, 6));
+ };
+ Thread thread1 = new Thread(listOperations);
+ Thread thread2 = new Thread(listOperations);
+ thread1.start();
+ thread2.start();
+ thread1.join();
+ thread2.join();
+
+ assertThat(syncList.size()).isEqualTo(12);
+ }
+
+ @Test
+ public void givenStringList_whenTwoThreadsIterateOnSynchronizedList_thenCorrectResult() throws InterruptedException {
+ List syncCollection = Collections.synchronizedList(Arrays.asList("a", "b", "c"));
+ List uppercasedCollection = new ArrayList<>();
+
+ Runnable listOperations = () -> {
+ synchronized (syncCollection) {
+ syncCollection.forEach((e) -> {
+ uppercasedCollection.add(e.toUpperCase());
+ });
+ }
+ };
+
+ Thread thread1 = new Thread(listOperations);
+ Thread thread2 = new Thread(listOperations);
+ thread1.start();
+ thread2.start();
+ thread1.join();
+ thread2.join();
+
+ assertThat(uppercasedCollection.get(0)).isEqualTo("A");
+ }
+}
diff --git a/core-java-modules/core-java-collections/src/test/java/com/ossez/synchronizedcollections/SynchronizedMapUnitTest.java b/core-java-modules/core-java-collections/src/test/java/com/ossez/synchronizedcollections/SynchronizedMapUnitTest.java
new file mode 100644
index 0000000000..b543c9ac1b
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/test/java/com/ossez/synchronizedcollections/SynchronizedMapUnitTest.java
@@ -0,0 +1,30 @@
+package com.ossez.synchronizedcollections;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.Test;
+import static org.assertj.core.api.Assertions.*;
+
+public class SynchronizedMapUnitTest {
+
+ @Test
+ public void givenSynchronizedMap_whenTwoThreadsAddElements_thenCorrectMapSize() throws InterruptedException {
+ Map syncMap = Collections.synchronizedMap(new HashMap<>());
+
+ Runnable mapOperations = () -> {
+ syncMap.put(1, "one");
+ syncMap.put(2, "two");
+ syncMap.put(3, "three");
+
+ };
+ Thread thread1 = new Thread(mapOperations);
+ Thread thread2 = new Thread(mapOperations);
+ thread1.start();
+ thread2.start();
+ thread1.join();
+ thread2.join();
+
+ assertThat(syncMap.size()).isEqualTo(3);
+ }
+}
diff --git a/core-java-modules/core-java-collections/src/test/java/com/ossez/synchronizedcollections/SynchronizedSetUnitTest.java b/core-java-modules/core-java-collections/src/test/java/com/ossez/synchronizedcollections/SynchronizedSetUnitTest.java
new file mode 100644
index 0000000000..cb1be80114
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/test/java/com/ossez/synchronizedcollections/SynchronizedSetUnitTest.java
@@ -0,0 +1,26 @@
+package com.ossez.synchronizedcollections;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import org.junit.Test;
+import static org.assertj.core.api.Assertions.*;
+
+public class SynchronizedSetUnitTest {
+
+ @Test
+ public void givenSynchronizedSet_whenTwoThreadsAddElements_thenCorrectSetSize() throws InterruptedException {
+ Set syncSet = Collections.synchronizedSet(new HashSet<>());
+
+ Runnable setOperations = () -> {syncSet.addAll(Arrays.asList(1, 2, 3, 4, 5, 6));};
+ Thread thread1 = new Thread(setOperations);
+ Thread thread2 = new Thread(setOperations);
+ thread1.start();
+ thread2.start();
+ thread1.join();
+ thread2.join();
+
+ assertThat(syncSet.size()).isEqualTo(6);
+ }
+}
diff --git a/core-java-modules/core-java-collections/src/test/java/com/ossez/synchronizedcollections/SynchronizedSortedMapUnitTest.java b/core-java-modules/core-java-collections/src/test/java/com/ossez/synchronizedcollections/SynchronizedSortedMapUnitTest.java
new file mode 100644
index 0000000000..a3124a7005
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/test/java/com/ossez/synchronizedcollections/SynchronizedSortedMapUnitTest.java
@@ -0,0 +1,29 @@
+package com.ossez.synchronizedcollections;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.TreeMap;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class SynchronizedSortedMapUnitTest {
+
+ @Test
+ public void givenSynchronizedSorteMap_whenTwoThreadsAddElements_thenCorrectSortedMapSize() throws InterruptedException {
+ Map syncSortedMap = Collections.synchronizedSortedMap(new TreeMap<>());
+
+ Runnable sortedMapOperations = () -> {
+ syncSortedMap.put(1, "One");
+ syncSortedMap.put(2, "Two");
+ syncSortedMap.put(3, "Three");
+ };
+ Thread thread1 = new Thread(sortedMapOperations);
+ Thread thread2 = new Thread(sortedMapOperations);
+ thread1.start();
+ thread2.start();
+ thread1.join();
+ thread2.join();
+
+ assertThat(syncSortedMap.size()).isEqualTo(3);
+ }
+}
diff --git a/core-java-modules/core-java-collections/src/test/java/com/ossez/synchronizedcollections/SynchronizedSortedSetUnitTest.java b/core-java-modules/core-java-collections/src/test/java/com/ossez/synchronizedcollections/SynchronizedSortedSetUnitTest.java
new file mode 100644
index 0000000000..1877bebc52
--- /dev/null
+++ b/core-java-modules/core-java-collections/src/test/java/com/ossez/synchronizedcollections/SynchronizedSortedSetUnitTest.java
@@ -0,0 +1,28 @@
+package com.ossez.synchronizedcollections;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class SynchronizedSortedSetUnitTest {
+
+ @Test
+ public void givenSynchronizedSortedSet_whenTwoThreadsAddElements_thenCorrectSortedSetSize() throws InterruptedException {
+ SortedSet syncSortedSet = Collections.synchronizedSortedSet(new TreeSet<>());
+
+ Runnable sortedSetOperations = () -> {syncSortedSet.addAll(Arrays.asList(1, 2, 3, 4, 5, 6));};
+ sortedSetOperations.run();
+ sortedSetOperations.run();
+ Thread thread1 = new Thread(sortedSetOperations);
+ Thread thread2 = new Thread(sortedSetOperations);
+ thread1.start();
+ thread2.start();
+ thread1.join();
+ thread2.join();
+
+ assertThat(syncSortedSet.size()).isEqualTo(6);
+ }
+}