diff --git a/jooq/pom.xml b/jooq/pom.xml
new file mode 100644
index 0000000000..ef287d0292
--- /dev/null
+++ b/jooq/pom.xml
@@ -0,0 +1,46 @@
+
+
+
+ parent-modules
+ com.baeldung
+ 1.0.0-SNAPSHOT
+
+ 4.0.0
+
+ jooq
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.8
+ 1.8
+
+
+
+
+
+
+
+ org.jooq
+ jool
+ ${jool.version}
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+
+ 0.9.12
+ 4.12
+
+
+
+
\ No newline at end of file
diff --git a/jooq/src/test/java/com/baeldung/JOOLTest.java b/jooq/src/test/java/com/baeldung/JOOLTest.java
new file mode 100644
index 0000000000..18fca1f67a
--- /dev/null
+++ b/jooq/src/test/java/com/baeldung/JOOLTest.java
@@ -0,0 +1,206 @@
+package com.baeldung;
+
+
+import org.jooq.lambda.Seq;
+import org.jooq.lambda.Unchecked;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.TestCase.assertEquals;
+import static org.jooq.lambda.tuple.Tuple.tuple;
+
+public class JOOLTest {
+ @Test
+ public void givenSeq_whenCheckContains_shouldReturnTrue() {
+ List concat = Seq.of(1, 2, 3).concat(Seq.of(4, 5, 6)).toList();
+
+ assertEquals(concat, Arrays.asList(1, 2, 3, 4, 5, 6));
+
+
+ assertTrue(Seq.of(1, 2, 3, 4).contains(2));
+
+
+ assertTrue(Seq.of(1, 2, 3, 4).containsAll(2, 3));
+
+
+ assertTrue(Seq.of(1, 2, 3, 4).containsAny(2, 5));
+ }
+
+ @Test
+ public void givenStreams_whenJoin_shouldHaveElementsFromTwoStreams() {
+ //given
+ Stream left = Stream.of(1, 2, 4);
+ Stream right = Stream.of(1, 2, 3);
+
+ //when
+ List rightCollected = right.collect(Collectors.toList());
+ List collect = left.filter(rightCollected::contains).collect(Collectors.toList());
+
+ //then
+ assertEquals(collect, Arrays.asList(1, 2));
+ }
+
+ @Test
+ public void givenSeq_whenJoin_shouldHaveElementsFromBothSeq() {
+ assertEquals(
+ Seq.of(1, 2, 4).innerJoin(Seq.of(1, 2, 3), (a, b) -> a == b).toList(),
+ Arrays.asList(tuple(1, 1), tuple(2, 2))
+ );
+
+
+ assertEquals(
+ Seq.of(1, 2, 4).leftOuterJoin(Seq.of(1, 2, 3), (a, b) -> a == b).toList(),
+ Arrays.asList(tuple(1, 1), tuple(2, 2), tuple(4, null))
+ );
+
+ assertEquals(
+ Seq.of(1, 2, 4).rightOuterJoin(Seq.of(1, 2, 3), (a, b) -> a == b).toList(),
+ Arrays.asList(tuple(1, 1), tuple(2, 2), tuple(null, 3))
+ );
+
+ assertEquals(
+ Seq.of(1, 2).crossJoin(Seq.of("A", "B")).toList(),
+ Arrays.asList(tuple(1, "A"), tuple(1, "B"), tuple(2, "A"), tuple(2, "B"))
+ );
+ }
+
+ @Test
+ public void givenSeq_whenManipulateSeq_seqShouldHaveNewElementsInIt() {
+ assertEquals(
+ Seq.of(1, 2, 3).cycle().limit(9).toList(),
+ Arrays.asList(1, 2, 3, 1, 2, 3, 1, 2, 3)
+ );
+
+ assertEquals(
+ Seq.of(1, 2, 3).duplicate().map((first, second) -> tuple(first.toList(), second.toList())),
+ tuple(Arrays.asList(1, 2, 3), Arrays.asList(1, 2, 3))
+ );
+
+ assertEquals(
+ Seq.of(1, 2, 3, 4).intersperse(0).toList(),
+ Arrays.asList(1, 0, 2, 0, 3, 0, 4)
+ );
+
+ assertEquals(
+ Seq.of(1, 2, 3, 4, 5).shuffle().toList().size(),
+ 5
+ );
+
+ assertEquals(
+ Seq.of(1, 2, 3, 4).partition(i -> i > 2).map((first, second) -> tuple(first.toList(), second.toList())),
+ tuple(Arrays.asList(3, 4), Arrays.asList(1, 2))
+
+ );
+
+ assertEquals(
+ Seq.of(1, 2, 3, 4).reverse().toList(),
+ Arrays.asList(4, 3, 2, 1)
+ );
+ }
+
+ @Test
+ public void givenSeq_whenGroupByAndFold_shouldReturnProperSeq() {
+
+ Map> expectedAfterGroupBy = new HashMap<>();
+ expectedAfterGroupBy.put(1, Arrays.asList(1, 3));
+ expectedAfterGroupBy.put(0, Arrays.asList(2, 4));
+
+ assertEquals(
+ Seq.of(1, 2, 3, 4).groupBy(i -> i % 2),
+ expectedAfterGroupBy
+ );
+
+
+ assertEquals(
+ Seq.of("a", "b", "c").foldLeft("!", (u, t) -> u + t),
+ "!abc"
+ );
+
+
+ assertEquals(
+ Seq.of("a", "b", "c").foldRight("!", (t, u) -> t + u),
+ "abc!"
+ );
+ }
+
+ @Test
+ public void givenSeq_whenUsingSeqWhile_shouldBehaveAsWhileLoop() {
+
+ assertEquals(
+ Seq.of(1, 2, 3, 4, 5).skipWhile(i -> i < 3).toList(),
+ Arrays.asList(3, 4, 5)
+ );
+
+ assertEquals(
+ Seq.of(1, 2, 3, 4, 5).skipUntil(i -> i == 3).toList(),
+ Arrays.asList(3, 4, 5)
+ );
+ }
+
+ @Test
+ public void givenSeq_whenZip_shouldHaveZippedSeq() {
+
+ assertEquals(
+ Seq.of(1, 2, 3).zip(Seq.of("a", "b", "c")).toList(),
+ Arrays.asList(tuple(1, "a"), tuple(2, "b"), tuple(3, "c"))
+ );
+
+ assertEquals(
+ Seq.of(1, 2, 3).zip(Seq.of("a", "b", "c"), (x, y) -> x + ":" + y).toList(),
+ Arrays.asList("1:a", "2:b", "3:c")
+ );
+
+
+ assertEquals(
+ Seq.of("a", "b", "c").zipWithIndex().toList(),
+ Arrays.asList(tuple("a", 0L), tuple("b", 1L), tuple("c", 2L))
+ );
+ }
+
+
+ public Integer methodThatThrowsChecked(String arg) throws Exception {
+ return arg.length();
+ }
+
+ @Test
+ public void givenOperationThatThrowsCheckedException_whenExecuteAndNeedToWrapCheckedIntoUnchecked_shouldPass() {
+ //when
+ List collect = Stream.of("a", "b", "c").map(elem -> {
+ try {
+ return methodThatThrowsChecked(elem);
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+ }).collect(Collectors.toList());
+
+ //then
+ assertEquals(
+ collect,
+ Arrays.asList(1, 1, 1)
+ );
+ }
+
+
+ @Test
+ public void givenOperationThatThrowsCheckedException_whenExecuteUsingUncheckedFuction_shouldPass() {
+ //when
+ List collect = Stream.of("a", "b", "c")
+ .map(Unchecked.function(elem -> methodThatThrowsChecked(elem)))
+ .collect(Collectors.toList());
+
+ //then
+ assertEquals(
+ collect,
+ Arrays.asList(1, 1, 1)
+ );
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index ad60436151..9e95537775 100644
--- a/pom.xml
+++ b/pom.xml
@@ -66,6 +66,7 @@
jaxb
jee7
jjwt
+ jooq
jpa-storedprocedure
jsf
json-path