diff --git a/testing-modules/streams-ordering/pom.xml b/testing-modules/streams-ordering/pom.xml
new file mode 100644
index 0000000000..99d08e19be
--- /dev/null
+++ b/testing-modules/streams-ordering/pom.xml
@@ -0,0 +1,34 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ StreamsOrdering
+ 1.0-SNAPSHOT
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
+
+ org.openjdk.jmh
+ jmh-core
+ 1.21
+
+
+
+ org.openjdk.jmh
+ jmh-generator-annprocess
+ 1.21
+ provided
+
+
+
+
\ No newline at end of file
diff --git a/testing-modules/streams-ordering/src/test/java/StreamsOrderingTest.java b/testing-modules/streams-ordering/src/test/java/StreamsOrderingTest.java
new file mode 100644
index 0000000000..b657911780
--- /dev/null
+++ b/testing-modules/streams-ordering/src/test/java/StreamsOrderingTest.java
@@ -0,0 +1,148 @@
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import static org.junit.Assert.assertEquals;
+
+
+public class StreamsOrderingTest {
+
+ Logger logger = Logger.getLogger( StreamsOrderingTest.class.getName());
+
+ @Before
+ public void setUp() throws Exception {
+ logger.setLevel(Level.ALL);
+ }
+
+ @Test
+ public void givenTwoCollections_whenStreamed_thenCheckOutputDifferent(){
+
+ List list = Arrays.asList("B", "A", "C", "D", "F");
+ Set set = new TreeSet<>(Arrays.asList("B", "A", "C", "D", "F"));
+
+ Object[] listOutput = list.stream().toArray();
+ Object[] setOutput = set.stream().toArray();
+
+ assertEquals("[B, A, C, D, F]", Arrays.toString(listOutput));
+ assertEquals("[A, B, C, D, F]", Arrays.toString(setOutput));
+
+ }
+
+ @Test
+ public void givenTwoCollections_whenStreamedInParallel_thenCheckOutputDifferent(){
+
+ List list = Arrays.asList("B", "A", "C", "D", "F");
+ Set set = new TreeSet<>(Arrays.asList("B", "A", "C", "D", "F"));
+
+ Object[] listOutput = list.stream().parallel().toArray();
+ Object[] setOutput = set.stream().parallel().toArray();
+
+ assertEquals("[B, A, C, D, F]", Arrays.toString(listOutput));
+ assertEquals("[A, B, C, D, F]", Arrays.toString(setOutput));
+
+ }
+
+
+
+ @Test
+ public void givenOrderedInput_whenUnorderedAndOrderedCompared_thenCheckUnorderedOutputChanges(){
+ Set set = new TreeSet<>(
+ Arrays.asList(-9, -5, -4, -2, 1, 2, 4, 5, 7, 9, 12, 13, 16, 29, 23, 34, 57, 68, 90, 102, 230));
+
+ Object[] orderedArray = set.stream()
+ .parallel()
+ .limit(5)
+ .toArray();
+ Object[] unorderedArray = set.stream()
+ .unordered()
+ .parallel()
+ .limit(5)
+ .toArray();
+
+ logger.info(Arrays.toString(orderedArray));
+ logger.info(Arrays.toString(unorderedArray));
+ }
+
+
+ @Test
+ public void givenUnsortedStreamInput_whenStreamSorted_thenCheckOrderChanged(){
+
+ List list = Arrays.asList(-3,10,-4,1,3);
+
+ Object[] listOutput = list.stream().toArray();
+ Object[] listOutputSorted = list.stream().sorted().toArray();
+
+ assertEquals("[-3, 10, -4, 1, 3]", Arrays.toString(listOutput));
+ assertEquals("[-4, -3, 1, 3, 10]", Arrays.toString(listOutputSorted));
+
+ }
+
+ @Test
+ public void givenUnsortedStreamInput_whenStreamDistinct_thenShowTimeTaken(){
+ long start, end;
+ start = System.currentTimeMillis();
+ IntStream.range(1,1_000_000).unordered().parallel().distinct().toArray();
+ end = System.currentTimeMillis();
+ System.out.println(String.format("Time taken when unordered: %d ms", (end - start)));
+ }
+
+
+ @Test
+ public void givenSameCollection_whenStreamTerminated_thenCheckEachVsEachOrdered(){
+
+ List list = Arrays.asList("B", "A", "C", "D", "F");
+
+ list.stream().parallel().forEach(e -> logger.log(Level.INFO, e));
+ list.stream().parallel().forEachOrdered(e -> logger.log(Level.INFO, e));
+
+ }
+
+ @Test
+ public void givenSameCollection_whenStreamCollected_thenCheckOutput(){
+
+ List list = Arrays.asList("B", "A", "C", "D", "F");
+
+ List collectionList = list.stream().parallel().collect(Collectors.toList());
+ Set collectionSet = list.stream().parallel().collect(Collectors.toCollection(TreeSet::new));
+
+ assertEquals("[B, A, C, D, F]", collectionList.toString());
+ assertEquals("[A, B, C, D, F]", collectionSet.toString());
+
+ }
+
+
+ @Test
+ public void givenListIterationOrder_whenStreamCollectedToMap_thenCeckOrderChanged() {
+ List list = Arrays.asList("A", "BB", "CCC");
+
+ Map hashMap = list.stream().collect(Collectors.toMap(Function.identity(), String::length));
+
+ Object[] keySet = hashMap.keySet().toArray();
+
+ assertEquals("[BB, A, CCC]", Arrays.toString(keySet));
+
+ }
+
+ @Test
+ public void givenListIteration_whenStreamCollectedtoHashMap_thenCheckOrderMaintained() {
+ List list = Arrays.asList("A", "BB", "CCC", "CCC");
+
+ Map linkedHashMap = list.stream().collect(Collectors.toMap(
+ Function.identity(),
+ String::length,
+ (u, v) -> u,
+ LinkedHashMap::new
+ ));
+
+ Object[] keySet = linkedHashMap.keySet().toArray();
+
+ assertEquals("[A, BB, CCC]", Arrays.toString(keySet));
+ }
+
+}
diff --git a/testing-modules/streams-ordering/src/test/java/benchmarking/TestBenchmark.java b/testing-modules/streams-ordering/src/test/java/benchmarking/TestBenchmark.java
new file mode 100644
index 0000000000..a3e99e6465
--- /dev/null
+++ b/testing-modules/streams-ordering/src/test/java/benchmarking/TestBenchmark.java
@@ -0,0 +1,97 @@
+package benchmarking;
+
+import org.junit.Test;
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.infra.Blackhole;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+import org.openjdk.jmh.runner.options.TimeValue;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.IntStream;
+
+
+public class TestBenchmark
+{
+
+ @Test
+ public void
+ launchBenchmark() throws Exception {
+
+ Options opt = new OptionsBuilder()
+ // Specify which benchmarks to run.
+ // You can be more specific if you'd like to run only one benchmark per test.
+ .include(this.getClass().getName() + ".*")
+ // Set the following options as needed
+ .mode (Mode.AverageTime)
+ .timeUnit(TimeUnit.MICROSECONDS)
+ .warmupTime(TimeValue.seconds(1))
+ .warmupIterations(2)
+ .measurementTime(TimeValue.seconds(1))
+ .measurementIterations(2)
+ .threads(2)
+ .forks(1)
+ .shouldFailOnError(true)
+ .shouldDoGC(true)
+ //.jvmArgs("-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintInlining")
+ //.addProfiler(WinPerfAsmProfiler.class)
+ .build();
+
+ new Runner(opt).run();
+
+
+ }
+
+ @Benchmark
+ public void givenOrderedStreamInput_whenStreamFiltered_showOpsPerMS(){
+ IntStream.range(1, 100_000_000).parallel().filter(i -> i % 10 == 0).toArray();
+ }
+
+ @Benchmark
+ public void givenUnorderedStreamInput_whenStreamFiltered_showOpsPerMS(){
+ IntStream.range(1,100_000_000).unordered().parallel().filter(i -> i % 10 == 0).toArray();
+ }
+
+ @Benchmark
+ public void givenUnorderedStreamInput_whenStreamDistinct_showOpsPerMS(){
+ IntStream.range(1, 1_000_000).unordered().parallel().distinct().toArray();
+ }
+
+ @Benchmark
+ public void givenOrderedStreamInput_whenStreamDistinct_showOpsPerMS() {
+ //section 5.1.
+ IntStream.range(1, 1_000_000).parallel().distinct().toArray();
+ }
+
+
+ // The JMH samples are the best documentation for how to use it
+ // http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/
+ @State(Scope.Thread)
+ public static class BenchmarkState
+ {
+ List list;
+
+ @Setup(Level.Trial) public void
+ initialize() {
+
+ Random rand = new Random();
+
+ list = new ArrayList<>();
+ for (int i = 0; i < 1000; i++)
+ list.add (rand.nextInt());
+ }
+ }
+
+ @Benchmark public void
+ benchmark1 (BenchmarkState state, Blackhole bh) {
+
+ List list = state.list;
+
+ for (int i = 0; i < 1000; i++)
+ bh.consume (list.get (i));
+ }
+}
\ No newline at end of file