diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000000..df7825df61 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/anonymousclass/EmailSenderService.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/anonymousclass/EmailSenderService.java new file mode 100644 index 0000000000..a7f9d95045 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/anonymousclass/EmailSenderService.java @@ -0,0 +1,10 @@ +package com.ossez.anonymousclass; + +public class EmailSenderService implements SenderService { + + @Override + public String callSender(Sender sender) { + return sender.send("Email Notification"); + } + +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/anonymousclass/Sender.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/anonymousclass/Sender.java new file mode 100644 index 0000000000..9b280e0f15 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/anonymousclass/Sender.java @@ -0,0 +1,7 @@ +package com.ossez.anonymousclass; + +public interface Sender { + + String send(final String message); + +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/anonymousclass/SenderService.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/anonymousclass/SenderService.java new file mode 100644 index 0000000000..da30102bd6 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/anonymousclass/SenderService.java @@ -0,0 +1,7 @@ +package com.ossez.anonymousclass; + +public interface SenderService { + + String callSender(Sender sender); + +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/anonymousclass/SmsSenderService.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/anonymousclass/SmsSenderService.java new file mode 100644 index 0000000000..ab44b28df5 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/anonymousclass/SmsSenderService.java @@ -0,0 +1,10 @@ +package com.ossez.anonymousclass; + +public class SmsSenderService implements SenderService { + + @Override + public String callSender(Sender sender) { + return sender.send("SMS Notification"); + } + +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/serialization/SerializableLambdaExpression.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/serialization/SerializableLambdaExpression.java new file mode 100644 index 0000000000..0122ac40b4 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/serialization/SerializableLambdaExpression.java @@ -0,0 +1,10 @@ +package com.ossez.java8.lambda.serialization; + +import java.io.Serializable; + +public class SerializableLambdaExpression { + public static Object getLambdaExpressionObject() { + Runnable r = (Runnable & Serializable) () -> System.out.println("please serialize this message"); + return r; + } +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/suppliercallable/data/User.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/suppliercallable/data/User.java new file mode 100644 index 0000000000..393fbee6ae --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/suppliercallable/data/User.java @@ -0,0 +1,59 @@ +package com.ossez.suppliercallable.data; + +import java.time.LocalDate; + +public class User { + + private String name; + private String surname; + private LocalDate birthDate; + private Integer age; + private Boolean canDriveACar = false; + + public User(String name, String surname, LocalDate birthDate) { + this.name = name; + this.surname = surname; + this.birthDate = birthDate; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSurname() { + return surname; + } + + public void setSurname(String surname) { + this.surname = surname; + } + + public LocalDate getBirthDate() { + return birthDate; + } + + public void setBirthDate(LocalDate birthDate) { + this.birthDate = birthDate; + } + + public void setAge(Integer age) { + this.age = age; + } + + public Integer getAge() { + return age; + } + + public Boolean getCanDriveACar() { + return canDriveACar; + } + + public void setCanDriveACar(Boolean canDriveACar) { + this.canDriveACar = canDriveACar; + } + +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/suppliercallable/service/Service.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/suppliercallable/service/Service.java new file mode 100644 index 0000000000..0a8353efad --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/suppliercallable/service/Service.java @@ -0,0 +1,8 @@ +package com.ossez.suppliercallable.service; + +import com.ossez.suppliercallable.data.User; + +public interface Service { + + User execute(User user); +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/suppliercallable/service/callable/AgeCalculatorCallable.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/suppliercallable/service/callable/AgeCalculatorCallable.java new file mode 100644 index 0000000000..0fc3e4b35c --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/suppliercallable/service/callable/AgeCalculatorCallable.java @@ -0,0 +1,20 @@ +package com.ossez.suppliercallable.service.callable; + +import java.time.LocalDate; +import java.time.Period; +import java.util.concurrent.Callable; + +public class AgeCalculatorCallable implements Callable { + + private final LocalDate birthDate; + + @Override + public Integer call() throws Exception { + return Period.between(birthDate, LocalDate.now()) + .getYears(); + } + + public AgeCalculatorCallable(LocalDate birthDate) { + this.birthDate = birthDate; + } +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/suppliercallable/service/callable/CallableServiceImpl.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/suppliercallable/service/callable/CallableServiceImpl.java new file mode 100644 index 0000000000..36633c893d --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/suppliercallable/service/callable/CallableServiceImpl.java @@ -0,0 +1,31 @@ +package com.ossez.suppliercallable.service.callable; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import com.ossez.suppliercallable.data.User; +import com.ossez.suppliercallable.service.Service; + +public class CallableServiceImpl implements Service { + + @Override + public User execute(User user) { + ExecutorService executorService = Executors.newCachedThreadPool(); + + try { + Future ageFuture = executorService.submit(new AgeCalculatorCallable(user.getBirthDate())); + Integer age = ageFuture.get(); + Future canDriveACarFuture = executorService.submit(new CarDriverValidatorCallable(age)); + Boolean canDriveACar = canDriveACarFuture.get(); + user.setAge(age); + user.setCanDriveACar(canDriveACar); + } catch (ExecutionException | InterruptedException e) { + throw new RuntimeException(e.getCause()); + } + + return user; + } + +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/suppliercallable/service/callable/CarDriverValidatorCallable.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/suppliercallable/service/callable/CarDriverValidatorCallable.java new file mode 100644 index 0000000000..813ac9c86a --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/suppliercallable/service/callable/CarDriverValidatorCallable.java @@ -0,0 +1,17 @@ +package com.ossez.suppliercallable.service.callable; + +import java.util.concurrent.Callable; + +public class CarDriverValidatorCallable implements Callable { + + private final Integer age; + + @Override + public Boolean call() throws Exception { + return age > 18; + } + + public CarDriverValidatorCallable(Integer age) { + this.age = age; + } +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/suppliercallable/service/supplier/SupplierServiceImpl.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/suppliercallable/service/supplier/SupplierServiceImpl.java new file mode 100644 index 0000000000..5e5ea3a82d --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/suppliercallable/service/supplier/SupplierServiceImpl.java @@ -0,0 +1,26 @@ +package com.ossez.suppliercallable.service.supplier; + +import java.time.LocalDate; +import java.time.Period; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import com.ossez.suppliercallable.data.User; +import com.ossez.suppliercallable.service.Service; + +public class SupplierServiceImpl implements Service { + @Override + public User execute(User user) { + ExecutorService executorService = Executors.newCachedThreadPool(); + CompletableFuture ageFut = CompletableFuture.supplyAsync(() -> Period.between(user.getBirthDate(), LocalDate.now()) + .getYears(), executorService) + .exceptionally((throwable -> null)); + CompletableFuture canDriveACarFut = ageFut.thenComposeAsync(age -> CompletableFuture.supplyAsync(() -> age > 18, executorService)) + .exceptionally((ex) -> false); + user.setAge(ageFut.join()); + user.setCanDriveACar(canDriveACarFut.join()); + return user; + } + +} diff --git a/core-java-modules/core-java-lambdas/src/test/java/com/ossez/anonymousclass/AnonymousClassToLambdaIntegrationTest.java b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/anonymousclass/AnonymousClassToLambdaIntegrationTest.java new file mode 100644 index 0000000000..2579b4ba86 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/anonymousclass/AnonymousClassToLambdaIntegrationTest.java @@ -0,0 +1,38 @@ +package com.ossez.anonymousclass; + +import static org.junit.Assert.assertEquals; + +import com.ossez.anonymousclass.EmailSenderService; +import com.ossez.anonymousclass.Sender; +import com.ossez.anonymousclass.SenderService; +import com.ossez.anonymousclass.SmsSenderService; +import org.junit.Test; + +public class AnonymousClassToLambdaIntegrationTest { + + @Test + public void whenPassingAnonymousClass_thenSuccess() { + final SenderService emailSenderService = new EmailSenderService(); + + final String emailNotif = emailSenderService.callSender(new Sender() { + @Override + public String send(String message) { + return message; + } + }); + + assertEquals(emailNotif, "Email Notification"); + } + + @Test + public void whenPassingLambdaExpression_thenSuccess() { + final SenderService smsSenderService = new SmsSenderService(); + + final String smsNotif = smsSenderService.callSender((String message) -> { + return message; + }); + + assertEquals(smsNotif, "SMS Notification"); + } + +} diff --git a/core-java-modules/core-java-lambdas/src/test/java/com/ossez/java8/lambda/serialization/LambdaSerializationUnitTest.java b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/java8/lambda/serialization/LambdaSerializationUnitTest.java new file mode 100644 index 0000000000..faf7cf3bf3 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/java8/lambda/serialization/LambdaSerializationUnitTest.java @@ -0,0 +1,79 @@ +package com.ossez.java8.lambda.serialization; + +import com.ossez.java8.lambda.serialization.NotSerializableLambdaExpression; +import com.ossez.java8.lambda.serialization.SerializableLambdaExpression; +import org.junit.Test; + +import java.io.*; +import java.nio.file.Files; +import java.util.function.Consumer; +import java.util.function.Function; + +import static org.junit.Assert.assertTrue; + +public class LambdaSerializationUnitTest { + @Test(expected = NotSerializableException.class) + public void givenRunnable_whenNoCapturing_thenSerializationFailed() throws IOException, ClassNotFoundException { + Object obj = NotSerializableLambdaExpression.getLambdaExpressionObject(); + writeAndReadObject(obj, Runnable.class); + } + + @Test + public void givenIntersectionType_whenNoCapturing_thenSerializationSuccess() throws IOException, ClassNotFoundException { + Object obj = SerializableLambdaExpression.getLambdaExpressionObject(); + writeAndReadObject(obj, Runnable.class); + } + + @Test + public void givenSerializableRunnable_whenNoCapturing_thenSerializationSuccess() throws IOException, ClassNotFoundException { + SerializableRunnable obj = () -> System.out.println("please serialize this message"); + writeAndReadObject(obj, SerializableRunnable.class); + } + + @Test + public void givenSerializableFunction_whenNoCapturing_thenSerializationSuccess() throws IOException, ClassNotFoundException { + SerializableFunction obj = message -> String.format("Hello %s", message); + writeAndReadObject(obj, SerializableFunction.class); + } + + @Test + public void givenSerializableConsumer_whenNoCapturing_thenSerializationSuccess() throws IOException, ClassNotFoundException { + SerializableConsumer obj = message -> System.out.println(message); + writeAndReadObject(obj, SerializableConsumer.class); + } + + @Test(expected = NotSerializableException.class) + public void givenSerializableConsumer_whenCapturingNotSerializable_thenSerializationFailed() throws IOException, ClassNotFoundException { + SerializableConsumer obj = System.out::println; + writeAndReadObject(obj, SerializableConsumer.class); + } + + private void writeAndReadObject(Object obj, Class clazz) throws IOException, ClassNotFoundException { + File file = Files.createTempFile("lambda", "ser").toFile(); + try ( + FileOutputStream fos = new FileOutputStream(file); + ObjectOutputStream oos = new ObjectOutputStream(fos) + ) { + oos.writeObject(obj); + } + + try ( + FileInputStream fis = new FileInputStream(file); + ObjectInputStream ois = new ObjectInputStream(fis) + ) { + Object newObj = ois.readObject(); + boolean isInstance = clazz.isInstance(newObj); + + assertTrue(isInstance); + } + } + + interface SerializableRunnable extends Runnable, Serializable { + } + + interface SerializableFunction extends Function, Serializable { + } + + interface SerializableConsumer extends Consumer, Serializable { + } +} diff --git a/core-java-modules/core-java-lambdas/src/test/java/com/ossez/suppliercallable/CallableSupplierUnitTest.java b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/suppliercallable/CallableSupplierUnitTest.java new file mode 100644 index 0000000000..08134b5781 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/suppliercallable/CallableSupplierUnitTest.java @@ -0,0 +1,64 @@ +package com.ossez.suppliercallable; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import java.time.LocalDate; +import java.time.Month; +import org.junit.jupiter.api.Test; +import com.ossez.suppliercallable.data.User; +import com.ossez.suppliercallable.service.Service; +import com.ossez.suppliercallable.service.callable.CallableServiceImpl; +import com.ossez.suppliercallable.service.supplier.SupplierServiceImpl; + +public class CallableSupplierUnitTest { + + @Test + void givenCallableService_whenUserIsAnAdult_thenCanDriveACar() { + User user = new User("Test", "Test", LocalDate.of(2000, Month.JANUARY, 19)); + Service service = new CallableServiceImpl(); + service.execute(user); + assertEquals(true, user.getCanDriveACar()); + } + + @Test + void givenCallableService_whenUserIsNotAnAdult_thenCannotDriveACar() { + User user = new User("Test", "Test", LocalDate.of(2010, Month.JANUARY, 19)); + Service service = new CallableServiceImpl(); + service.execute(user); + assertEquals(false, user.getCanDriveACar()); + } + + @Test + void givenCallableService_whenBirthDateIsNull_thenShouldThrowAnException() { + User user = new User("Test", "Test", null); + Service service = new CallableServiceImpl(); + assertThrows(RuntimeException.class, () -> service.execute(user)); + } + + @Test + void givenSupplierService_whenUserIsAnAdult_thenCanDriveACar() { + User user = new User("Test", "Test", LocalDate.of(2000, Month.JANUARY, 19)); + Service service = new SupplierServiceImpl(); + service.execute(user); + assertEquals(true, user.getCanDriveACar()); + } + + @Test + void givenSupplierService_whenUserIsNotAnAdult_thenCannotDriveACar() { + User user = new User("Test", "Test", LocalDate.of(2010, Month.JANUARY, 19)); + Service service = new SupplierServiceImpl(); + service.execute(user); + assertEquals(false, user.getCanDriveACar()); + } + + @Test + void givenSupplierService_whenBirthDateIsNull_thenCannotDriveACarAndAgeIsNull() { + User user = new User("Test", "Test", null); + Service service = new SupplierServiceImpl(); + service.execute(user); + assertEquals(false, user.getCanDriveACar()); + assertNull(user.getBirthDate()); + } + +}