diff --git a/README.md b/README.md
index b08a93f23e..88750cf654 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,3 @@
-**UPDATE**: The price of "Learn Spring Security OAuth" will permanently change on the 11th of December, along with the upcoming OAuth2 material: http://bit.ly/github-lss
-
The Courses
==============================
diff --git a/algorithms-genetic/README.md b/algorithms-genetic/README.md
index 1c9e831ac2..eb4e3fb798 100644
--- a/algorithms-genetic/README.md
+++ b/algorithms-genetic/README.md
@@ -5,6 +5,6 @@ This module contains articles about genetic algorithms.
### Relevant articles:
- [Introduction to Jenetics Library](https://www.baeldung.com/jenetics)
-- [Ant Colony Optimization](https://www.baeldung.com/java-ant-colony-optimization)
+- [Ant Colony Optimization with a Java Example](https://www.baeldung.com/java-ant-colony-optimization)
- [Design a Genetic Algorithm in Java](https://www.baeldung.com/java-genetic-algorithm)
- [The Traveling Salesman Problem in Java](https://www.baeldung.com/java-simulated-annealing-for-traveling-salesman)
diff --git a/algorithms-miscellaneous-1/README.md b/algorithms-miscellaneous-1/README.md
index 77c621339a..02bf874197 100644
--- a/algorithms-miscellaneous-1/README.md
+++ b/algorithms-miscellaneous-1/README.md
@@ -6,8 +6,8 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
### Relevant articles:
- [Validating Input With Finite Automata in Java](https://www.baeldung.com/java-finite-automata)
-- [Example of Hill Climbing Algorithm](https://www.baeldung.com/java-hill-climbing-algorithm)
-- [Introduction to Minimax Algorithm](https://www.baeldung.com/java-minimax-algorithm)
+- [Example of Hill Climbing Algorithm in Java](https://www.baeldung.com/java-hill-climbing-algorithm)
+- [Introduction to Minimax Algorithm with a Java Implementation](https://www.baeldung.com/java-minimax-algorithm)
- [How to Calculate Levenshtein Distance in Java?](https://www.baeldung.com/java-levenshtein-distance)
- [How to Find the Kth Largest Element in Java](https://www.baeldung.com/java-kth-largest-element)
- More articles: [[next -->]](/algorithms-miscellaneous-2)
diff --git a/algorithms-miscellaneous-4/README.md b/algorithms-miscellaneous-4/README.md
index fd33b58d72..2649df9fc9 100644
--- a/algorithms-miscellaneous-4/README.md
+++ b/algorithms-miscellaneous-4/README.md
@@ -5,8 +5,8 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
### Relevant articles:
- [Multi-Swarm Optimization Algorithm in Java](https://www.baeldung.com/java-multi-swarm-algorithm)
-- [Check If a String Contains All The Letters of The Alphabet](https://www.baeldung.com/java-string-contains-all-letters)
-- [Find the Middle Element of a Linked List](https://www.baeldung.com/java-linked-list-middle-element)
+- [Check If a String Contains All The Letters of The Alphabet with Java](https://www.baeldung.com/java-string-contains-all-letters)
+- [Find the Middle Element of a Linked List in Java](https://www.baeldung.com/java-linked-list-middle-element)
- [Find Substrings That Are Palindromes in Java](https://www.baeldung.com/java-palindrome-substrings)
- [Find the Longest Substring without Repeating Characters](https://www.baeldung.com/java-longest-substring-without-repeated-characters)
- [Permutations of an Array in Java](https://www.baeldung.com/java-array-permutations)
diff --git a/algorithms-miscellaneous-5/README.md b/algorithms-miscellaneous-5/README.md
index e5d46ace1c..54b936586f 100644
--- a/algorithms-miscellaneous-5/README.md
+++ b/algorithms-miscellaneous-5/README.md
@@ -9,11 +9,11 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
- [Reversing a Binary Tree in Java](https://www.baeldung.com/java-reversing-a-binary-tree)
- [Find If Two Numbers Are Relatively Prime in Java](https://www.baeldung.com/java-two-relatively-prime-numbers)
- [Knapsack Problem Implementation in Java](https://www.baeldung.com/java-knapsack)
-- [How to Determine if a Binary Tree is Balanced](https://www.baeldung.com/java-balanced-binary-tree)
+- [How to Determine if a Binary Tree is Balanced in Java](https://www.baeldung.com/java-balanced-binary-tree)
- [Overview of Combinatorial Problems in Java](https://www.baeldung.com/java-combinatorial-algorithms)
-- [Prim’s Algorithm](https://www.baeldung.com/java-prim-algorithm)
-- [Maximum Subarray Problem](https://www.baeldung.com/java-maximum-subarray)
-- [How to Merge Two Sorted Arrays](https://www.baeldung.com/java-merge-sorted-arrays)
-- [Median of Stream of Integers using Heap](https://www.baeldung.com/java-stream-integers-median-using-heap)
+- [Prim’s Algorithm with a Java Implementation](https://www.baeldung.com/java-prim-algorithm)
+- [Maximum Subarray Problem in Java](https://www.baeldung.com/java-maximum-subarray)
+- [How to Merge Two Sorted Arrays in Java](https://www.baeldung.com/java-merge-sorted-arrays)
+- [Median of Stream of Integers using Heap in Java](https://www.baeldung.com/java-stream-integers-median-using-heap)
- More articles: [[<-- prev]](/algorithms-miscellaneous-4) [[next -->]](/algorithms-miscellaneous-6)
diff --git a/algorithms-miscellaneous-6/README.md b/algorithms-miscellaneous-6/README.md
index 5c2306d794..f21eddeed8 100644
--- a/algorithms-miscellaneous-6/README.md
+++ b/algorithms-miscellaneous-6/README.md
@@ -1,13 +1,13 @@
### Relevant Articles:
-- [Boruvka’s Algorithm for Minimum Spanning Trees](https://www.baeldung.com/java-boruvka-algorithm)
+- [Boruvka’s Algorithm for Minimum Spanning Trees in Java](https://www.baeldung.com/java-boruvka-algorithm)
- [Gradient Descent in Java](https://www.baeldung.com/java-gradient-descent)
-- [Kruskal’s Algorithm for Spanning Trees](https://www.baeldung.com/java-spanning-trees-kruskal)
+- [Kruskal’s Algorithm for Spanning Trees with a Java Implementation](https://www.baeldung.com/java-spanning-trees-kruskal)
- [Balanced Brackets Algorithm in Java](https://www.baeldung.com/java-balanced-brackets-algorithm)
- [Efficiently Merge Sorted Java Sequences](https://www.baeldung.com/java-merge-sorted-sequences)
- [Introduction to Greedy Algorithms with Java](https://www.baeldung.com/java-greedy-algorithms)
- [The Caesar Cipher in Java](https://www.baeldung.com/java-caesar-cipher)
- [Implementing a 2048 Solver in Java](https://www.baeldung.com/2048-java-solver)
-- [Finding Top K Elements in an Array](https://www.baeldung.com/java-array-top-elements)
+- [Finding Top K Elements in a Java Array](https://www.baeldung.com/java-array-top-elements)
- [Reversing a Linked List in Java](https://www.baeldung.com/java-reverse-linked-list)
- More articles: [[<-- prev]](/algorithms-miscellaneous-5)
diff --git a/algorithms-searching/README.md b/algorithms-searching/README.md
index a3ea023da3..7d10100832 100644
--- a/algorithms-searching/README.md
+++ b/algorithms-searching/README.md
@@ -8,8 +8,8 @@ This module contains articles about searching algorithms.
- [Depth First Search in Java](https://www.baeldung.com/java-depth-first-search)
- [Interpolation Search in Java](https://www.baeldung.com/java-interpolation-search)
- [Breadth-First Search Algorithm in Java](https://www.baeldung.com/java-breadth-first-search)
-- [String Search Algorithms for Large Texts](https://www.baeldung.com/java-full-text-search-algorithms)
-- [Monte Carlo Tree Search for Tic-Tac-Toe Game](https://www.baeldung.com/java-monte-carlo-tree-search)
+- [String Search Algorithms for Large Texts with Java](https://www.baeldung.com/java-full-text-search-algorithms)
+- [Monte Carlo Tree Search for Tic-Tac-Toe Game in Java](https://www.baeldung.com/java-monte-carlo-tree-search)
- [Range Search Algorithm in Java](https://www.baeldung.com/java-range-search)
-- [Fast Pattern Matching of Strings Using Suffix Tree](https://www.baeldung.com/java-pattern-matching-suffix-tree)
-- [Find the Kth Smallest Element in Two Sorted Arrays](https://www.baeldung.com/java-kth-smallest-element-in-sorted-arrays)
+- [Fast Pattern Matching of Strings Using Suffix Tree in Java](https://www.baeldung.com/java-pattern-matching-suffix-tree)
+- [Find the Kth Smallest Element in Two Sorted Arrays in Java](https://www.baeldung.com/java-kth-smallest-element-in-sorted-arrays)
diff --git a/algorithms-sorting-2/README.md b/algorithms-sorting-2/README.md
index 71c9b8f86c..b31cfceb42 100644
--- a/algorithms-sorting-2/README.md
+++ b/algorithms-sorting-2/README.md
@@ -2,6 +2,6 @@
- [Sorting a String Alphabetically in Java](https://www.baeldung.com/java-sort-string-alphabetically)
- [Sorting Strings by Contained Numbers in Java](https://www.baeldung.com/java-sort-strings-contained-numbers)
-- [How an In-Place Sorting Algorithm Works](https://www.baeldung.com/java-in-place-sorting)
-- [Partitioning and Sorting Arrays with Many Repeated Entries](https://www.baeldung.com/java-sorting-arrays-with-repeated-entries)
+- [Guide to In-Place Sorting Algorithm Works with a Java Implementation](https://www.baeldung.com/java-in-place-sorting)
+- [Partitioning and Sorting Arrays with Many Repeated Entries with Java Examples](https://www.baeldung.com/java-sorting-arrays-with-repeated-entries)
- More articles: [[<-- prev]](/algorithms-sorting)
diff --git a/apache-spark/README.md b/apache-spark/README.md
index c60b556d51..3a2d2f4e15 100644
--- a/apache-spark/README.md
+++ b/apache-spark/README.md
@@ -8,3 +8,4 @@ This module contains articles about Apache Spark
- [Building a Data Pipeline with Kafka, Spark Streaming and Cassandra](https://www.baeldung.com/kafka-spark-data-pipeline)
- [Machine Learning with Spark MLlib](https://www.baeldung.com/spark-mlib-machine-learning)
- [Introduction to Spark Graph Processing with GraphFrames](https://www.baeldung.com/spark-graph-graphframes)
+- [Apache Spark: Differences between Dataframes, Datasets and RDDs](https://www.baeldung.com/java-spark-dataframe-dataset-rdd)
diff --git a/core-java-modules/core-java-15/.mvn/jvm.config b/core-java-modules/core-java-15/.mvn/jvm.config
new file mode 100644
index 0000000000..50f549be0a
--- /dev/null
+++ b/core-java-modules/core-java-15/.mvn/jvm.config
@@ -0,0 +1 @@
+--enable-preview
\ No newline at end of file
diff --git a/core-java-modules/core-java-15/README.md b/core-java-modules/core-java-15/README.md
new file mode 100644
index 0000000000..53989f5cbb
--- /dev/null
+++ b/core-java-modules/core-java-15/README.md
@@ -0,0 +1,7 @@
+## Core Java 15
+
+This module contains articles about Java 15.
+
+### Relevant articles
+
+- TODO: add article links here
diff --git a/core-java-modules/core-java-15/pom.xml b/core-java-modules/core-java-15/pom.xml
new file mode 100644
index 0000000000..c6f1454078
--- /dev/null
+++ b/core-java-modules/core-java-15/pom.xml
@@ -0,0 +1,77 @@
+
+
+ 4.0.0
+ core-java-15
+ core-java-15
+ jar
+ http://maven.apache.org
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+ ../../pom.xml
+
+
+
+
+ org.apache.commons
+ commons-lang3
+ ${apache-commons-lang3.version}
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ ${junit-jupiter.version}
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit-jupiter.version}
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ ${maven.compiler.release}
+ --enable-preview
+
+ 15
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${surefire.plugin.version}
+
+ --enable-preview
+
+
+
+
+
+
+ 15
+ 3.11
+ 3.17.2
+ 3.8.1
+ 3.0.0-M3
+
+
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/alternative/Vehicles.java b/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/alternative/Vehicles.java
new file mode 100644
index 0000000000..091c5841bf
--- /dev/null
+++ b/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/alternative/Vehicles.java
@@ -0,0 +1,49 @@
+package com.baeldung.sealed.alternative;
+
+public class Vehicles {
+
+ abstract static class Vehicle {
+
+ private final String registrationNumber;
+
+ public Vehicle(String registrationNumber) {
+ this.registrationNumber = registrationNumber;
+ }
+
+ public String getRegistrationNumber() {
+ return registrationNumber;
+ }
+
+ }
+
+ public static final class Car extends Vehicle {
+
+ private final int numberOfSeats;
+
+ public Car(int numberOfSeats, String registrationNumber) {
+ super(registrationNumber);
+ this.numberOfSeats = numberOfSeats;
+ }
+
+ public int getNumberOfSeats() {
+ return numberOfSeats;
+ }
+
+ }
+
+ public static final class Truck extends Vehicle {
+
+ private final int loadCapacity;
+
+ public Truck(int loadCapacity, String registrationNumber) {
+ super(registrationNumber);
+ this.loadCapacity = loadCapacity;
+ }
+
+ public int getLoadCapacity() {
+ return loadCapacity;
+ }
+
+ }
+
+}
diff --git a/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/classes/Car.java b/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/classes/Car.java
new file mode 100644
index 0000000000..7dce266da7
--- /dev/null
+++ b/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/classes/Car.java
@@ -0,0 +1,21 @@
+package com.baeldung.sealed.classes;
+
+public non-sealed class Car extends Vehicle implements Service {
+
+ private final int numberOfSeats;
+
+ public Car(int numberOfSeats, String registrationNumber) {
+ super(registrationNumber);
+ this.numberOfSeats = numberOfSeats;
+ }
+
+ public int getNumberOfSeats() {
+ return numberOfSeats;
+ }
+
+ @Override
+ public int getMaxServiceIntervalInMonths() {
+ return 12;
+ }
+
+}
diff --git a/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/classes/Service.java b/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/classes/Service.java
new file mode 100644
index 0000000000..9486b302f1
--- /dev/null
+++ b/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/classes/Service.java
@@ -0,0 +1,11 @@
+package com.baeldung.sealed.classes;
+
+public sealed interface Service permits Car, Truck {
+
+ int getMaxServiceIntervalInMonths();
+
+ default int getMaxDistanceBetweenServicesInKilometers() {
+ return 100000;
+ }
+
+}
diff --git a/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/classes/Truck.java b/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/classes/Truck.java
new file mode 100644
index 0000000000..8d5234342b
--- /dev/null
+++ b/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/classes/Truck.java
@@ -0,0 +1,21 @@
+package com.baeldung.sealed.classes;
+
+public final class Truck extends Vehicle implements Service {
+
+ private final int loadCapacity;
+
+ public Truck(int loadCapacity, String registrationNumber) {
+ super(registrationNumber);
+ this.loadCapacity = loadCapacity;
+ }
+
+ public int getLoadCapacity() {
+ return loadCapacity;
+ }
+
+ @Override
+ public int getMaxServiceIntervalInMonths() {
+ return 18;
+ }
+
+}
diff --git a/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/classes/Vehicle.java b/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/classes/Vehicle.java
new file mode 100644
index 0000000000..79eda0c790
--- /dev/null
+++ b/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/classes/Vehicle.java
@@ -0,0 +1,15 @@
+package com.baeldung.sealed.classes;
+
+public abstract sealed class Vehicle permits Car, Truck {
+
+ protected final String registrationNumber;
+
+ public Vehicle(String registrationNumber) {
+ this.registrationNumber = registrationNumber;
+ }
+
+ public String getRegistrationNumber() {
+ return registrationNumber;
+ }
+
+}
diff --git a/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/records/Car.java b/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/records/Car.java
new file mode 100644
index 0000000000..74b6ed1405
--- /dev/null
+++ b/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/records/Car.java
@@ -0,0 +1,14 @@
+package com.baeldung.sealed.records;
+
+public record Car(int numberOfSeats, String registrationNumber) implements Vehicle {
+
+ @Override
+ public String getRegistrationNumber() {
+ return registrationNumber;
+ }
+
+ public int getNumberOfSeats() {
+ return numberOfSeats;
+ }
+
+}
diff --git a/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/records/Truck.java b/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/records/Truck.java
new file mode 100644
index 0000000000..1b887ae014
--- /dev/null
+++ b/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/records/Truck.java
@@ -0,0 +1,14 @@
+package com.baeldung.sealed.records;
+
+public record Truck(int loadCapacity, String registrationNumber) implements Vehicle {
+
+ @Override
+ public String getRegistrationNumber() {
+ return registrationNumber;
+ }
+
+ public int getLoadCapacity() {
+ return loadCapacity;
+ }
+
+}
diff --git a/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/records/Vehicle.java b/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/records/Vehicle.java
new file mode 100644
index 0000000000..c51f8e97c6
--- /dev/null
+++ b/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/records/Vehicle.java
@@ -0,0 +1,7 @@
+package com.baeldung.sealed.records;
+
+public sealed interface Vehicle permits Car, Truck {
+
+ String getRegistrationNumber();
+
+}
diff --git a/core-java-modules/core-java-15/src/test/java/com/baeldung/sealed/classes/VehicleUnitTest.java b/core-java-modules/core-java-15/src/test/java/com/baeldung/sealed/classes/VehicleUnitTest.java
new file mode 100644
index 0000000000..b614981a43
--- /dev/null
+++ b/core-java-modules/core-java-15/src/test/java/com/baeldung/sealed/classes/VehicleUnitTest.java
@@ -0,0 +1,76 @@
+package com.baeldung.sealed.classes;
+
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import java.lang.constant.ClassDesc;
+
+public class VehicleUnitTest {
+
+ private static Vehicle car;
+ private static Vehicle truck;
+
+ @BeforeAll
+ public static void createInstances() {
+ car = new Car(5, "VZ500DA");
+ truck = new Truck(19000, "VZ600TA");
+ }
+
+ @Test
+ public void givenCar_whenUsingReflectionAPI_thenSuperClassIsSealed() {
+ Assertions.assertThat(car.getClass().isSealed()).isEqualTo(false);
+ Assertions.assertThat(car.getClass().getSuperclass().isSealed()).isEqualTo(true);
+ Assertions.assertThat(car.getClass().getSuperclass().permittedSubclasses())
+ .contains(ClassDesc.of(car.getClass().getCanonicalName()));
+ }
+
+ @Test
+ public void givenTruck_whenUsingReflectionAPI_thenSuperClassIsSealed() {
+ Assertions.assertThat(truck.getClass().isSealed()).isEqualTo(false);
+ Assertions.assertThat(truck.getClass().getSuperclass().isSealed()).isEqualTo(true);
+ Assertions.assertThat(truck.getClass().getSuperclass().permittedSubclasses())
+ .contains(ClassDesc.of(truck.getClass().getCanonicalName()));
+ }
+
+ @Test
+ public void givenCar_whenGettingPropertyTraditionalWay_thenNumberOfSeatsPropertyIsReturned() {
+ Assertions.assertThat(getPropertyTraditionalWay(car)).isEqualTo(5);
+ }
+
+ @Test
+ public void givenCar_whenGettingPropertyViaPatternMatching_thenNumberOfSeatsPropertyIsReturned() {
+ Assertions.assertThat(getPropertyViaPatternMatching(car)).isEqualTo(5);
+ }
+
+ @Test
+ public void givenTruck_whenGettingPropertyTraditionalWay_thenLoadCapacityIsReturned() {
+ Assertions.assertThat(getPropertyTraditionalWay(truck)).isEqualTo(19000);
+ }
+
+ @Test
+ public void givenTruck_whenGettingPropertyViaPatternMatching_thenLoadCapacityIsReturned() {
+ Assertions.assertThat(getPropertyViaPatternMatching(truck)).isEqualTo(19000);
+ }
+
+ private int getPropertyTraditionalWay(Vehicle vehicle) {
+ if (vehicle instanceof Car) {
+ return ((Car) vehicle).getNumberOfSeats();
+ } else if (vehicle instanceof Truck) {
+ return ((Truck) vehicle).getLoadCapacity();
+ } else {
+ throw new RuntimeException("Unknown instance of Vehicle");
+ }
+ }
+
+ private int getPropertyViaPatternMatching(Vehicle vehicle) {
+ if (vehicle instanceof Car car) {
+ return car.getNumberOfSeats();
+ } else if (vehicle instanceof Truck truck) {
+ return truck.getLoadCapacity();
+ } else {
+ throw new RuntimeException("Unknown instance of Vehicle");
+ }
+ }
+
+}
diff --git a/core-java-modules/core-java-15/src/test/java/com/baeldung/sealed/records/VehicleUnitTest.java b/core-java-modules/core-java-15/src/test/java/com/baeldung/sealed/records/VehicleUnitTest.java
new file mode 100644
index 0000000000..ac8a8c953c
--- /dev/null
+++ b/core-java-modules/core-java-15/src/test/java/com/baeldung/sealed/records/VehicleUnitTest.java
@@ -0,0 +1,76 @@
+package com.baeldung.sealed.records;
+
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import java.lang.constant.ClassDesc;
+
+public class VehicleUnitTest {
+
+ private static Vehicle car;
+ private static Vehicle truck;
+
+ @BeforeAll
+ public static void createInstances() {
+ car = new Car(4, "VZ500DA");
+ truck = new Truck(16000, "VZ600TA");
+ }
+
+ @Test
+ public void givenCar_whenUsingReflectionAPI_thenInterfaceIsSealed() {
+ Assertions.assertThat(car.getClass().isSealed()).isEqualTo(false);
+ Assertions.assertThat(car.getClass().getInterfaces()[0].isSealed()).isEqualTo(true);
+ Assertions.assertThat(car.getClass().getInterfaces()[0].permittedSubclasses())
+ .contains(ClassDesc.of(car.getClass().getCanonicalName()));
+ }
+
+ @Test
+ public void givenTruck_whenUsingReflectionAPI_thenInterfaceIsSealed() {
+ Assertions.assertThat(truck.getClass().isSealed()).isEqualTo(false);
+ Assertions.assertThat(truck.getClass().getInterfaces()[0].isSealed()).isEqualTo(true);
+ Assertions.assertThat(truck.getClass().getInterfaces()[0].permittedSubclasses())
+ .contains(ClassDesc.of(truck.getClass().getCanonicalName()));
+ }
+
+ @Test
+ public void givenCar_whenGettingPropertyTraditionalWay_thenNumberOfSeatsPropertyIsReturned() {
+ Assertions.assertThat(getPropertyTraditionalWay(car)).isEqualTo(4);
+ }
+
+ @Test
+ public void givenCar_whenGettingPropertyViaPatternMatching_thenNumberOfSeatsPropertyIsReturned() {
+ Assertions.assertThat(getPropertyViaPatternMatching(car)).isEqualTo(4);
+ }
+
+ @Test
+ public void givenTruck_whenGettingPropertyTraditionalWay_thenLoadCapacityIsReturned() {
+ Assertions.assertThat(getPropertyTraditionalWay(truck)).isEqualTo(16000);
+ }
+
+ @Test
+ public void givenTruck_whenGettingPropertyViaPatternMatching_thenLoadCapacityIsReturned() {
+ Assertions.assertThat(getPropertyViaPatternMatching(truck)).isEqualTo(16000);
+ }
+
+ private int getPropertyTraditionalWay(Vehicle vehicle) {
+ if (vehicle instanceof Car) {
+ return ((Car) vehicle).getNumberOfSeats();
+ } else if (vehicle instanceof Truck) {
+ return ((Truck) vehicle).getLoadCapacity();
+ } else {
+ throw new RuntimeException("Unknown instance of Vehicle");
+ }
+ }
+
+ private int getPropertyViaPatternMatching(Vehicle vehicle) {
+ if (vehicle instanceof Car car) {
+ return car.getNumberOfSeats();
+ } else if (vehicle instanceof Truck truck) {
+ return truck.getLoadCapacity();
+ } else {
+ throw new RuntimeException("Unknown instance of Vehicle");
+ }
+ }
+
+}
diff --git a/core-java-modules/core-java-collections-3/README.md b/core-java-modules/core-java-collections-3/README.md
index e21e3642f9..6bc9139856 100644
--- a/core-java-modules/core-java-collections-3/README.md
+++ b/core-java-modules/core-java-collections-3/README.md
@@ -14,3 +14,4 @@
- [Convert an Array of Primitives to a List](https://www.baeldung.com/java-primitive-array-to-list)
- [A Guide to BitSet in Java](https://www.baeldung.com/java-bitset)
- [Get the First Key and Value From a HashMap](https://www.baeldung.com/java-hashmap-get-first-entry)
+- [Performance of removeAll() in a HashSet](https://www.baeldung.com/java-hashset-removeall-performance)
diff --git a/core-java-modules/core-java-concurrency-advanced-3/README.md b/core-java-modules/core-java-concurrency-advanced-3/README.md
index 7d98e462d7..9495d5f479 100644
--- a/core-java-modules/core-java-concurrency-advanced-3/README.md
+++ b/core-java-modules/core-java-concurrency-advanced-3/README.md
@@ -13,7 +13,7 @@ This module contains articles about advanced topics about multithreading with co
- [Java Thread Deadlock and Livelock](https://www.baeldung.com/java-deadlock-livelock)
- [Guide to AtomicStampedReference in Java](https://www.baeldung.com/java-atomicstampedreference)
- [The ABA Problem in Concurrency](https://www.baeldung.com/cs/aba-concurrency)
-- [Introduction to Lock-Free Data Structures](https://www.baeldung.com/lock-free-programming)
+- [Introduction to Lock-Free Data Structures with Java Examples](https://www.baeldung.com/lock-free-programming)
- [Introduction to Exchanger in Java](https://www.baeldung.com/java-exchanger)
- [Why Not To Start A Thread In The Constructor?](https://www.baeldung.com/java-thread-constructor)
- [[<-- previous]](/core-java-modules/core-java-concurrency-advanced-2)
diff --git a/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/stopexecution/StopExecution.java b/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/stopexecution/StopExecution.java
new file mode 100644
index 0000000000..20f66da5da
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/stopexecution/StopExecution.java
@@ -0,0 +1,263 @@
+package com.baeldung.concurrent.stopexecution;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+public class StopExecution {
+ private static final Logger LOG = LoggerFactory.getLogger(StopExecution.class);
+
+ public static void main(String[] args) {
+ StopExecution stopExecution = new StopExecution();
+ //stopExecution.testUsingLoop();
+ //stopExecution.testTimer();
+ stopExecution.testScheduledExecutor();
+ LOG.info("done");
+ }
+
+ public void testUsingLoop() {
+ long start = System.currentTimeMillis();
+ long end = start + 5000;
+ List items = new ArrayList<>();
+ int counter = 0;
+
+ // Let this loop run only upto 5 seconds
+ while (System.currentTimeMillis() < end && counter < items.size()) {
+ // Fetch the item from the list.
+ // Some expensive operation on the item.
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ counter++;
+ }
+ }
+
+ public static void testThreads() {
+ Thread thread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ LOG.info("inside run");
+
+ try {
+ Thread.sleep(10000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ LOG.info("exit run");
+ }
+ });
+ thread.start();
+ while (thread.getState() != Thread.State.TERMINATED) {
+ LOG.info(thread.getState().name());
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static void testExecutor() {
+ final ExecutorService service = Executors.newSingleThreadExecutor();
+ Future f = null;
+ try {
+ f = service.submit(() -> {
+ // Do you long running calculation here
+ try {
+ Thread.sleep(2737); // Simulate some delay
+ } catch (InterruptedException e) {
+ LOG.info("Interrupted");
+ return "interrupted";
+ }
+ LOG.info("Sleep finished");
+ return "42";
+ });
+
+ LOG.info(f.get(2, TimeUnit.SECONDS));
+ } catch (TimeoutException e) {
+ f.cancel(true);
+ LOG.error("Calculation took to long");
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ service.shutdown();
+ }
+ }
+
+ public void testExecutor2() {
+ final ExecutorService service = Executors.newSingleThreadExecutor();
+ Future f = null;
+ try {
+ f = service.submit(new LongRunningTask());
+ LOG.info("testExecutor2");
+ f.get(1, TimeUnit.SECONDS);
+ } catch (final TimeoutException e) {
+ f.cancel(true);
+ LOG.error("Calculation took to long");
+ } catch (final Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ service.shutdownNow();
+ }
+ }
+
+ public void testScheduledExecutor() {
+ LOG.info("testScheduledExecutor");
+ ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
+ Future future = executor.submit(new LongRunningTask());
+ executor.schedule(new Runnable() {
+ public void run() {
+ future.cancel(true);
+ }
+ }, 1000, TimeUnit.MILLISECONDS);
+ executor.shutdown();
+ }
+
+ public void testThreadAndInterrupt() {
+
+ Thread t;
+ try {
+ t = new Thread(new LongRunningTask());
+
+ LOG.info("testExecutor3");
+ long end = System.currentTimeMillis() + 2000;
+ t.start();
+ while (t.isAlive() && System.currentTimeMillis() < end) {
+ Thread.sleep(50);
+ }
+ t.interrupt();
+ } catch (final Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void testTimer() {
+ LOG.info("Timer test");
+ Thread t = new Thread(new LongRunningTask());
+ Timer timeoutTimer = new Timer();
+ timeoutTimer.schedule(new TimeOutTask(t, timeoutTimer), 1000);
+ t.start();
+ }
+
+ class MyRunnableTask implements Runnable {
+ public void run() {
+ try {
+ LOG.info("MyRunnable...");
+ Thread.sleep(10000);
+ } catch (InterruptedException ie) {
+ LOG.info("MyRunnable interrupted...");
+ }
+ }
+ }
+
+ class TimeOutTask extends TimerTask {
+ private Thread t;
+ private Timer timer;
+
+ TimeOutTask(Thread t, Timer timer) {
+ this.t = t;
+ this.timer = timer;
+ }
+
+ public void run() {
+ if (t != null && t.isAlive()) {
+ t.interrupt();
+ timer.cancel();
+ }
+ }
+ }
+
+ class LongRunningTask implements Runnable {
+ @Override
+ public void run() {
+ longRunningSort();
+ }
+
+ private void longRunningOperation() {
+ LOG.info("long Running operation started");
+
+ try {
+ //Thread.sleep(500);
+ longFileRead();
+ LOG.info("long running operation finished");
+ } catch (InterruptedException e) {
+ LOG.info("long Running operation interrupted");
+ }
+ }
+
+ private void longRunningSort() {
+ LOG.info("long Running task started");
+ // Do you long running calculation here
+ int len = 100000;
+ List numbers = new ArrayList<>();
+ try {
+ for (int i = len; i > 0; i--) {
+ //Thread.sleep(5)
+ numbers.add(i);
+ }
+
+ int i = 0;
+ for (i = 0; i < len; i++) {
+ int minIndex = i;
+ for (int j = i + 1; j < len; j++) {
+ if (numbers.get(minIndex) > numbers.get(j))
+ minIndex = j;
+ }
+ if (minIndex != i) {
+ int temp = numbers.get(i);
+ numbers.set(i, numbers.get(minIndex));
+ numbers.set(minIndex, temp);
+ }
+ throwExceptionOnThreadInterrupt();
+ }
+ LOG.info("Index position: " + i);
+ LOG.info("Long running task finished");
+ } catch (InterruptedException e) {
+ LOG.info("long Running operation interrupted");
+ }
+ }
+
+ private void longFileRead() throws InterruptedException {
+ String file = "input.txt";
+ ClassLoader classloader = getClass().getClassLoader();
+
+ try (InputStream inputStream = classloader.getResourceAsStream(file)) {
+ Reader inputStreamReader = new InputStreamReader(inputStream);
+
+ int data = inputStreamReader.read();
+ while (data != -1) {
+ char theChar = (char) data;
+ data = inputStreamReader.read();
+ throwExceptionOnThreadInterrupt();
+ }
+ } catch (IOException e) {
+ LOG.error("Exception: ", e);
+ }
+ }
+
+ private void throwExceptionOnThreadInterrupt() throws InterruptedException {
+ if (Thread.currentThread().interrupted()) {
+ throw new InterruptedException();
+ }
+ }
+ }
+
+}
+
+
diff --git a/core-java-modules/core-java-exceptions-3/pom.xml b/core-java-modules/core-java-exceptions-3/pom.xml
index b909572afe..8c36fd0af1 100644
--- a/core-java-modules/core-java-exceptions-3/pom.xml
+++ b/core-java-modules/core-java-exceptions-3/pom.xml
@@ -17,6 +17,14 @@
+
+
+ com.h2database
+ h2
+ 1.4.191
+ test
+
+
org.assertj
diff --git a/core-java-modules/core-java-exceptions-3/src/test/java/com/baeldung/exceptions/abstractmethoderror/AbstractMethodErrorUnitTest.java b/core-java-modules/core-java-exceptions-3/src/test/java/com/baeldung/exceptions/abstractmethoderror/AbstractMethodErrorUnitTest.java
new file mode 100644
index 0000000000..cadc884487
--- /dev/null
+++ b/core-java-modules/core-java-exceptions-3/src/test/java/com/baeldung/exceptions/abstractmethoderror/AbstractMethodErrorUnitTest.java
@@ -0,0 +1,23 @@
+package com.baeldung.exceptions.abstractmethoderror;
+
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+class AbstractMethodErrorUnitTest {
+ private static final String url = "jdbc:h2:mem:A-DATABASE;INIT=CREATE SCHEMA IF NOT EXISTS myschema";
+ private static final String username = "sa";
+
+ @Test
+ void givenOldH2Database_whenCallgetSchemaMethod_thenThrowAbstractMethodError() throws SQLException {
+ Connection conn = DriverManager.getConnection(url, username, "");
+ assertNotNull(conn);
+ Assertions.assertThrows(AbstractMethodError.class, () -> conn.getSchema());
+ }
+}
diff --git a/core-java-modules/core-java-functional/README.md b/core-java-modules/core-java-functional/README.md
new file mode 100644
index 0000000000..ff12555376
--- /dev/null
+++ b/core-java-modules/core-java-functional/README.md
@@ -0,0 +1 @@
+## Relevant articles:
diff --git a/core-java-modules/core-java-functional/pom.xml b/core-java-modules/core-java-functional/pom.xml
new file mode 100644
index 0000000000..f00600c794
--- /dev/null
+++ b/core-java-modules/core-java-functional/pom.xml
@@ -0,0 +1,18 @@
+
+
+ 4.0.0
+ core-java-functional
+ 0.1.0-SNAPSHOT
+ core-java-functional
+ jar
+
+ com.baeldung.core-java-modules
+ core-java-modules
+ 0.0.1-SNAPSHOT
+ ../
+
+
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/Currying.java b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/Currying.java
new file mode 100644
index 0000000000..594fea4b8c
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/Currying.java
@@ -0,0 +1,26 @@
+package com.baeldung.functional;
+
+import java.util.function.Function;
+
+public class Currying {
+
+ private static Function> weight = mass -> gravity -> mass * gravity;
+
+ private static Function weightOnEarth = weight.apply(9.81);
+
+ private static Function weightOnMars = weight.apply(3.75);
+
+ public static Double weightOnEarth(Double mass) {
+ return weightOnEarth.apply(mass);
+ }
+
+ public static Double weightOnMars(Double mass) {
+ return weightOnMars.apply(mass);
+ }
+
+ public static Function weightOnEarth() {
+ final double gravity = 9.81;
+ return mass -> mass * gravity;
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/FirstClassFunctions.java b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/FirstClassFunctions.java
new file mode 100644
index 0000000000..13b408ab27
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/FirstClassFunctions.java
@@ -0,0 +1,24 @@
+package com.baeldung.functional;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class FirstClassFunctions {
+
+ public static List sortWithoutLambda(List numbers) {
+ Collections.sort(numbers, new Comparator() {
+ @Override
+ public int compare(Integer n1, Integer n2) {
+ return n1.compareTo(n2);
+ }
+ });
+ return numbers;
+ }
+
+ public static List sortWithLambda(List numbers) {
+ Collections.sort(numbers, (n1, n2) -> n1.compareTo(n2));
+ return numbers;
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/FunctionComposition.java b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/FunctionComposition.java
new file mode 100644
index 0000000000..57103be98a
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/FunctionComposition.java
@@ -0,0 +1,20 @@
+package com.baeldung.functional;
+
+import java.util.function.Function;
+
+public class FunctionComposition {
+
+ private static Function log = (value) -> Math.log(value);
+ private static Function sqrt = (value) -> Math.sqrt(value);
+
+ public static Double logThenSqrt(Double number) {
+ Function logThenSqrt = sqrt.compose(log);
+ return (logThenSqrt.apply(3.14));
+ }
+
+ public static Double sqrtThenLog(Double number) {
+ Function sqrtThenLog = sqrt.andThen(log);
+ return (sqrtThenLog.apply(3.14));
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/ImmutableData.java b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/ImmutableData.java
new file mode 100644
index 0000000000..738680f743
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/ImmutableData.java
@@ -0,0 +1,36 @@
+package com.baeldung.functional;
+
+public class ImmutableData {
+
+ private final String someData;
+
+ private final AnotherImmutableData anotherImmutableData;
+
+ public ImmutableData(final String someData, final AnotherImmutableData anotherImmutableData) {
+ this.someData = someData;
+ this.anotherImmutableData = anotherImmutableData;
+ }
+
+ public String getSomeData() {
+ return someData;
+ }
+
+ public AnotherImmutableData getAnotherImmutableData() {
+ return anotherImmutableData;
+ }
+
+ public class AnotherImmutableData {
+
+ private final Integer someOtherData;
+
+ public AnotherImmutableData(final Integer someData) {
+ this.someOtherData = someData;
+ }
+
+ public Integer getSomeOtherData() {
+ return someOtherData;
+ }
+
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/Monads.java b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/Monads.java
new file mode 100644
index 0000000000..c1223c73c7
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/Monads.java
@@ -0,0 +1,11 @@
+package com.baeldung.functional;
+
+import java.util.Optional;
+
+public class Monads {
+
+ public static Optional add(Optional val1, Optional val2) {
+ return val1.flatMap(first -> val2.flatMap(second -> Optional.of(first + second)));
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/PureFunctions.java b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/PureFunctions.java
new file mode 100644
index 0000000000..522b9de9eb
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/PureFunctions.java
@@ -0,0 +1,13 @@
+package com.baeldung.functional;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class PureFunctions {
+
+ public static Integer sum(List numbers) {
+ return numbers.stream()
+ .collect(Collectors.summingInt(Integer::intValue));
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/Recursion.java b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/Recursion.java
new file mode 100644
index 0000000000..d5492df69d
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/Recursion.java
@@ -0,0 +1,17 @@
+package com.baeldung.functional;
+
+public class Recursion {
+
+ public static Integer headRecursion(Integer number) {
+
+ return (number == 1) ? 1 : number * headRecursion(number - 1);
+
+ }
+
+ public static Integer tailRecursion(Integer number, Integer result) {
+
+ return (number == 1) ? result : tailRecursion(number - 1, result * number);
+
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/ReferentialTransparency.java b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/ReferentialTransparency.java
new file mode 100644
index 0000000000..1392cdd00a
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/ReferentialTransparency.java
@@ -0,0 +1,39 @@
+package com.baeldung.functional;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class ReferentialTransparency {
+
+ private static Logger logger = Logger.getGlobal();
+
+ public void main() {
+
+ String data = new SimpleData().setData("Baeldung")
+ .getData();
+ logger.log(Level.INFO, new SimpleData().setData("Baeldung")
+ .getData());
+ logger.log(Level.INFO, data);
+ logger.log(Level.INFO, "Baeldung");
+ }
+
+ public class SimpleData {
+
+ private Logger logger = Logger.getGlobal();
+
+ private String data;
+
+ public String getData() {
+ logger.log(Level.INFO, "Get data called for SimpleData");
+ return data;
+ }
+
+ public SimpleData setData(String data) {
+ logger.log(Level.INFO, "Set data called for SimpleData");
+ this.data = data;
+ return this;
+ }
+
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/CurryingUnitTest.java b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/CurryingUnitTest.java
new file mode 100644
index 0000000000..0cf96ed566
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/CurryingUnitTest.java
@@ -0,0 +1,22 @@
+package com.baeldung.functional;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.Test;
+
+public class CurryingUnitTest {
+
+ @Test
+ public void testWeightOnEarth() {
+
+ assertEquals(588.6, Currying.weightOnEarth(60.0), 0.1);
+
+ }
+
+ @Test
+ public void testWeightOnMars() {
+
+ assertEquals(225.0, Currying.weightOnMars(60.0), 0.1);
+
+ }
+}
diff --git a/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/FirstClassFunctionsUnitTest.java b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/FirstClassFunctionsUnitTest.java
new file mode 100644
index 0000000000..8056b44f21
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/FirstClassFunctionsUnitTest.java
@@ -0,0 +1,27 @@
+package com.baeldung.functional;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.Arrays;
+
+import org.junit.Test;
+
+public class FirstClassFunctionsUnitTest {
+
+ @Test
+ public void testSortingWithoutLambda() {
+
+ assertEquals(new Integer(8), FirstClassFunctions.sortWithoutLambda(Arrays.asList(new Integer(10), new Integer(8)))
+ .get(0));
+
+ }
+
+ @Test
+ public void testSortingWithLambda() {
+
+ assertEquals(new Integer(8), FirstClassFunctions.sortWithLambda(Arrays.asList(new Integer(10), new Integer(8)))
+ .get(0));
+
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/FunctionCompositionUnitTest.java b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/FunctionCompositionUnitTest.java
new file mode 100644
index 0000000000..48d8fb695c
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/FunctionCompositionUnitTest.java
@@ -0,0 +1,23 @@
+package com.baeldung.functional;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.Test;
+
+public class FunctionCompositionUnitTest {
+
+ @Test
+ public void testLogThenSqrt() {
+
+ assertEquals(1.07, FunctionComposition.logThenSqrt(3.14), 0.01);
+
+ }
+
+ @Test
+ public void testSqrtThenLog() {
+
+ assertEquals(0.57, FunctionComposition.sqrtThenLog(3.14), 0.01);
+
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/MonadsUnitTest.java b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/MonadsUnitTest.java
new file mode 100644
index 0000000000..8258eef59e
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/MonadsUnitTest.java
@@ -0,0 +1,19 @@
+package com.baeldung.functional;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.Optional;
+
+import org.junit.Test;
+
+public class MonadsUnitTest {
+
+ @Test
+ public void testOptionalAdd() {
+
+ assertEquals(5, Monads.add(Optional.of(new Integer(2)), Optional.of(new Integer(3)))
+ .get());
+
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/PureFunctionsUnitTets.java b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/PureFunctionsUnitTets.java
new file mode 100644
index 0000000000..23cca8bf8d
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/PureFunctionsUnitTets.java
@@ -0,0 +1,18 @@
+package com.baeldung.functional;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.Arrays;
+
+import org.junit.Test;
+
+public class PureFunctionsUnitTets {
+
+ @Test
+ public void testSortingWithoutLambda() {
+
+ assertEquals(new Integer(18), PureFunctions.sum(Arrays.asList(new Integer(10), new Integer(8))));
+
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/RecursionUnitTest.java b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/RecursionUnitTest.java
new file mode 100644
index 0000000000..aa406dc7ab
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/RecursionUnitTest.java
@@ -0,0 +1,23 @@
+package com.baeldung.functional;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.Test;
+
+public class RecursionUnitTest {
+
+ @Test
+ public void testHeadRecursion() {
+
+ assertEquals(120, Recursion.headRecursion(5));
+
+ }
+
+ @Test
+ public void testTailRecursion() {
+
+ assertEquals(120, Recursion.tailRecursion(5, 1));
+
+ }
+
+}
diff --git a/core-java-modules/core-java-jar/.gitignore b/core-java-modules/core-java-jar/.gitignore
new file mode 100644
index 0000000000..ba516c02b5
--- /dev/null
+++ b/core-java-modules/core-java-jar/.gitignore
@@ -0,0 +1 @@
+!src/test/resources/example-jar/stripe-0.0.1-SNAPSHOT.jar
diff --git a/core-java-modules/core-java-jar/README.md b/core-java-modules/core-java-jar/README.md
index f6bb7677d4..f83ea496ab 100644
--- a/core-java-modules/core-java-jar/README.md
+++ b/core-java-modules/core-java-jar/README.md
@@ -7,3 +7,4 @@ This module contains articles about JAR files
- [How to Create an Executable JAR with Maven](http://www.baeldung.com/executable-jar-with-maven)
- [Importance of Main Manifest Attribute in a Self-Executing JAR](http://www.baeldung.com/java-jar-executable-manifest-main-class)
- [Guide to Creating and Running a Jar File in Java](https://www.baeldung.com/java-create-jar)
+- [Get Names of Classes Inside a JAR File](https://www.baeldung.com/jar-file-get-class-names)
diff --git a/core-java-modules/core-java-jar/src/main/java/com/baeldung/jar/GetClassNamesFromJar.java b/core-java-modules/core-java-jar/src/main/java/com/baeldung/jar/GetClassNamesFromJar.java
new file mode 100644
index 0000000000..0d8a67dbd6
--- /dev/null
+++ b/core-java-modules/core-java-jar/src/main/java/com/baeldung/jar/GetClassNamesFromJar.java
@@ -0,0 +1,43 @@
+package com.baeldung.jar;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+public class GetClassNamesFromJar {
+
+ public static Set getClassNamesFromJarFile(File givenFile) throws IOException {
+ Set classNames = new HashSet<>();
+ try (JarFile jarFile = new JarFile(givenFile)) {
+ Enumeration e = jarFile.entries();
+ while (e.hasMoreElements()) {
+ JarEntry jarEntry = e.nextElement();
+ if (jarEntry.getName().endsWith(".class")) {
+ String className = jarEntry.getName()
+ .replace("/", ".")
+ .replace(".class", "");
+ classNames.add(className);
+ }
+ }
+ return classNames;
+ }
+ }
+
+ public static Set getClassesFromJarFile(File jarFile) throws IOException, ClassNotFoundException {
+ Set classNames = getClassNamesFromJarFile(jarFile);
+ Set classes = new HashSet<>(classNames.size());
+ try (URLClassLoader cl = URLClassLoader.newInstance(new URL[] { new URL("jar:file:" + jarFile + "!/") })) {
+ for (String name : classNames) {
+ Class clazz = cl.loadClass(name); // Loading the class by its name
+ classes.add(clazz);
+ }
+ }
+ return classes;
+ }
+}
diff --git a/core-java-modules/core-java-jar/src/test/java/com/baeldung/jar/GetClassNamesFromJarUnitTest.java b/core-java-modules/core-java-jar/src/test/java/com/baeldung/jar/GetClassNamesFromJarUnitTest.java
new file mode 100644
index 0000000000..7af3ff59fd
--- /dev/null
+++ b/core-java-modules/core-java-jar/src/test/java/com/baeldung/jar/GetClassNamesFromJarUnitTest.java
@@ -0,0 +1,39 @@
+package com.baeldung.jar;
+
+import com.google.common.collect.Sets;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class GetClassNamesFromJarUnitTest {
+ private static final String JAR_PATH = "example-jar/stripe-0.0.1-SNAPSHOT.jar";
+ private static final Set EXPECTED_CLASS_NAMES = Sets.newHashSet(
+ "com.baeldung.stripe.StripeApplication",
+ "com.baeldung.stripe.ChargeRequest",
+ "com.baeldung.stripe.StripeService",
+ "com.baeldung.stripe.ChargeRequest$Currency",
+ "com.baeldung.stripe.ChargeController",
+ "com.baeldung.stripe.CheckoutController");
+
+ @Test
+ public void givenJarFilePath_whenLoadClassNames_thenGetClassNames() throws IOException, URISyntaxException {
+ File jarFile = new File(Objects.requireNonNull(getClass().getClassLoader().getResource(JAR_PATH)).toURI());
+ Set classNames = GetClassNamesFromJar.getClassNamesFromJarFile(jarFile);
+ Assert.assertEquals(EXPECTED_CLASS_NAMES, classNames);
+ }
+
+ @Test
+ public void givenJarFilePath_whenLoadClass_thenGetClassObjects() throws IOException, ClassNotFoundException, URISyntaxException {
+ File jarFile = new File(Objects.requireNonNull(getClass().getClassLoader().getResource(JAR_PATH)).toURI());
+ Set classes = GetClassNamesFromJar.getClassesFromJarFile(jarFile);
+ Set names = classes.stream().map(Class::getName).collect(Collectors.toSet());
+ Assert.assertEquals(EXPECTED_CLASS_NAMES, names);
+ }
+}
diff --git a/core-java-modules/core-java-jar/src/test/resources/example-jar/stripe-0.0.1-SNAPSHOT.jar b/core-java-modules/core-java-jar/src/test/resources/example-jar/stripe-0.0.1-SNAPSHOT.jar
new file mode 100644
index 0000000000..213d7f9400
Binary files /dev/null and b/core-java-modules/core-java-jar/src/test/resources/example-jar/stripe-0.0.1-SNAPSHOT.jar differ
diff --git a/core-java-modules/core-java-lang-3/README.md b/core-java-modules/core-java-lang-3/README.md
index 598014bb92..0707d0de98 100644
--- a/core-java-modules/core-java-lang-3/README.md
+++ b/core-java-modules/core-java-lang-3/README.md
@@ -7,4 +7,5 @@ This module contains articles about core features in the Java language
- [When are Static Variables Initialized in Java?](https://www.baeldung.com/java-static-variables-initialization)
- [Checking if a Class Exists in Java](https://www.baeldung.com/java-check-class-exists)
- [The Difference Between a.getClass() and A.class in Java](https://www.baeldung.com/java-getclass-vs-class)
+- [Constants in Java: Patterns and Anti-Patterns](https://www.baeldung.com/java-constants-good-practices)
- [[<-- Prev]](/core-java-modules/core-java-lang-2)
diff --git a/core-java-modules/core-java-lang-math-2/README.md b/core-java-modules/core-java-lang-math-2/README.md
index 69ee00b5a5..a98ff863ac 100644
--- a/core-java-modules/core-java-lang-math-2/README.md
+++ b/core-java-modules/core-java-lang-math-2/README.md
@@ -9,9 +9,9 @@
- [Check If Two Rectangles Overlap In Java](https://www.baeldung.com/java-check-if-two-rectangles-overlap)
- [Calculate the Distance Between Two Points in Java](https://www.baeldung.com/java-distance-between-two-points)
- [Find the Intersection of Two Lines in Java](https://www.baeldung.com/java-intersection-of-two-lines)
-- [Round Up to the Nearest Hundred](https://www.baeldung.com/java-round-up-nearest-hundred)
+- [Round Up to the Nearest Hundred in Java](https://www.baeldung.com/java-round-up-nearest-hundred)
- [Convert Latitude and Longitude to a 2D Point in Java](https://www.baeldung.com/java-convert-latitude-longitude)
- [Debugging with Eclipse](https://www.baeldung.com/eclipse-debugging)
- [Matrix Multiplication in Java](https://www.baeldung.com/java-matrix-multiplication)
-- [Largest Power of 2 That Is Less Than the Given Number](https://www.baeldung.com/java-largest-power-of-2-less-than-number)
+- [Largest Power of 2 That Is Less Than the Given Number with Java](https://www.baeldung.com/java-largest-power-of-2-less-than-number)
- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math)
diff --git a/core-java-modules/core-java-lang/src/main/java/com/baeldung/finalize/CrashedFinalizable.java b/core-java-modules/core-java-lang/src/main/java/com/baeldung/finalize/CrashedFinalizable.java
new file mode 100644
index 0000000000..d5ee27591b
--- /dev/null
+++ b/core-java-modules/core-java-lang/src/main/java/com/baeldung/finalize/CrashedFinalizable.java
@@ -0,0 +1,28 @@
+package com.baeldung.finalize;
+
+import java.lang.ref.ReferenceQueue;
+import java.lang.reflect.Field;
+
+public class CrashedFinalizable {
+ public static void main(String[] args) throws ReflectiveOperationException {
+ for (int i = 0; ; i++) {
+ new CrashedFinalizable();
+ if ((i % 1_000_000) == 0) {
+ Class> finalizerClass = Class.forName("java.lang.ref.Finalizer");
+ Field queueStaticField = finalizerClass.getDeclaredField("queue");
+ queueStaticField.setAccessible(true);
+ ReferenceQueue
+
+
+
+ com.squareup.retrofit2
+ retrofit
+ ${retrofit.version}
+
+
+ com.squareup.retrofit2
+ converter-gson
+ ${retrofit.version}
+
@@ -76,6 +88,7 @@
1.0.3
9.4.19.v20190610
2.2.11
+ 2.3.0
5.1.9.RELEASE
1.0.3
3.2.12.RELEASE
diff --git a/libraries-http-2/src/main/java/com/baeldung/retrofit/dynamic/GitHubDynamicApi.java b/libraries-http-2/src/main/java/com/baeldung/retrofit/dynamic/GitHubDynamicApi.java
new file mode 100644
index 0000000000..5356c12b26
--- /dev/null
+++ b/libraries-http-2/src/main/java/com/baeldung/retrofit/dynamic/GitHubDynamicApi.java
@@ -0,0 +1,19 @@
+package com.baeldung.retrofit.dynamic;
+
+import com.baeldung.retrofit.models.Contributor;
+import com.baeldung.retrofit.models.Repository;
+import retrofit2.Call;
+import retrofit2.http.GET;
+import retrofit2.http.Path;
+import retrofit2.http.Url;
+
+import java.util.List;
+
+public interface GitHubDynamicApi {
+
+ @GET
+ Call> reposList(@Url String url);
+
+ @GET("{fullUrl}")
+ Call> contributorsList(@Path(value = "fullUrl", encoded = true) String fullUrl);
+}
diff --git a/libraries-http-2/src/main/java/com/baeldung/retrofit/dynamic/GitHubDynamicApiApp.java b/libraries-http-2/src/main/java/com/baeldung/retrofit/dynamic/GitHubDynamicApiApp.java
new file mode 100644
index 0000000000..06f6b3cef7
--- /dev/null
+++ b/libraries-http-2/src/main/java/com/baeldung/retrofit/dynamic/GitHubDynamicApiApp.java
@@ -0,0 +1,13 @@
+package com.baeldung.retrofit.dynamic;
+
+import java.io.IOException;
+import java.util.List;
+
+public class GitHubDynamicApiApp {
+
+ public static void main(String[] args) throws IOException {
+ String url = "https://api.github.com/users/eugenp/repos";
+ List topContributors = new GitHubDynamicApiService().getTopContributors(url);
+ topContributors.forEach(System.out::println);
+ }
+}
diff --git a/libraries-http-2/src/main/java/com/baeldung/retrofit/dynamic/GitHubDynamicApiService.java b/libraries-http-2/src/main/java/com/baeldung/retrofit/dynamic/GitHubDynamicApiService.java
new file mode 100644
index 0000000000..cb8e95f2d5
--- /dev/null
+++ b/libraries-http-2/src/main/java/com/baeldung/retrofit/dynamic/GitHubDynamicApiService.java
@@ -0,0 +1,44 @@
+package com.baeldung.retrofit.dynamic;
+
+import com.baeldung.retrofit.models.Contributor;
+import com.baeldung.retrofit.models.Repository;
+import retrofit2.Retrofit;
+import retrofit2.converter.gson.GsonConverterFactory;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+class GitHubDynamicApiService {
+
+ private GitHubDynamicApi gitHubDynamicApi;
+
+ GitHubDynamicApiService() {
+ Retrofit retrofit = new Retrofit.Builder().baseUrl("https://api.github.com/").addConverterFactory(GsonConverterFactory.create()).build();
+
+ gitHubDynamicApi = retrofit.create(GitHubDynamicApi.class);
+ }
+
+ List getTopContributors(String url) throws IOException {
+ List repos = gitHubDynamicApi.reposList(url).execute().body();
+
+ repos = repos != null ? repos : Collections.emptyList();
+
+ return repos.stream().flatMap(repo -> getContributors("repos/eugenp/"+repo+"/contributors")).sorted((a, b) -> b.getContributions() - a.getContributions()).map(com.baeldung.retrofit.models.Contributor::getName).distinct().sorted().collect(Collectors.toList());
+ }
+
+ private Stream getContributors(String fullUrl) {
+ List contributors = null;
+ try {
+ contributors = gitHubDynamicApi.contributorsList(fullUrl).execute().body();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ contributors = contributors != null ? contributors : Collections.emptyList();
+
+ return contributors.stream().filter(c -> c.getContributions() > 100);
+ }
+}
diff --git a/libraries-http-2/src/main/java/com/baeldung/retrofit/models/Contributor.java b/libraries-http-2/src/main/java/com/baeldung/retrofit/models/Contributor.java
new file mode 100644
index 0000000000..f98b19de96
--- /dev/null
+++ b/libraries-http-2/src/main/java/com/baeldung/retrofit/models/Contributor.java
@@ -0,0 +1,33 @@
+package com.baeldung.retrofit.models;
+
+import com.google.gson.annotations.SerializedName;
+
+public class Contributor {
+
+ @SerializedName("login")
+ private String name;
+
+ private Integer contributions;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Integer getContributions() {
+ return contributions;
+ }
+
+ public void setContributions(Integer contributions) {
+ this.contributions = contributions;
+ }
+
+ @Override
+ public String toString() {
+ return "Contributer [name=" + name + ", contributions=" + contributions + "]";
+ }
+
+}
diff --git a/libraries-http-2/src/main/java/com/baeldung/retrofit/models/Repository.java b/libraries-http-2/src/main/java/com/baeldung/retrofit/models/Repository.java
new file mode 100644
index 0000000000..6bc91eb772
--- /dev/null
+++ b/libraries-http-2/src/main/java/com/baeldung/retrofit/models/Repository.java
@@ -0,0 +1,30 @@
+package com.baeldung.retrofit.models;
+
+public class Repository {
+
+ private String name;
+
+ private String description;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ @Override
+ public String toString() {
+ return "Repository [name=" + name + ", description=" + description + "]";
+ }
+
+}
diff --git a/netflix-modules/README.md b/netflix-modules/README.md
index c126bbdf5b..21d6958dab 100644
--- a/netflix-modules/README.md
+++ b/netflix-modules/README.md
@@ -2,3 +2,6 @@
This module contains articles about Netflix.
+### Relevant Articles:
+
+- [Introduction to Netflix Mantis](https://www.baeldung.com/java-netflix-mantis)
diff --git a/patterns/design-patterns-architectural/README.md b/patterns/design-patterns-architectural/README.md
index 5b6011c159..ae6781c66c 100644
--- a/patterns/design-patterns-architectural/README.md
+++ b/patterns/design-patterns-architectural/README.md
@@ -1,4 +1,4 @@
### Relevant Articles:
-- [Service Locator Pattern](https://www.baeldung.com/java-service-locator-pattern)
+- [Service Locator Pattern and Java Implementation](https://www.baeldung.com/java-service-locator-pattern)
- [The DAO Pattern in Java](https://www.baeldung.com/java-dao-pattern)
- [DAO vs Repository Patterns](https://www.baeldung.com/java-dao-vs-repository)
diff --git a/patterns/design-patterns-behavioral/src/main/java/com/baeldung/nulls/UsingOptional.java b/patterns/design-patterns-behavioral/src/main/java/com/baeldung/nulls/UsingOptional.java
index d5dd56e760..099864589c 100644
--- a/patterns/design-patterns-behavioral/src/main/java/com/baeldung/nulls/UsingOptional.java
+++ b/patterns/design-patterns-behavioral/src/main/java/com/baeldung/nulls/UsingOptional.java
@@ -1,23 +1,52 @@
package com.baeldung.nulls;
+import java.util.List;
import java.util.Optional;
+import static java.util.Collections.emptyList;
+
public class UsingOptional {
- public Optional
\ No newline at end of file
diff --git a/spring-security-modules/spring-security-oauth2-sso/spring-security-sso-auth-server/pom.xml b/spring-security-modules/spring-security-oauth2-sso/spring-security-sso-auth-server/pom.xml
index 3537c01e46..20a43eaf04 100644
--- a/spring-security-modules/spring-security-oauth2-sso/spring-security-sso-auth-server/pom.xml
+++ b/spring-security-modules/spring-security-oauth2-sso/spring-security-sso-auth-server/pom.xml
@@ -8,7 +8,7 @@
com.baeldung
- spring-security-sso
+ spring-security-oauth2-sso
1.0.0-SNAPSHOT
diff --git a/spring-security-modules/spring-security-oauth2-sso/spring-security-sso-kerberos/pom.xml b/spring-security-modules/spring-security-oauth2-sso/spring-security-sso-kerberos/pom.xml
index a67cc4af83..f17ca171a5 100644
--- a/spring-security-modules/spring-security-oauth2-sso/spring-security-sso-kerberos/pom.xml
+++ b/spring-security-modules/spring-security-oauth2-sso/spring-security-sso-kerberos/pom.xml
@@ -7,7 +7,7 @@
com.baeldung
- spring-security-sso
+ spring-security-oauth2-sso
1.0.0-SNAPSHOT
@@ -91,5 +91,9 @@
+
+
+ com.baeldung.intro.Application
+
\ No newline at end of file
diff --git a/spring-security-modules/spring-security-oauth2-sso/spring-security-sso-ui-2/pom.xml b/spring-security-modules/spring-security-oauth2-sso/spring-security-sso-ui-2/pom.xml
index 0645ba3593..514dd0d0f7 100644
--- a/spring-security-modules/spring-security-oauth2-sso/spring-security-sso-ui-2/pom.xml
+++ b/spring-security-modules/spring-security-oauth2-sso/spring-security-sso-ui-2/pom.xml
@@ -8,7 +8,7 @@
com.baeldung
- spring-security-sso
+ spring-security-oauth2-sso
1.0.0-SNAPSHOT
diff --git a/spring-security-modules/spring-security-oauth2-sso/spring-security-sso-ui/pom.xml b/spring-security-modules/spring-security-oauth2-sso/spring-security-sso-ui/pom.xml
index d34317a4b0..5076b1878b 100644
--- a/spring-security-modules/spring-security-oauth2-sso/spring-security-sso-ui/pom.xml
+++ b/spring-security-modules/spring-security-oauth2-sso/spring-security-sso-ui/pom.xml
@@ -8,7 +8,7 @@
com.baeldung
- spring-security-sso
+ spring-security-oauth2-sso
1.0.0-SNAPSHOT
diff --git a/vavr/src/test/java/com/baeldung/vavr/VavrUnitTest.java b/vavr/src/test/java/com/baeldung/vavr/VavrUnitTest.java
index 7beb75632e..b1a9405605 100644
--- a/vavr/src/test/java/com/baeldung/vavr/VavrUnitTest.java
+++ b/vavr/src/test/java/com/baeldung/vavr/VavrUnitTest.java
@@ -93,6 +93,37 @@ public class VavrUnitTest {
assertEquals("JavaVavr 4", transformed);
}
+ @Test
+ public void editTupleValueForNewTupleInstance(){
+ final Tuple2 java9 = Tuple.of("Java", 8);
+ final Tuple2 transformed = java9.update2(9);
+ int num = transformed._2();
+ assertEquals(9,num);
+ }
+
+ @Test
+ public void editTupleValueForSameInstance(){
+ Tuple2 java9 = Tuple.of("Java", 8);
+ java9 = java9.update2(9);
+ final int num = java9._2();
+ assertEquals(9,num);
+ }
+
+ @Test
+ public void getNumberOfElementTuple(){
+ Tuple2 java8 = Tuple.of("Java", 8);
+ Tuple3 java8Triple = Tuple.of("Java", 8, 1.8);
+ Tuple3 java8TripleWnull = Tuple.of("Java", null, 1.8);
+
+ int num = java8.arity();
+ int numTriple = java8Triple.arity();
+ int numTripleWnull = java8TripleWnull.arity();
+ assertEquals(2,num);
+ assertEquals(3,numTriple);
+ assertEquals(3,numTripleWnull);
+ }
+
+
/*
* Functions
*/