, Annotation>) annotations.get(targetClass);
+ System.out.println(map);
+ map.put(targetAnnotation, targetValue);
+ System.out.println(map);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/reflection/Greetings.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/reflection/Greetings.java
new file mode 100644
index 0000000000..fc6dfe949b
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/reflection/Greetings.java
@@ -0,0 +1,6 @@
+package com.baeldung.reflection;
+
+@Greeter(greet="Good morning")
+public class Greetings {
+
+}
diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/reflection/Locomotion.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/reflection/Locomotion.java
new file mode 100644
index 0000000000..230fd9a466
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/reflection/Locomotion.java
@@ -0,0 +1,5 @@
+package com.baeldung.reflection;
+
+public interface Locomotion {
+ String getLocomotion();
+}
diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/reflection/Operations.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/reflection/Operations.java
new file mode 100644
index 0000000000..5264378524
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/reflection/Operations.java
@@ -0,0 +1,21 @@
+package com.baeldung.reflection;
+
+public class Operations {
+
+ public double publicSum(int a, double b) {
+ return a + b;
+ }
+
+ public static double publicStaticMultiply(float a, long b) {
+ return a * b;
+ }
+
+ private boolean privateAnd(boolean a, boolean b) {
+ return a && b;
+ }
+
+ protected int protectedMax(int a, int b) {
+ return a > b ? a : b;
+ }
+
+}
diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/reflection/Person.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/reflection/Person.java
new file mode 100644
index 0000000000..1a1fafef93
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/reflection/Person.java
@@ -0,0 +1,6 @@
+package com.baeldung.reflection;
+
+public class Person {
+ private String name;
+ private int age;
+}
diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/Country.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/Country.java
new file mode 100644
index 0000000000..d39f333b41
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/Country.java
@@ -0,0 +1,135 @@
+
+package com.baeldung.soap.ws.client.generated;
+
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
+import jakarta.xml.bind.annotation.XmlSchemaType;
+import jakarta.xml.bind.annotation.XmlType;
+
+
+/**
+ * Java class for country complex type.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <complexType name="country">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <element name="capital" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ * <element name="currency" type="{http://server.ws.soap.baeldung.com/}currency" minOccurs="0"/>
+ * <element name="name" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ * <element name="population" type="{http://www.w3.org/2001/XMLSchema}int"/>
+ * </sequence>
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ *
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "country", propOrder = {
+ "capital",
+ "currency",
+ "name",
+ "population"
+})
+public class Country {
+
+ protected String capital;
+ @XmlSchemaType(name = "string")
+ protected Currency currency;
+ protected String name;
+ protected int population;
+
+ /**
+ * Gets the value of the capital property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getCapital() {
+ return capital;
+ }
+
+ /**
+ * Sets the value of the capital property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setCapital(String value) {
+ this.capital = value;
+ }
+
+ /**
+ * Gets the value of the currency property.
+ *
+ * @return
+ * possible object is
+ * {@link Currency }
+ *
+ */
+ public Currency getCurrency() {
+ return currency;
+ }
+
+ /**
+ * Sets the value of the currency property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Currency }
+ *
+ */
+ public void setCurrency(Currency value) {
+ this.currency = value;
+ }
+
+ /**
+ * Gets the value of the name property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the value of the name property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setName(String value) {
+ this.name = value;
+ }
+
+ /**
+ * Gets the value of the population property.
+ *
+ */
+ public int getPopulation() {
+ return population;
+ }
+
+ /**
+ * Sets the value of the population property.
+ *
+ */
+ public void setPopulation(int value) {
+ this.population = value;
+ }
+
+}
diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/CountryService.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/CountryService.java
new file mode 100644
index 0000000000..f10dcade1b
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/CountryService.java
@@ -0,0 +1,40 @@
+
+package com.baeldung.soap.ws.client.generated;
+
+import jakarta.jws.WebMethod;
+import jakarta.jws.WebParam;
+import jakarta.jws.WebResult;
+import jakarta.jws.WebService;
+import jakarta.jws.soap.SOAPBinding;
+import jakarta.xml.bind.annotation.XmlSeeAlso;
+import jakarta.xml.ws.Action;
+
+
+/**
+ * This class was generated by the JAX-WS RI.
+ * JAX-WS RI 3.0.2
+ * Generated source version: 3.0
+ *
+ */
+@WebService(name = "CountryService", targetNamespace = "http://server.ws.soap.baeldung.com/")
+@SOAPBinding(style = SOAPBinding.Style.RPC)
+@XmlSeeAlso({
+ ObjectFactory.class
+})
+public interface CountryService {
+
+
+ /**
+ *
+ * @param arg0
+ * @return
+ * returns com.baeldung.soap.ws.client.generated.Country
+ */
+ @WebMethod
+ @WebResult(partName = "return")
+ @Action(input = "http://server.ws.soap.baeldung.com/CountryService/findByNameRequest", output = "http://server.ws.soap.baeldung.com/CountryService/findByNameResponse")
+ public Country findByName(
+ @WebParam(name = "arg0", partName = "arg0")
+ String arg0);
+
+}
diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/CountryServiceImplService.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/CountryServiceImplService.java
new file mode 100644
index 0000000000..ae7ff38f7d
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/CountryServiceImplService.java
@@ -0,0 +1,94 @@
+
+package com.baeldung.soap.ws.client.generated;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import javax.xml.namespace.QName;
+import jakarta.xml.ws.Service;
+import jakarta.xml.ws.WebEndpoint;
+import jakarta.xml.ws.WebServiceClient;
+import jakarta.xml.ws.WebServiceException;
+import jakarta.xml.ws.WebServiceFeature;
+
+
+/**
+ * This class was generated by the JAX-WS RI.
+ * JAX-WS RI 3.0.2
+ * Generated source version: 3.0
+ *
+ */
+@WebServiceClient(name = "CountryServiceImplService", targetNamespace = "http://server.ws.soap.baeldung.com/", wsdlLocation = "http://localhost:8888/ws/country?wsdl")
+public class CountryServiceImplService
+ extends Service
+{
+
+ private final static URL COUNTRYSERVICEIMPLSERVICE_WSDL_LOCATION;
+ private final static WebServiceException COUNTRYSERVICEIMPLSERVICE_EXCEPTION;
+ private final static QName COUNTRYSERVICEIMPLSERVICE_QNAME = new QName("http://server.ws.soap.baeldung.com/", "CountryServiceImplService");
+
+ static {
+ URL url = null;
+ WebServiceException e = null;
+ try {
+ url = new URL("http://localhost:8888/ws/country?wsdl");
+ } catch (MalformedURLException ex) {
+ e = new WebServiceException(ex);
+ }
+ COUNTRYSERVICEIMPLSERVICE_WSDL_LOCATION = url;
+ COUNTRYSERVICEIMPLSERVICE_EXCEPTION = e;
+ }
+
+ public CountryServiceImplService() {
+ super(__getWsdlLocation(), COUNTRYSERVICEIMPLSERVICE_QNAME);
+ }
+
+ public CountryServiceImplService(WebServiceFeature... features) {
+ super(__getWsdlLocation(), COUNTRYSERVICEIMPLSERVICE_QNAME, features);
+ }
+
+ public CountryServiceImplService(URL wsdlLocation) {
+ super(wsdlLocation, COUNTRYSERVICEIMPLSERVICE_QNAME);
+ }
+
+ public CountryServiceImplService(URL wsdlLocation, WebServiceFeature... features) {
+ super(wsdlLocation, COUNTRYSERVICEIMPLSERVICE_QNAME, features);
+ }
+
+ public CountryServiceImplService(URL wsdlLocation, QName serviceName) {
+ super(wsdlLocation, serviceName);
+ }
+
+ public CountryServiceImplService(URL wsdlLocation, QName serviceName, WebServiceFeature... features) {
+ super(wsdlLocation, serviceName, features);
+ }
+
+ /**
+ *
+ * @return
+ * returns CountryService
+ */
+ @WebEndpoint(name = "CountryServiceImplPort")
+ public CountryService getCountryServiceImplPort() {
+ return super.getPort(new QName("http://server.ws.soap.baeldung.com/", "CountryServiceImplPort"), CountryService.class);
+ }
+
+ /**
+ *
+ * @param features
+ * A list of {@link jakarta.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the features
parameter will have their default values.
+ * @return
+ * returns CountryService
+ */
+ @WebEndpoint(name = "CountryServiceImplPort")
+ public CountryService getCountryServiceImplPort(WebServiceFeature... features) {
+ return super.getPort(new QName("http://server.ws.soap.baeldung.com/", "CountryServiceImplPort"), CountryService.class, features);
+ }
+
+ private static URL __getWsdlLocation() {
+ if (COUNTRYSERVICEIMPLSERVICE_EXCEPTION!= null) {
+ throw COUNTRYSERVICEIMPLSERVICE_EXCEPTION;
+ }
+ return COUNTRYSERVICEIMPLSERVICE_WSDL_LOCATION;
+ }
+
+}
diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/Currency.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/Currency.java
new file mode 100644
index 0000000000..ad42c65461
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/Currency.java
@@ -0,0 +1,39 @@
+
+package com.baeldung.soap.ws.client.generated;
+
+import jakarta.xml.bind.annotation.XmlEnum;
+import jakarta.xml.bind.annotation.XmlType;
+
+
+/**
+ * Java class for currency.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ * <simpleType name="currency">
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}string">
+ * <enumeration value="EUR"/>
+ * <enumeration value="INR"/>
+ * <enumeration value="USD"/>
+ * </restriction>
+ * </simpleType>
+ *
+ *
+ */
+@XmlType(name = "currency")
+@XmlEnum
+public enum Currency {
+
+ EUR,
+ INR,
+ USD;
+
+ public String value() {
+ return name();
+ }
+
+ public static Currency fromValue(String v) {
+ return valueOf(v);
+ }
+
+}
diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/ObjectFactory.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/ObjectFactory.java
new file mode 100644
index 0000000000..0489e49c2b
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/ObjectFactory.java
@@ -0,0 +1,40 @@
+
+package com.baeldung.soap.ws.client.generated;
+
+import jakarta.xml.bind.annotation.XmlRegistry;
+
+
+/**
+ * This object contains factory methods for each
+ * Java content interface and Java element interface
+ * generated in the com.baeldung.soap.ws.client.generated package.
+ * An ObjectFactory allows you to programatically
+ * construct new instances of the Java representation
+ * for XML content. The Java representation of XML
+ * content can consist of schema derived interfaces
+ * and classes representing the binding of schema
+ * type definitions, element declarations and model
+ * groups. Factory methods for each of these are
+ * provided in this class.
+ *
+ */
+@XmlRegistry
+public class ObjectFactory {
+
+
+ /**
+ * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.baeldung.soap.ws.client.generated
+ *
+ */
+ public ObjectFactory() {
+ }
+
+ /**
+ * Create an instance of {@link Country }
+ *
+ */
+ public Country createCountry() {
+ return new Country();
+ }
+
+}
diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/package-info.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/package-info.java
new file mode 100644
index 0000000000..6dcc08c268
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/package-info.java
@@ -0,0 +1,2 @@
+@jakarta.xml.bind.annotation.XmlSchema(namespace = "http://server.ws.soap.baeldung.com/")
+package com.baeldung.soap.ws.client.generated;
diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/server/Country.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/server/Country.java
new file mode 100644
index 0000000000..62ea4a22ed
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/server/Country.java
@@ -0,0 +1,41 @@
+package com.baeldung.soap.ws.server;
+
+public class Country {
+ protected String name;
+ protected int population;
+ protected String capital;
+ protected Currency currency;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getPopulation() {
+ return population;
+ }
+
+ public void setPopulation(int population) {
+ this.population = population;
+ }
+
+ public String getCapital() {
+ return capital;
+ }
+
+ public void setCapital(String capital) {
+ this.capital = capital;
+ }
+
+ public Currency getCurrency() {
+ return currency;
+ }
+
+ public void setCurrency(Currency currency) {
+ this.currency = currency;
+ }
+
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/server/CountryRepository.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/server/CountryRepository.java
new file mode 100644
index 0000000000..558f7c1293
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/server/CountryRepository.java
@@ -0,0 +1,43 @@
+package com.baeldung.soap.ws.server;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class CountryRepository {
+
+ private static final Map countries = new HashMap<>();
+
+ {
+ initData();
+ }
+
+ private final static void initData() {
+ Country usa = new Country();
+ usa.setName("USA");
+ usa.setCapital("Washington D.C.");
+ usa.setCurrency(Currency.USD);
+ usa.setPopulation(323947000);
+
+ countries.put(usa.getName(), usa);
+
+ Country india = new Country();
+ india.setName("India");
+ india.setCapital("New Delhi");
+ india.setCurrency(Currency.INR);
+ india.setPopulation(1295210000);
+
+ countries.put(india.getName(), india);
+
+ Country france = new Country();
+ france.setName("France");
+ france.setCapital("Paris");
+ france.setCurrency(Currency.EUR);
+ france.setPopulation(66710000);
+
+ countries.put(france.getName(), france);
+ }
+
+ public Country findCountry(String name) {
+ return countries.get(name);
+ }
+}
diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/server/CountryService.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/server/CountryService.java
new file mode 100644
index 0000000000..b11765b326
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/server/CountryService.java
@@ -0,0 +1,15 @@
+package com.baeldung.soap.ws.server;
+
+import jakarta.jws.WebMethod;
+import jakarta.jws.WebService;
+import jakarta.jws.soap.SOAPBinding;
+import jakarta.jws.soap.SOAPBinding.Style;
+
+@WebService
+@SOAPBinding(style=Style.RPC)
+public interface CountryService {
+
+ @WebMethod
+ Country findByName(String name);
+
+}
diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/server/CountryServiceImpl.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/server/CountryServiceImpl.java
new file mode 100644
index 0000000000..da159a1475
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/server/CountryServiceImpl.java
@@ -0,0 +1,15 @@
+package com.baeldung.soap.ws.server;
+
+import jakarta.jws.WebService;
+
+@WebService(endpointInterface = "com.baeldung.soap.ws.server.CountryService")
+public class CountryServiceImpl implements CountryService {
+
+ private CountryRepository countryRepository = new CountryRepository();
+
+ @Override
+ public Country findByName(String name) {
+ return countryRepository.findCountry(name);
+ }
+
+}
diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/server/CountryServicePublisher.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/server/CountryServicePublisher.java
new file mode 100644
index 0000000000..314a91dc48
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/server/CountryServicePublisher.java
@@ -0,0 +1,19 @@
+package com.baeldung.soap.ws.server;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import jakarta.xml.ws.Endpoint;
+
+
+public class CountryServicePublisher {
+
+ private static final Logger logger = LoggerFactory.getLogger(CountryServicePublisher.class);
+
+ public static void main(String[] args) {
+ Endpoint endpoint = Endpoint.create(new CountryServiceImpl());
+ endpoint.publish("http://localhost:8888/ws/country");
+
+ logger.info("Country web service ready to consume requests!");
+ }
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/server/Currency.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/server/Currency.java
new file mode 100644
index 0000000000..d1b25a26c6
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/server/Currency.java
@@ -0,0 +1,15 @@
+package com.baeldung.soap.ws.server;
+
+public enum Currency {
+
+ EUR, INR, USD;
+
+ public String value() {
+ return name();
+ }
+
+ public static Currency fromValue(String v) {
+ return valueOf(v);
+ }
+
+}
diff --git a/core-java-modules/core-java-11-2/src/test/java/com/baeldung/collectors/Java8CollectorsUnitTest.java b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/collectors/Java8CollectorsUnitTest.java
new file mode 100644
index 0000000000..7990b1fdb7
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/collectors/Java8CollectorsUnitTest.java
@@ -0,0 +1,237 @@
+package com.baeldung.collectors;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import org.junit.Test;
+
+import java.util.*;
+import java.util.function.BiConsumer;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.stream.Collector;
+
+import static com.google.common.collect.Sets.newHashSet;
+import static java.util.stream.Collectors.*;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+public class Java8CollectorsUnitTest {
+
+ private final List givenList = Arrays.asList("a", "bb", "ccc", "dd");
+ private final List listWithDuplicates = Arrays.asList("a", "bb", "c", "d", "bb");
+
+ @Test
+ public void whenCollectingToList_shouldCollectToList() throws Exception {
+ final List result = givenList.stream().collect(toList());
+
+ assertThat(result).containsAll(givenList);
+ }
+
+ @Test
+ public void whenCollectingToUnmodifiableList_shouldCollectToUnmodifiableList() {
+ final List result = givenList.stream().collect(toUnmodifiableList());
+
+ assertThatThrownBy(() -> result.add("foo"))
+ .isInstanceOf(UnsupportedOperationException.class);
+ }
+
+ @Test
+ public void whenCollectingToSet_shouldCollectToSet() throws Exception {
+ final Set result = givenList.stream().collect(toSet());
+
+ assertThat(result).containsAll(givenList);
+ }
+
+ @Test
+ public void whenCollectingToUnmodifiableSet_shouldCollectToUnmodifiableSet() {
+ final Set result = givenList.stream().collect(toUnmodifiableSet());
+
+ assertThatThrownBy(() -> result.add("foo"))
+ .isInstanceOf(UnsupportedOperationException.class);
+ }
+
+ @Test
+ public void givenContainsDuplicateElements_whenCollectingToSet_shouldAddDuplicateElementsOnlyOnce() throws Exception {
+ final Set result = listWithDuplicates.stream().collect(toSet());
+
+ assertThat(result).hasSize(4);
+ }
+
+ @Test
+ public void whenCollectingToCollection_shouldCollectToCollection() throws Exception {
+ final List result = givenList.stream().collect(toCollection(LinkedList::new));
+
+ assertThat(result).containsAll(givenList).isInstanceOf(LinkedList.class);
+ }
+
+ @Test
+ public void whenCollectingToImmutableCollection_shouldThrowException() throws Exception {
+ assertThatThrownBy(() -> {
+ givenList.stream().collect(toCollection(ImmutableList::of));
+ }).isInstanceOf(UnsupportedOperationException.class);
+
+ }
+
+ @Test
+ public void whenCollectingToMap_shouldCollectToMap() throws Exception {
+ final Map result = givenList.stream().collect(toMap(Function.identity(), String::length));
+
+ assertThat(result).containsEntry("a", 1).containsEntry("bb", 2).containsEntry("ccc", 3).containsEntry("dd", 2);
+ }
+
+ @Test
+ public void whenCollectingToUnmodifiableMap_shouldCollectToUnmodifiableMap() {
+ final Map result = givenList.stream()
+ .collect(toUnmodifiableMap(Function.identity(), String::length));
+
+ assertThatThrownBy(() -> result.put("foo", 3))
+ .isInstanceOf(UnsupportedOperationException.class);
+ }
+
+ @Test
+ public void whenCollectingToMapwWithDuplicates_shouldCollectToMapMergingTheIdenticalItems() throws Exception {
+ final Map result = listWithDuplicates.stream().collect(
+ toMap(
+ Function.identity(),
+ String::length,
+ (item, identicalItem) -> item
+ )
+ );
+
+ assertThat(result).containsEntry("a", 1).containsEntry("bb", 2).containsEntry("c", 1).containsEntry("d", 1);
+ }
+
+ @Test
+ public void givenContainsDuplicateElements_whenCollectingToMap_shouldThrowException() throws Exception {
+ assertThatThrownBy(() -> {
+ listWithDuplicates.stream().collect(toMap(Function.identity(), String::length));
+ }).isInstanceOf(IllegalStateException.class);
+ }
+
+ @Test
+ public void whenCollectingAndThen_shouldCollect() throws Exception {
+ final List result = givenList.stream().collect(collectingAndThen(toList(), ImmutableList::copyOf));
+
+ assertThat(result).containsAll(givenList).isInstanceOf(ImmutableList.class);
+ }
+
+ @Test
+ public void whenJoining_shouldJoin() throws Exception {
+ final String result = givenList.stream().collect(joining());
+
+ assertThat(result).isEqualTo("abbcccdd");
+ }
+
+ @Test
+ public void whenJoiningWithSeparator_shouldJoinWithSeparator() throws Exception {
+ final String result = givenList.stream().collect(joining(" "));
+
+ assertThat(result).isEqualTo("a bb ccc dd");
+ }
+
+ @Test
+ public void whenJoiningWithSeparatorAndPrefixAndPostfix_shouldJoinWithSeparatorPrePost() throws Exception {
+ final String result = givenList.stream().collect(joining(" ", "PRE-", "-POST"));
+
+ assertThat(result).isEqualTo("PRE-a bb ccc dd-POST");
+ }
+
+ @Test
+ public void whenPartitioningBy_shouldPartition() throws Exception {
+ final Map> result = givenList.stream().collect(partitioningBy(s -> s.length() > 2));
+
+ assertThat(result).containsKeys(true, false).satisfies(booleanListMap -> {
+ assertThat(booleanListMap.get(true)).contains("ccc");
+
+ assertThat(booleanListMap.get(false)).contains("a", "bb", "dd");
+ });
+ }
+
+ @Test
+ public void whenCounting_shouldCount() throws Exception {
+ final Long result = givenList.stream().collect(counting());
+
+ assertThat(result).isEqualTo(4);
+ }
+
+ @Test
+ public void whenSummarizing_shouldSummarize() throws Exception {
+ final DoubleSummaryStatistics result = givenList.stream().collect(summarizingDouble(String::length));
+
+ assertThat(result.getAverage()).isEqualTo(2);
+ assertThat(result.getCount()).isEqualTo(4);
+ assertThat(result.getMax()).isEqualTo(3);
+ assertThat(result.getMin()).isEqualTo(1);
+ assertThat(result.getSum()).isEqualTo(8);
+ }
+
+ @Test
+ public void whenAveraging_shouldAverage() throws Exception {
+ final Double result = givenList.stream().collect(averagingDouble(String::length));
+
+ assertThat(result).isEqualTo(2);
+ }
+
+ @Test
+ public void whenSumming_shouldSum() throws Exception {
+ final Double result = givenList.stream().filter(i -> true).collect(summingDouble(String::length));
+
+ assertThat(result).isEqualTo(8);
+ }
+
+ @Test
+ public void whenMaxingBy_shouldMaxBy() throws Exception {
+ final Optional result = givenList.stream().collect(maxBy(Comparator.naturalOrder()));
+
+ assertThat(result).isPresent().hasValue("dd");
+ }
+
+ @Test
+ public void whenGroupingBy_shouldGroupBy() throws Exception {
+ final Map> result = givenList.stream().collect(groupingBy(String::length, toSet()));
+
+ assertThat(result).containsEntry(1, newHashSet("a")).containsEntry(2, newHashSet("bb", "dd")).containsEntry(3, newHashSet("ccc"));
+ }
+
+ @Test
+ public void whenCreatingCustomCollector_shouldCollect() throws Exception {
+ final ImmutableSet result = givenList.stream().collect(toImmutableSet());
+
+ assertThat(result).isInstanceOf(ImmutableSet.class).contains("a", "bb", "ccc", "dd");
+
+ }
+
+ private static ImmutableSetCollector toImmutableSet() {
+ return new ImmutableSetCollector<>();
+ }
+
+ private static class ImmutableSetCollector implements Collector, ImmutableSet> {
+
+ @Override
+ public Supplier> supplier() {
+ return ImmutableSet::builder;
+ }
+
+ @Override
+ public BiConsumer, T> accumulator() {
+ return ImmutableSet.Builder::add;
+ }
+
+ @Override
+ public BinaryOperator> combiner() {
+ return (left, right) -> left.addAll(right.build());
+ }
+
+ @Override
+ public Function, ImmutableSet> finisher() {
+ return ImmutableSet.Builder::build;
+ }
+
+ @Override
+ public Set characteristics() {
+ return Sets.immutableEnumSet(Characteristics.UNORDERED);
+ }
+ }
+}
diff --git a/core-java-modules/core-java-11-2/src/test/java/com/baeldung/features/HttpClientIntegrationTest.java b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/features/HttpClientIntegrationTest.java
new file mode 100644
index 0000000000..1d49f5dbd1
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/features/HttpClientIntegrationTest.java
@@ -0,0 +1,54 @@
+package com.baeldung.features;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mockserver.integration.ClientAndServer;
+import org.mockserver.model.HttpStatusCode;
+import org.mockserver.socket.PortFactory;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.time.Duration;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockserver.integration.ClientAndServer.startClientAndServer;
+
+class HttpClientIntegrationTest {
+
+ private static ClientAndServer mockServer;
+ private static int port;
+
+ @BeforeAll
+ static void startServer() {
+ port = PortFactory.findFreePort();
+ mockServer = startClientAndServer(port);
+ mockServer.when(new org.mockserver.model.HttpRequest().withMethod("GET"))
+ .respond(new org.mockserver.model.HttpResponse()
+ .withStatusCode(HttpStatusCode.OK_200.code())
+ .withBody("Hello from the server!"));
+ }
+
+ @AfterAll
+ static void stopServer() {
+ mockServer.stop();
+ }
+
+ @Test
+ void givenSampleHttpRequest_whenRequestIsSent_thenServerResponseIsReceived() throws IOException, InterruptedException {
+ HttpClient httpClient = HttpClient.newBuilder()
+ .version(HttpClient.Version.HTTP_2)
+ .connectTimeout(Duration.ofSeconds(20))
+ .build();
+ HttpRequest httpRequest = HttpRequest.newBuilder()
+ .GET()
+ .uri(URI.create("http://localhost:" + port))
+ .build();
+ HttpResponse httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
+ assertThat(httpResponse.body()).isEqualTo("Hello from the server!");
+ }
+
+}
diff --git a/core-java-modules/core-java-11-2/src/test/java/com/baeldung/features/JavaElevenFeaturesUnitTest.java b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/features/JavaElevenFeaturesUnitTest.java
new file mode 100644
index 0000000000..61ce9c7c13
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/features/JavaElevenFeaturesUnitTest.java
@@ -0,0 +1,61 @@
+package com.baeldung.features;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import javax.annotation.Nonnull;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class JavaElevenFeaturesUnitTest {
+
+ @Test
+ void givenMultilineString_whenExtractingNonBlankStrippedLines_thenLinesAreReturned() {
+ String multilineString = "Baeldung helps \n \n developers \n explore Java.";
+ List lines = multilineString.lines()
+ .filter(line -> !line.isBlank())
+ .map(String::strip)
+ .collect(Collectors.toList());
+ assertThat(lines).containsExactly("Baeldung helps", "developers", "explore Java.");
+ }
+
+ @Test
+ void givenTemporaryFile_whenReadingStringContent_thenContentIsReturned(@TempDir Path tempDir) throws IOException {
+ Path filePath = Files.writeString(Files.createTempFile(tempDir, "demo", ".txt"), "Sample text");
+ String fileContent = Files.readString(filePath);
+ assertThat(fileContent).isEqualTo("Sample text");
+ }
+
+ @Test
+ void givenSampleList_whenConvertingToArray_thenItemsRemainUnchanged() {
+ List sampleList = Arrays.asList("Java", "Kotlin");
+ String[] sampleArray = sampleList.toArray(String[]::new);
+ assertThat(sampleArray).containsExactly("Java", "Kotlin");
+ }
+
+ @Test
+ void givenSampleList_whenConvertingToUppercaseString_thenUppercaseIsReturned() {
+ List sampleList = Arrays.asList("Java", "Kotlin");
+ String resultString = sampleList.stream()
+ .map((@Nonnull var x) -> x.toUpperCase())
+ .collect(Collectors.joining(", "));
+ assertThat(resultString).isEqualTo("JAVA, KOTLIN");
+ }
+
+ @Test
+ void givenSampleList_whenExtractingNonBlankValues_thenOnlyNonBlanksAreReturned() {
+ List sampleList = Arrays.asList("Java", "\n \n", "Kotlin", " ");
+ List withoutBlanks = sampleList.stream()
+ .filter(Predicate.not(String::isBlank))
+ .collect(Collectors.toList());
+ assertThat(withoutBlanks).containsExactly("Java", "Kotlin");
+ }
+
+}
diff --git a/core-java-modules/core-java-11-2/src/test/java/com/baeldung/features/NestedClassesUnitTest.java b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/features/NestedClassesUnitTest.java
new file mode 100644
index 0000000000..902ad9c6f8
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/features/NestedClassesUnitTest.java
@@ -0,0 +1,37 @@
+package com.baeldung.features;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class NestedClassesUnitTest {
+
+ @Test
+ public void giveNestedClass_whenCallingMainClassPrivateMethod_thenNoExceptionIsThrown() {
+ MainClass.NestedClass nestedInstance = new MainClass.NestedClass();
+ assertThat(nestedInstance.nestedPublicMethod()).isTrue();
+ }
+
+ @Test
+ public void giveNestedClass_whenCheckingNestmate_thenNestedClassIsReturned() {
+ assertThat(MainClass.class.isNestmateOf(MainClass.NestedClass.class)).isTrue();
+ }
+
+ @Test
+ public void giveNestedClass_whenCheckingNestHost_thenMainClassIsReturned() {
+ assertThat(MainClass.NestedClass.class.getNestHost()).isEqualTo(MainClass.class);
+ }
+
+ @Test
+ public void giveNestedClass_whenCheckingNestMembers_thenNestMembersAreReturned() {
+ Set nestedMembers = Arrays.stream(MainClass.NestedClass.class.getNestMembers())
+ .map(Class::getName)
+ .collect(Collectors.toSet());
+ assertThat(nestedMembers).contains(MainClass.class.getName(), MainClass.NestedClass.class.getName());
+ }
+
+}
diff --git a/core-java-modules/core-java-11-2/src/test/java/com/baeldung/optional/OptionalChainingUnitTest.java b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/optional/OptionalChainingUnitTest.java
new file mode 100644
index 0000000000..65b9e22f44
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/optional/OptionalChainingUnitTest.java
@@ -0,0 +1,112 @@
+package com.baeldung.optional;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Optional;
+import java.util.function.Supplier;
+import java.util.stream.Stream;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class OptionalChainingUnitTest {
+
+ private boolean getEmptyEvaluated;
+ private boolean getHelloEvaluated;
+ private boolean getByeEvaluated;
+
+ @Before
+ public void setUp() {
+ getEmptyEvaluated = false;
+ getHelloEvaluated = false;
+ getByeEvaluated = false;
+ }
+
+ @Test
+ public void givenThreeOptionals_whenChaining_thenFirstNonEmptyIsReturned() {
+ Optional found = Stream.of(getEmpty(), getHello(), getBye())
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .findFirst();
+
+ assertEquals(getHello(), found);
+ }
+
+ @Test
+ public void givenTwoEmptyOptionals_whenChaining_thenEmptyOptionalIsReturned() {
+ Optional found = Stream.of(getEmpty(), getEmpty())
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .findFirst();
+
+ assertFalse(found.isPresent());
+ }
+
+ @Test
+ public void givenTwoEmptyOptionals_whenChaining_thenDefaultIsReturned() {
+ String found = Stream.>>of(
+ () -> createOptional("empty"),
+ () -> createOptional("empty")
+ )
+ .map(Supplier::get)
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .findFirst()
+ .orElseGet(() -> "default");
+
+ assertEquals("default", found);
+ }
+
+ @Test
+ public void givenThreeOptionals_whenChaining_thenFirstNonEmptyIsReturnedAndRestNotEvaluated() {
+ Optional found = Stream.>>of(this::getEmpty, this::getHello, this::getBye)
+ .map(Supplier::get)
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .findFirst();
+
+ assertTrue(this.getEmptyEvaluated);
+ assertTrue(this.getHelloEvaluated);
+ assertFalse(this.getByeEvaluated);
+ assertEquals(getHello(), found);
+ }
+
+ @Test
+ public void givenTwoOptionalsReturnedByOneArgMethod_whenChaining_thenFirstNonEmptyIsReturned() {
+ Optional found = Stream.>>of(
+ () -> createOptional("empty"),
+ () -> createOptional("hello")
+ )
+ .map(Supplier::get)
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .findFirst();
+
+ assertEquals(createOptional("hello"), found);
+ }
+
+ private Optional getEmpty() {
+ this.getEmptyEvaluated = true;
+ return Optional.empty();
+ }
+
+ private Optional getHello() {
+ this.getHelloEvaluated = true;
+ return Optional.of("hello");
+ }
+
+ private Optional getBye() {
+ this.getByeEvaluated = true;
+ return Optional.of("bye");
+ }
+
+ private Optional createOptional(String input) {
+ if (input == null || "".equals(input) || "empty".equals(input)) {
+ return Optional.empty();
+ }
+
+ return Optional.of(input);
+ }
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-11-2/src/test/java/com/baeldung/optional/OptionalUnitTest.java b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/optional/OptionalUnitTest.java
new file mode 100644
index 0000000000..1b0a2d4445
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/optional/OptionalUnitTest.java
@@ -0,0 +1,288 @@
+package com.baeldung.optional;
+
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Optional;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class OptionalUnitTest {
+
+ private static final Logger LOG = LoggerFactory.getLogger(OptionalUnitTest.class);
+
+ // creating Optional
+ @Test
+ public void whenCreatesEmptyOptional_thenCorrect() {
+ Optional empty = Optional.empty();
+ assertFalse(empty.isPresent());
+ }
+
+ @Test
+ public void givenNonNull_whenCreatesNonNullable_thenCorrect() {
+ String name = "baeldung";
+ Optional opt = Optional.of(name);
+ assertTrue(opt.isPresent());
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void givenNull_whenThrowsErrorOnCreate_thenCorrect() {
+ String name = null;
+ Optional.of(name);
+ }
+
+ @Test
+ public void givenNonNull_whenCreatesOptional_thenCorrect() {
+ String name = "baeldung";
+ Optional opt = Optional.of(name);
+ assertTrue(opt.isPresent());
+ }
+
+ @Test
+ public void givenNonNull_whenCreatesNullable_thenCorrect() {
+ String name = "baeldung";
+ Optional opt = Optional.ofNullable(name);
+ assertTrue(opt.isPresent());
+ }
+
+ @Test
+ public void givenNull_whenCreatesNullable_thenCorrect() {
+ String name = null;
+ Optional opt = Optional.ofNullable(name);
+ assertFalse(opt.isPresent());
+ }
+ // Checking Value With isPresent()
+
+ @Test
+ public void givenOptional_whenIsPresentWorks_thenCorrect() {
+ Optional opt = Optional.of("Baeldung");
+ assertTrue(opt.isPresent());
+
+ opt = Optional.ofNullable(null);
+ assertFalse(opt.isPresent());
+ }
+
+ // Condition Action With ifPresent()
+ @Test
+ public void givenOptional_whenIfPresentWorks_thenCorrect() {
+ Optional opt = Optional.of("baeldung");
+ opt.ifPresent(name -> LOG.debug("{}", name.length()));
+ }
+
+ // returning Value With get()
+ @Test
+ public void givenOptional_whenGetsValue_thenCorrect() {
+ Optional opt = Optional.of("baeldung");
+ String name = opt.get();
+ assertEquals("baeldung", name);
+ }
+
+ @Test(expected = NoSuchElementException.class)
+ public void givenOptionalWithNull_whenGetThrowsException_thenCorrect() {
+ Optional opt = Optional.ofNullable(null);
+ String name = opt.get();
+ }
+
+ @Test
+ public void givenAnEmptyOptional_thenIsEmptyBehavesAsExpected() {
+ Optional opt = Optional.of("Baeldung");
+ assertTrue(opt.isPresent());
+
+ opt = Optional.ofNullable(null);
+ assertFalse(opt.isPresent());
+ }
+
+ // Conditional Return With filter()
+ @Test
+ public void whenOptionalFilterWorks_thenCorrect() {
+ Integer year = 2016;
+ Optional yearOptional = Optional.of(year);
+ boolean is2016 = yearOptional.filter(y -> y == 2016)
+ .isPresent();
+ assertTrue(is2016);
+ boolean is2017 = yearOptional.filter(y -> y == 2017)
+ .isPresent();
+ assertFalse(is2017);
+ }
+
+ @Test
+ public void whenFiltersWithoutOptional_thenCorrect() {
+ assertTrue(priceIsInRange1(new Modem(10.0)));
+ assertFalse(priceIsInRange1(new Modem(9.9)));
+ assertFalse(priceIsInRange1(new Modem(null)));
+ assertFalse(priceIsInRange1(new Modem(15.5)));
+ assertFalse(priceIsInRange1(null));
+
+ }
+
+ @Test
+ public void whenFiltersWithOptional_thenCorrect() {
+ assertTrue(priceIsInRange2(new Modem(10.0)));
+ assertFalse(priceIsInRange2(new Modem(9.9)));
+ assertFalse(priceIsInRange2(new Modem(null)));
+ assertFalse(priceIsInRange2(new Modem(15.5)));
+ assertFalse(priceIsInRange1(null));
+ }
+
+ public boolean priceIsInRange1(Modem modem) {
+ boolean isInRange = false;
+ if (modem != null && modem.getPrice() != null && (modem.getPrice() >= 10 && modem.getPrice() <= 15)) {
+ isInRange = true;
+ }
+ return isInRange;
+ }
+
+ public boolean priceIsInRange2(Modem modem2) {
+ return Optional.ofNullable(modem2)
+ .map(Modem::getPrice)
+ .filter(p -> p >= 10)
+ .filter(p -> p <= 15)
+ .isPresent();
+ }
+
+ // Transforming Value With map()
+ @Test
+ public void givenOptional_whenMapWorks_thenCorrect() {
+ List companyNames = Arrays.asList("paypal", "oracle", "", "microsoft", "", "apple");
+ Optional> listOptional = Optional.of(companyNames);
+
+ int size = listOptional.map(List::size)
+ .orElse(0);
+ assertEquals(6, size);
+ }
+
+ @Test
+ public void givenOptional_whenMapWorks_thenCorrect2() {
+ String name = "baeldung";
+ Optional nameOptional = Optional.of(name);
+
+ int len = nameOptional.map(String::length)
+ .orElse(0);
+ assertEquals(8, len);
+ }
+
+ @Test
+ public void givenOptional_whenMapWorksWithFilter_thenCorrect() {
+ String password = " password ";
+ Optional passOpt = Optional.of(password);
+ boolean correctPassword = passOpt.filter(pass -> pass.equals("password"))
+ .isPresent();
+ assertFalse(correctPassword);
+
+ correctPassword = passOpt.map(String::trim)
+ .filter(pass -> pass.equals("password"))
+ .isPresent();
+ assertTrue(correctPassword);
+ }
+
+ // Transforming Value With flatMap()
+ @Test
+ public void givenOptional_whenFlatMapWorks_thenCorrect2() {
+ Person person = new Person("john", 26);
+ Optional personOptional = Optional.of(person);
+
+ Optional> nameOptionalWrapper = personOptional.map(Person::getName);
+ Optional nameOptional = nameOptionalWrapper.orElseThrow(IllegalArgumentException::new);
+ String name1 = nameOptional.orElseThrow(IllegalArgumentException::new);
+ assertEquals("john", name1);
+
+ String name = personOptional.flatMap(Person::getName)
+ .orElseThrow(IllegalArgumentException::new);
+ assertEquals("john", name);
+ }
+
+ @Test
+ public void givenOptional_whenFlatMapWorksWithFilter_thenCorrect() {
+ Person person = new Person("john", 26);
+ person.setPassword("password");
+ Optional personOptional = Optional.of(person);
+
+ String password = personOptional.flatMap(Person::getPassword)
+ .filter(cleanPass -> cleanPass.equals("password"))
+ .orElseThrow(IllegalArgumentException::new);
+ assertEquals("password", password);
+ }
+
+ // Default Value With orElse
+ @Test
+ public void whenOrElseWorks_thenCorrect() {
+ String nullName = null;
+ String name = Optional.ofNullable(nullName)
+ .orElse("john");
+ assertEquals("john", name);
+ }
+
+ // Default Value With orElseGet
+ @Test
+ public void whenOrElseGetWorks_thenCorrect() {
+ String nullName = null;
+ String name = Optional.ofNullable(nullName)
+ .orElseGet(() -> "john");
+ assertEquals("john", name);
+
+ }
+
+ @Test
+ public void whenOrElseGetAndOrElseOverlap_thenCorrect() {
+ String text = null;
+ LOG.debug("Using orElseGet:");
+ String defaultText = Optional.ofNullable(text)
+ .orElseGet(this::getMyDefault);
+ assertEquals("Default Value", defaultText);
+
+ LOG.debug("Using orElse:");
+ defaultText = Optional.ofNullable(text)
+ .orElse(getMyDefault());
+ assertEquals("Default Value", defaultText);
+ }
+
+ @Test
+ public void whenOrElseGetAndOrElseDiffer_thenCorrect() {
+ String text = "Text present";
+ LOG.debug("Using orElseGet:");
+ String defaultText = Optional.ofNullable(text)
+ .orElseGet(this::getMyDefault);
+ assertEquals("Text present", defaultText);
+
+ LOG.debug("Using orElse:");
+ defaultText = Optional.ofNullable(text)
+ .orElse(getMyDefault());
+ assertEquals("Text present", defaultText);
+ }
+
+ // Exceptions With orElseThrow
+ @Test(expected = IllegalArgumentException.class)
+ public void whenOrElseThrowWorks_thenCorrect() {
+ String nullName = null;
+ String name = Optional.ofNullable(nullName)
+ .orElseThrow(IllegalArgumentException::new);
+ }
+
+ @Test(expected = NoSuchElementException.class)
+ public void whenNoArgOrElseThrowWorks_thenCorrect() {
+ String nullName = null;
+ String name = Optional.ofNullable(nullName).orElseThrow();
+ }
+
+ public String getMyDefault() {
+ LOG.debug("Getting default value...");
+ return "Default Value";
+ }
+
+// Uncomment code when code base is compatible with Java 11
+// @Test
+// public void givenAnEmptyOptional_thenIsEmptyBehavesAsExpected() {
+// Optional opt = Optional.of("Baeldung");
+// assertFalse(opt.isEmpty());
+//
+// opt = Optional.ofNullable(null);
+// assertTrue(opt.isEmpty());
+// }
+
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-11-2/src/test/java/com/baeldung/reflection/OperationsUnitTest.java b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/reflection/OperationsUnitTest.java
new file mode 100644
index 0000000000..92f5b83f2b
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/reflection/OperationsUnitTest.java
@@ -0,0 +1,77 @@
+package com.baeldung.reflection;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertThat;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.junit.Test;
+
+public class OperationsUnitTest {
+
+ public OperationsUnitTest() {
+ }
+
+ @Test(expected = IllegalAccessException.class)
+ public void givenObject_whenInvokePrivateMethod_thenFail() throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+ Method andPrivateMethod = Operations.class.getDeclaredMethod("privateAnd", boolean.class, boolean.class);
+
+ Operations operationsInstance = new Operations();
+ Boolean result = (Boolean) andPrivateMethod.invoke(operationsInstance, true, false);
+
+ assertFalse(result);
+ }
+
+ @Test
+ public void givenObject_whenInvokePrivateMethod_thenCorrect() throws Exception {
+ Method andPrivatedMethod = Operations.class.getDeclaredMethod("privateAnd", boolean.class, boolean.class);
+ andPrivatedMethod.setAccessible(true);
+
+ Operations operationsInstance = new Operations();
+ Boolean result = (Boolean) andPrivatedMethod.invoke(operationsInstance, true, false);
+
+ assertFalse(result);
+ }
+
+ @Test
+ public void givenObject_whenInvokePrivateMethod_thenCheckAccess() throws Exception {
+ Operations operationsInstance = new Operations();
+ Method andPrivatedMethod = Operations.class.getDeclaredMethod("privateAnd", boolean.class, boolean.class);
+ boolean isAccessEnabled = andPrivatedMethod.canAccess(operationsInstance);
+
+ assertFalse(isAccessEnabled);
+ }
+
+ @Test
+ public void givenObject_whenInvokePublicMethod_thenEnableAccess() throws Exception {
+ Operations operationsInstance = new Operations();
+ Method andPrivatedMethod = Operations.class.getDeclaredMethod("privateAnd", boolean.class, boolean.class);
+ andPrivatedMethod.trySetAccessible();
+ boolean isAccessEnabled = andPrivatedMethod.canAccess(operationsInstance);
+
+ assertTrue(isAccessEnabled);
+ }
+
+ @Test
+ public void givenObject_whenInvokePublicMethod_thenCorrect() throws Exception {
+ Method sumInstanceMethod = Operations.class.getMethod("publicSum", int.class, double.class);
+
+ Operations operationsInstance = new Operations();
+ Double result = (Double) sumInstanceMethod.invoke(operationsInstance, 1, 3);
+
+ assertThat(result, equalTo(4.0));
+ }
+
+ @Test
+ public void givenObject_whenInvokeStaticMethod_thenCorrect() throws Exception {
+ Method multiplyStaticMethod = Operations.class.getDeclaredMethod("publicStaticMultiply", float.class, long.class);
+
+ Double result = (Double) multiplyStaticMethod.invoke(null, 3.5f, 2);
+
+ assertThat(result, equalTo(7.0));
+ }
+
+}
diff --git a/core-java-modules/core-java-11-2/src/test/java/com/baeldung/reflection/ReflectionUnitTest.java b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/reflection/ReflectionUnitTest.java
new file mode 100644
index 0000000000..c73fa5f8e0
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/reflection/ReflectionUnitTest.java
@@ -0,0 +1,295 @@
+package com.baeldung.reflection;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+
+public class ReflectionUnitTest {
+
+ @Test
+ public void givenObject_whenGetsFieldNamesAtRuntime_thenCorrect() {
+ final Object person = new Person();
+ final Field[] fields = person.getClass().getDeclaredFields();
+
+ final List actualFieldNames = getFieldNames(fields);
+
+ assertTrue(Arrays.asList("name", "age").containsAll(actualFieldNames));
+ }
+
+ @Test
+ public void givenObject_whenGetsClassName_thenCorrect() {
+ final Object goat = new Goat("goat");
+ final Class> clazz = goat.getClass();
+
+ assertEquals("Goat", clazz.getSimpleName());
+ assertEquals("com.baeldung.reflection.Goat", clazz.getName());
+ assertEquals("com.baeldung.reflection.Goat", clazz.getCanonicalName());
+ }
+
+ @Test
+ public void givenClassName_whenCreatesObject_thenCorrect() throws ClassNotFoundException {
+ final Class> clazz = Class.forName("com.baeldung.reflection.Goat");
+
+ assertEquals("Goat", clazz.getSimpleName());
+ assertEquals("com.baeldung.reflection.Goat", clazz.getName());
+ assertEquals("com.baeldung.reflection.Goat", clazz.getCanonicalName());
+ }
+
+ @Test
+ public void givenClass_whenRecognisesModifiers_thenCorrect() throws ClassNotFoundException {
+ final Class> goatClass = Class.forName("com.baeldung.reflection.Goat");
+ final Class> animalClass = Class.forName("com.baeldung.reflection.Animal");
+ final int goatMods = goatClass.getModifiers();
+ final int animalMods = animalClass.getModifiers();
+
+ assertTrue(Modifier.isPublic(goatMods));
+ assertTrue(Modifier.isAbstract(animalMods));
+ assertTrue(Modifier.isPublic(animalMods));
+ }
+
+ @Test
+ public void givenClass_whenGetsPackageInfo_thenCorrect() {
+ final Goat goat = new Goat("goat");
+ final Class> goatClass = goat.getClass();
+ final Package pkg = goatClass.getPackage();
+
+ assertEquals("com.baeldung.reflection", pkg.getName());
+ }
+
+ @Test
+ public void givenClass_whenGetsSuperClass_thenCorrect() {
+ final Goat goat = new Goat("goat");
+ final String str = "any string";
+
+ final Class> goatClass = goat.getClass();
+ final Class> goatSuperClass = goatClass.getSuperclass();
+
+ assertEquals("Animal", goatSuperClass.getSimpleName());
+ assertEquals("Object", str.getClass().getSuperclass().getSimpleName());
+
+ }
+
+ @Test
+ public void givenClass_whenGetsImplementedInterfaces_thenCorrect() throws ClassNotFoundException {
+ final Class> goatClass = Class.forName("com.baeldung.reflection.Goat");
+ final Class> animalClass = Class.forName("com.baeldung.reflection.Animal");
+ final Class>[] goatInterfaces = goatClass.getInterfaces();
+ final Class>[] animalInterfaces = animalClass.getInterfaces();
+
+ assertEquals(1, goatInterfaces.length);
+ assertEquals(1, animalInterfaces.length);
+ assertEquals("Locomotion", goatInterfaces[0].getSimpleName());
+ assertEquals("Eating", animalInterfaces[0].getSimpleName());
+ }
+
+ @Test
+ public void givenClass_whenGetsConstructor_thenCorrect() throws ClassNotFoundException {
+ final Class> goatClass = Class.forName("com.baeldung.reflection.Goat");
+ final Constructor>[] constructors = goatClass.getConstructors();
+
+ assertEquals(1, constructors.length);
+ assertEquals("com.baeldung.reflection.Goat", constructors[0].getName());
+ }
+
+ @Test
+ public void givenClass_whenGetsFields_thenCorrect() throws ClassNotFoundException {
+ final Class> animalClass = Class.forName("com.baeldung.reflection.Animal");
+ final Field[] fields = animalClass.getDeclaredFields();
+
+ final List actualFields = getFieldNames(fields);
+
+ assertEquals(2, actualFields.size());
+ assertTrue(actualFields.containsAll(Arrays.asList("name", "CATEGORY")));
+ }
+
+ @Test
+ public void givenClass_whenGetsMethods_thenCorrect() throws ClassNotFoundException {
+ final Class> animalClass = Class.forName("com.baeldung.reflection.Animal");
+ final Method[] methods = animalClass.getDeclaredMethods();
+ final List actualMethods = getMethodNames(methods);
+
+ assertEquals(3, actualMethods.size());
+ assertTrue(actualMethods.containsAll(Arrays.asList("getName", "setName", "getSound")));
+ }
+
+ @Test
+ public void givenClass_whenGetsAllConstructors_thenCorrect() throws ClassNotFoundException {
+ final Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ final Constructor>[] constructors = birdClass.getConstructors();
+
+ assertEquals(3, constructors.length);
+ }
+
+ @Test
+ public void givenClass_whenGetsEachConstructorByParamTypes_thenCorrect() throws Exception {
+ final Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ birdClass.getConstructor();
+ birdClass.getConstructor(String.class);
+ birdClass.getConstructor(String.class, boolean.class);
+ }
+
+ @Test
+ public void givenClass_whenInstantiatesObjectsAtRuntime_thenCorrect() throws Exception {
+ final Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+
+ final Constructor> cons1 = birdClass.getConstructor();
+ final Constructor> cons2 = birdClass.getConstructor(String.class);
+ final Constructor> cons3 = birdClass.getConstructor(String.class, boolean.class);
+
+ final Bird bird1 = (Bird) cons1.newInstance();
+ final Bird bird2 = (Bird) cons2.newInstance("Weaver bird");
+ final Bird bird3 = (Bird) cons3.newInstance("dove", true);
+
+ assertEquals("bird", bird1.getName());
+ assertEquals("Weaver bird", bird2.getName());
+ assertEquals("dove", bird3.getName());
+ assertFalse(bird1.walks());
+ assertTrue(bird3.walks());
+ }
+
+ @Test
+ public void givenClass_whenGetsPublicFields_thenCorrect() throws ClassNotFoundException {
+ final Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ final Field[] fields = birdClass.getFields();
+ assertEquals(1, fields.length);
+ assertEquals("CATEGORY", fields[0].getName());
+
+ }
+
+ @Test
+ public void givenClass_whenGetsPublicFieldByName_thenCorrect() throws Exception {
+ final Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ final Field field = birdClass.getField("CATEGORY");
+ assertEquals("CATEGORY", field.getName());
+
+ }
+
+ @Test
+ public void givenClass_whenGetsDeclaredFields_thenCorrect() throws ClassNotFoundException {
+ final Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ final Field[] fields = birdClass.getDeclaredFields();
+ assertEquals(1, fields.length);
+ assertEquals("walks", fields[0].getName());
+ }
+
+ @Test
+ public void givenClass_whenGetsFieldsByName_thenCorrect() throws Exception {
+ final Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ final Field field = birdClass.getDeclaredField("walks");
+ assertEquals("walks", field.getName());
+
+ }
+
+ @Test
+ public void givenClassField_whenGetsType_thenCorrect() throws Exception {
+ final Field field = Class.forName("com.baeldung.reflection.Bird").getDeclaredField("walks");
+ final Class> fieldClass = field.getType();
+ assertEquals("boolean", fieldClass.getSimpleName());
+ }
+
+ @Test
+ public void givenClassField_whenSetsAndGetsValue_thenCorrect() throws Exception {
+ final Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ final Bird bird = (Bird) birdClass.getConstructor().newInstance();
+ final Field field = birdClass.getDeclaredField("walks");
+ field.setAccessible(true);
+
+ assertFalse(field.getBoolean(bird));
+ assertFalse(bird.walks());
+
+ field.set(bird, true);
+
+ assertTrue(field.getBoolean(bird));
+ assertTrue(bird.walks());
+
+ }
+
+ @Test
+ public void givenClassField_whenGetsAndSetsWithNull_thenCorrect() throws Exception {
+ final Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ final Field field = birdClass.getField("CATEGORY");
+ field.setAccessible(true);
+
+ assertEquals("domestic", field.get(null));
+ }
+
+ @Test
+ public void givenClass_whenGetsAllPublicMethods_thenCorrect() throws ClassNotFoundException {
+ final Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ final Method[] methods = birdClass.getMethods();
+ final List methodNames = getMethodNames(methods);
+
+ assertTrue(methodNames.containsAll(Arrays.asList("equals", "notifyAll", "hashCode", "walks", "eats", "toString")));
+
+ }
+
+ @Test
+ public void givenClass_whenGetsOnlyDeclaredMethods_thenCorrect() throws ClassNotFoundException {
+ final Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ final List actualMethodNames = getMethodNames(birdClass.getDeclaredMethods());
+
+ final List expectedMethodNames = Arrays.asList("setWalks", "walks", "getSound", "eats");
+
+ assertEquals(expectedMethodNames.size(), actualMethodNames.size());
+ assertTrue(expectedMethodNames.containsAll(actualMethodNames));
+ assertTrue(actualMethodNames.containsAll(expectedMethodNames));
+
+ }
+
+ @Test
+ public void givenMethodName_whenGetsMethod_thenCorrect() throws Exception {
+ final Bird bird = new Bird();
+ final Method walksMethod = bird.getClass().getDeclaredMethod("walks");
+ final Method setWalksMethod = bird.getClass().getDeclaredMethod("setWalks", boolean.class);
+
+ assertTrue(walksMethod.canAccess(bird));
+ assertTrue(setWalksMethod.canAccess(bird));
+ }
+
+ @Test
+ public void givenMethod_whenInvokes_thenCorrect() throws Exception {
+ final Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ final Bird bird = (Bird) birdClass.getConstructor().newInstance();
+ final Method setWalksMethod = birdClass.getDeclaredMethod("setWalks", boolean.class);
+ final Method walksMethod = birdClass.getDeclaredMethod("walks");
+ final boolean walks = (boolean) walksMethod.invoke(bird);
+
+ assertFalse(walks);
+ assertFalse(bird.walks());
+
+ setWalksMethod.invoke(bird, true);
+ final boolean walks2 = (boolean) walksMethod.invoke(bird);
+
+ assertTrue(walks2);
+ assertTrue(bird.walks());
+
+ }
+
+ private static List getFieldNames(Field[] fields) {
+ final List fieldNames = new ArrayList<>();
+ for (final Field field : fields) {
+ fieldNames.add(field.getName());
+ }
+ return fieldNames;
+
+ }
+
+ private static List getMethodNames(Method[] methods) {
+ final List methodNames = new ArrayList<>();
+ for (final Method method : methods) {
+ methodNames.add(method.getName());
+ }
+ return methodNames;
+ }
+
+}
diff --git a/core-java-modules/core-java-11-2/src/test/java/com/baeldung/version/VersionManualTest.java b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/version/VersionManualTest.java
new file mode 100644
index 0000000000..74035a3e2f
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/version/VersionManualTest.java
@@ -0,0 +1,49 @@
+package com.baeldung.version;
+
+import org.apache.commons.lang3.SystemUtils;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+
+// manual test as the runtime JDK version can be different depending on where the test is run
+public class VersionManualTest {
+
+ @Test
+ public void givenJava_whenUsingRuntime_thenGetVersion() {
+ String expectedVersion = "15";
+ Runtime.Version runtimeVersion = Runtime.version();
+ String version = String.valueOf(runtimeVersion.version().get(0));
+ Assertions.assertThat(version).isEqualTo(expectedVersion);
+ }
+
+ @Test
+ @Disabled("Only valid for Java 8 and lower")
+ public void givenJava_whenUsingCommonsLang_thenGetVersion() {
+ int expectedVersion = 8;
+ String[] versionElements = SystemUtils.JAVA_SPECIFICATION_VERSION.split("\\.");
+ int discard = Integer.parseInt(versionElements[0]);
+ int version;
+ if (discard == 1) {
+ version = Integer.parseInt(versionElements[1]);
+ } else {
+ version = discard;
+ }
+ Assertions.assertThat(version).isEqualTo(expectedVersion);
+ }
+
+ @Test
+ @Disabled("Only valid for Java 8 and lower")
+ public void givenJava_whenUsingSystemProp_thenGetVersion() {
+ int expectedVersion = 8;
+ String[] versionElements = System.getProperty("java.version").split("\\.");
+ int discard = Integer.parseInt(versionElements[0]);
+ int version;
+ if (discard == 1) {
+ version = Integer.parseInt(versionElements[1]);
+ } else {
+ version = discard;
+ }
+ Assertions.assertThat(version).isEqualTo(expectedVersion);
+ }
+}
+