diff --git a/libraries-3/pom.xml b/libraries-3/pom.xml
index 2cfebd57ce..1dbe6b2435 100644
--- a/libraries-3/pom.xml
+++ b/libraries-3/pom.xml
@@ -67,7 +67,12 @@
org.cactoos
cactoos
${cactoos.version}
-
+
+
+ org.cache2k
+ cache2k-base-bom
+ ${cache2k.version}
+ pom
@@ -88,5 +93,6 @@
0.43
2.7.2
+ 1.2.3.Final
diff --git a/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelper.java b/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelper.java
new file mode 100644
index 0000000000..dc984e5f0b
--- /dev/null
+++ b/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelper.java
@@ -0,0 +1,41 @@
+package com.baeldung.cache2k;
+
+import java.util.Objects;
+
+import org.cache2k.Cache;
+import org.cache2k.Cache2kBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ProductHelper {
+
+ final Logger LOGGER = LoggerFactory.getLogger(ProductHelper.class);
+
+ private Cache cachedDiscounts;
+
+ public ProductHelper() {
+ cachedDiscounts = Cache2kBuilder.of(String.class, Integer.class)
+ .name("discount")
+ .eternal(true)
+ .entryCapacity(100)
+ .build();
+
+ initDiscountCache("Sports", 20);
+ }
+
+ public void initDiscountCache(String productType, Integer value) {
+ cachedDiscounts.put(productType, value);
+ }
+
+ public Integer getDiscount(String productType) {
+ Integer discount = cachedDiscounts.get(productType);
+ if (Objects.isNull(discount)) {
+ LOGGER.info("Discount for {} not found.", productType);
+ discount = 0;
+ } else {
+ LOGGER.info("Discount for {} found.", productType);
+ }
+ return discount;
+ }
+
+}
diff --git a/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelperUsingLoader.java b/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelperUsingLoader.java
new file mode 100644
index 0000000000..787a78cd36
--- /dev/null
+++ b/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelperUsingLoader.java
@@ -0,0 +1,41 @@
+package com.baeldung.cache2k;
+
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
+import org.cache2k.Cache;
+import org.cache2k.Cache2kBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ProductHelperUsingLoader {
+
+ final Logger LOGGER = LoggerFactory.getLogger(ProductHelperUsingLoader.class);
+
+ private Cache cachedDiscounts;
+
+ public ProductHelperUsingLoader() {
+ cachedDiscounts = Cache2kBuilder.of(String.class, Integer.class)
+ .name("discount-loader")
+ .eternal(false)
+ .expireAfterWrite(10, TimeUnit.MILLISECONDS)
+ .entryCapacity(100)
+ .loader((key) -> {
+ LOGGER.info("Calculating discount for {}.", key);
+ return "Sports".equalsIgnoreCase(key) ? 20 : 10;
+ })
+ .build();
+ }
+
+ public Integer getDiscount(String productType) {
+ Integer discount = cachedDiscounts.get(productType);
+ if (Objects.isNull(discount)) {
+ LOGGER.info("Discount for {} not found.", productType);
+ discount = 0;
+ } else {
+ LOGGER.info("Discount for {} found.", productType);
+ }
+ return discount;
+ }
+
+}
diff --git a/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelperWithEventListener.java b/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelperWithEventListener.java
new file mode 100644
index 0000000000..5b9eb28c68
--- /dev/null
+++ b/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelperWithEventListener.java
@@ -0,0 +1,49 @@
+package com.baeldung.cache2k;
+
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
+import org.cache2k.Cache;
+import org.cache2k.Cache2kBuilder;
+import org.cache2k.CacheEntry;
+import org.cache2k.event.CacheEntryCreatedListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ProductHelperWithEventListener {
+
+ final Logger LOGGER = LoggerFactory.getLogger(ProductHelperWithEventListener.class);
+
+ private Cache cachedDiscounts;
+
+ public ProductHelperWithEventListener() {
+ cachedDiscounts = Cache2kBuilder.of(String.class, Integer.class)
+ .name("discount-listener")
+ .eternal(false)
+ .expireAfterWrite(10, TimeUnit.MILLISECONDS)
+ .entryCapacity(100)
+ .loader((key) -> {
+ LOGGER.info("Calculating discount for {}.", key);
+ return "Sports".equalsIgnoreCase(key) ? 20 : 10;
+ })
+ .addListener(new CacheEntryCreatedListener() {
+ @Override
+ public void onEntryCreated(Cache cache, CacheEntry entry) {
+ LOGGER.info("Entry created: [{}, {}].", entry.getKey(), entry.getValue());
+ }
+ })
+ .build();
+ }
+
+ public Integer getDiscount(String productType) {
+ Integer discount = cachedDiscounts.get(productType);
+ if (Objects.isNull(discount)) {
+ LOGGER.info("Discount for {} not found.", productType);
+ discount = 0;
+ } else {
+ LOGGER.info("Discount for {} found.", productType);
+ }
+ return discount;
+ }
+
+}
diff --git a/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelperWithExpiry.java b/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelperWithExpiry.java
new file mode 100644
index 0000000000..b0bf8f90de
--- /dev/null
+++ b/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelperWithExpiry.java
@@ -0,0 +1,43 @@
+package com.baeldung.cache2k;
+
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
+import org.cache2k.Cache;
+import org.cache2k.Cache2kBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ProductHelperWithExpiry {
+
+ final Logger LOGGER = LoggerFactory.getLogger(ProductHelperWithExpiry.class);
+
+ private Cache cachedDiscounts;
+
+ public ProductHelperWithExpiry() {
+ cachedDiscounts = Cache2kBuilder.of(String.class, Integer.class)
+ .name("discount-expiry")
+ .eternal(false)
+ .expireAfterWrite(5, TimeUnit.MILLISECONDS)
+ .entryCapacity(100)
+ .build();
+
+ initDiscountCache("Sports", 20);
+ }
+
+ public void initDiscountCache(String productType, Integer value) {
+ cachedDiscounts.put(productType, value);
+ }
+
+ public Integer getDiscount(String productType) {
+ Integer discount = cachedDiscounts.get(productType);
+ if (Objects.isNull(discount)) {
+ LOGGER.info("Discount for {} not found.", productType);
+ discount = 0;
+ } else {
+ LOGGER.info("Discount for {} found.", productType);
+ }
+ return discount;
+ }
+
+}
diff --git a/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperUnitTest.java b/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperUnitTest.java
new file mode 100644
index 0000000000..69da2591dd
--- /dev/null
+++ b/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperUnitTest.java
@@ -0,0 +1,17 @@
+package com.baeldung.cache2k;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class ProductHelperUnitTest {
+
+ ProductHelper productHelper = new ProductHelper();
+
+ @Test
+ public void whenInvokedGetDiscount_thenGetItFromCache() {
+ assertTrue(productHelper.getDiscount("Sports") == 20);
+ assertTrue(productHelper.getDiscount("Electronics") == 0);
+ }
+
+}
diff --git a/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperUsingLoaderUnitTest.java b/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperUsingLoaderUnitTest.java
new file mode 100644
index 0000000000..2656e75cab
--- /dev/null
+++ b/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperUsingLoaderUnitTest.java
@@ -0,0 +1,17 @@
+package com.baeldung.cache2k;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class ProductHelperUsingLoaderUnitTest {
+
+ ProductHelperUsingLoader productHelper = new ProductHelperUsingLoader();
+
+ @Test
+ public void whenInvokedGetDiscount_thenPopulateCache() {
+ assertTrue(productHelper.getDiscount("Sports") == 20);
+ assertTrue(productHelper.getDiscount("Electronics") == 10);
+ }
+
+}
diff --git a/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperWithEventListenerUnitTest.java b/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperWithEventListenerUnitTest.java
new file mode 100644
index 0000000000..7bf08232f4
--- /dev/null
+++ b/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperWithEventListenerUnitTest.java
@@ -0,0 +1,16 @@
+package com.baeldung.cache2k;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class ProductHelperWithEventListenerUnitTest {
+
+ ProductHelperWithEventListener productHelper = new ProductHelperWithEventListener();
+
+ @Test
+ public void whenEntryAddedInCache_thenEventListenerCalled() {
+ assertTrue(productHelper.getDiscount("Sports") == 20);
+ }
+
+}
diff --git a/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperWithExpiryUnitTest.java b/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperWithExpiryUnitTest.java
new file mode 100644
index 0000000000..65feba2c70
--- /dev/null
+++ b/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperWithExpiryUnitTest.java
@@ -0,0 +1,18 @@
+package com.baeldung.cache2k;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class ProductHelperWithExpiryUnitTest {
+
+ ProductHelperWithExpiry productHelper = new ProductHelperWithExpiry();
+
+ @Test
+ public void whenInvokedGetDiscountForExpiredProduct_thenNoDiscount() throws InterruptedException {
+ assertTrue(productHelper.getDiscount("Sports") == 20);
+ Thread.sleep(20);
+ assertTrue(productHelper.getDiscount("Sports") == 0);
+ }
+
+}