diff --git a/pom.xml b/pom.xml
index 3ba105d..f59eae4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -90,7 +90,7 @@
com.fasterxml.jackson.core
jackson-databind
- 2.13.2.1
+ 2.13.4.2
org.assertj
diff --git a/src/main/java/java11/FeatureTest.java b/src/main/java/java11/FeatureTest.java
new file mode 100644
index 0000000..46b13dd
--- /dev/null
+++ b/src/main/java/java11/FeatureTest.java
@@ -0,0 +1,49 @@
+package java11;
+
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+//import javax.annotation.Nonnull;
+import lombok.NonNull;
+
+/**
+ * No need to compile, just run: java FeatureTest.java
+ */
+public class FeatureTest {
+ public static void main(String[] args) {
+ String multilineString = "This is a text \n \n from \n new line!";
+
+ // introducing lines() stream
+ List lines = multilineString.lines()
+ .filter(line -> !line.isBlank())
+ .map(String::strip)
+ .collect(Collectors.toList());
+
+ System.out.println(lines);
+
+ // introducing toArray()
+ String[] arr = lines.toArray(String[]::new);
+
+ for(String s: arr) System.out.println(s);
+
+ lines.add(" ");
+ System.out.println(lines);
+
+ // introducing not method in Predicate
+ List withoutBlanks = lines.stream()
+ .filter(Predicate.not(String::isBlank))
+ .collect(Collectors.toList());
+
+ System.out.println(withoutBlanks);
+
+ // introducing local-variable syntax
+ String resultString = lines.stream()
+ .map((@NonNull var x) -> x.toUpperCase())
+ .collect(Collectors.joining(", "));
+
+ System.out.println(resultString);
+
+ }
+
+}
diff --git a/src/main/java/java8/FunctionalInterfaceTest.java b/src/main/java/java8/FunctionalInterfaceTest.java
new file mode 100644
index 0000000..3027e5c
--- /dev/null
+++ b/src/main/java/java8/FunctionalInterfaceTest.java
@@ -0,0 +1,22 @@
+package java8;
+
+public class FunctionalInterfaceTest {
+
+ public static void main(String[] args) {
+ FunctionalInterfaceTest fit = new FunctionalInterfaceTest();
+ Functionalnterface fi = new Functionalnterface();
+ fi.setFi(fit::getConvertedValue);
+
+ fi.checkFi("9");
+ }
+
+ public void test() {
+ Functionalnterface fi = new Functionalnterface();
+ fi.setFi(this::getConvertedValue);
+ fi.checkFi("9");
+ }
+
+ public Integer getConvertedValue(String str) {
+ return Integer.valueOf(str);
+ }
+}
diff --git a/src/main/java/java8/Functionalnterface.java b/src/main/java/java8/Functionalnterface.java
index 391b706..146b354 100644
--- a/src/main/java/java8/Functionalnterface.java
+++ b/src/main/java/java8/Functionalnterface.java
@@ -1,7 +1,11 @@
package java8;
+import java.util.function.Function;
+
public class Functionalnterface {
+ Function fi;
+
public static void main(String[] args) {
Converter converter = (from) -> Integer.valueOf(from);
Integer converted = converter.convert("123");
@@ -18,6 +22,14 @@ public static void main(String[] args) {
tester.test();
}
+
+ public void setFi(Function fi){
+ this.fi = fi;
+ }
+
+ public void checkFi(String str) {
+ System.out.println(this.fi.apply(str));
+ }
@FunctionalInterface
interface Converter {
diff --git a/src/main/java/java8/README.md b/src/main/java/java8/README.md
index f99df12..34d86ef 100644
--- a/src/main/java/java8/README.md
+++ b/src/main/java/java8/README.md
@@ -63,3 +63,18 @@ Lambda expressions can only appear in places where they will be assigned to a va
One issue with anonymous classes is that if the implementation of your anonymous class is very simple, such as an interface that contains only one method, then the syntax of anonymous classes may seem unwieldy and unclear. In these cases, you're usually trying to pass functionality as an argument to another method, such as what action should be taken when someone clicks a button. Lambda expressions enable you to do this, to treat functionality as method argument, or code as data.
Anonymous Classes, shows you how to implement a base class without giving it a name. Although this is often more concise than a named class, for classes with only one method, even an anonymous class seems a bit excessive and cumbersome. Lambda expressions let you express instances of single-method classes more compactly.
+
+
+### Streams
+
+1. The main difference between intermediate and terminal operations is that intermediate operations return a stream as a result and terminal operations return non-stream values like primitive or object or collection or may not return anything.
+
+2. As intermediate operations return another stream as a result, they can be chained together to form a pipeline of operations. Terminal operations cannot be chained together.
+
+3. Pipeline of operations may contain any number of intermediate operations, but there has to be only one terminal operation, that too at the end of pipeline.
+
+4. Intermediate operations are lazily loaded. When you call intermediate operations, they are actually not executed. They are just stored in the memory and executed when the terminal operation is called on the stream.
+
+5. As the names suggest, intermediate operations doesn’t give end result. They just transform one stream to another stream. On the other hand, terminal operations give end result.
+
+
\ No newline at end of file
diff --git a/src/main/java/java8/SupplierTest.java b/src/main/java/java8/SupplierTest.java
new file mode 100644
index 0000000..dfd8f8d
--- /dev/null
+++ b/src/main/java/java8/SupplierTest.java
@@ -0,0 +1,124 @@
+package java8;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.function.Supplier;
+
+/*
+ @FunctionalInterface
+ public interface Supplier {
+ T get();
+ }
+ */
+public class SupplierTest {
+
+ private static final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+ public static void main(String[] args) {
+
+ Supplier s = () -> LocalDateTime.now();
+ LocalDateTime time = s.get();
+
+ System.out.println(time);
+
+ Supplier s1 = () -> dtf.format(LocalDateTime.now());
+ String time2 = s1.get();
+
+ System.out.println(time2);
+
+ // ---------------------------------------------------------- //
+
+ SupplierTest obj = new SupplierTest<>();
+ List list = obj.supplier().get();
+
+ // ---------------------------------------------------------- //
+
+ Developer dev = factory(Developer::new);
+ System.out.println(dev);
+
+ Developer dev2 = factory(() -> new Developer("vinkrish"));
+ System.out.println(dev2);
+
+ // ---------------------------------------------------------- //
+
+ System.out.println(new Developer().callRandomString.get());
+
+ }
+
+ public Supplier> supplier() {
+
+ // lambda
+ // return () -> new ArrayList<>();
+
+ // constructor reference
+ return ArrayList::new;
+
+ }
+
+ public static Developer factory(Supplier extends Developer> s) {
+
+ Developer developer = s.get();
+ if (developer.getName() == null || "".equals(developer.getName())) {
+ developer.setName("default");
+ }
+ developer.setSalary(BigDecimal.ONE);
+ developer.setStart(LocalDate.of(2017, 8, 8));
+
+ return developer;
+
+ }
+}
+
+class DeveloperParent {
+
+ /*
+ return Config instead of String,
+ let calling child read config values (Typesafe Config).getString("some.field")
+ */
+ public static String getRandomString() {
+ return "Hello From Supplier!";
+ }
+
+}
+
+class Developer extends DeveloperParent{
+
+ String name;
+ BigDecimal salary;
+ LocalDate start;
+
+ // for factory(Developer::new);
+ public Developer() {
+ }
+
+ // for factory(() -> new Developer("vinkrish"));
+ public Developer(String name) {
+ this.name = name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setSalary(BigDecimal salary) {
+ this.salary = salary;
+ }
+
+ public void setStart(LocalDate start) {
+ this.start = start;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public String toString() {
+ return this.name + " - " + this.salary + " - " + this.start;
+ }
+
+ public Supplier callRandomString = () -> getRandomString();
+
+}
diff --git a/src/main/java/java9/ListOf.java b/src/main/java/java9/ListOf.java
new file mode 100644
index 0000000..0cf97b3
--- /dev/null
+++ b/src/main/java/java9/ListOf.java
@@ -0,0 +1,25 @@
+package java9;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class ListOf {
+
+ public static void main(String[] args) {
+
+ final List list = new ArrayList(Arrays.asList("one", "two", "three"));
+ final List unmodifiableList = List.of(list.toArray(new String[]{}));
+
+ /**
+ * unmodifiableList.add("four");
+ *
+ * Exception in thread "main" java.lang.UnsupportedOperationException
+ at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:142)
+ at java.base/java.util.ImmutableCollections$AbstractImmutableCollection.add(ImmutableCollections.java:147)
+ at java9.ListOf.main(ListOf.java:13)
+ */
+
+ }
+
+}
diff --git a/src/main/java/java9/MapOf.java b/src/main/java/java9/MapOf.java
new file mode 100644
index 0000000..9d95589
--- /dev/null
+++ b/src/main/java/java9/MapOf.java
@@ -0,0 +1,68 @@
+package java9;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class MapOf {
+
+ public static void main(String[] args) {
+ // Immutable Map
+ Map map = Map.of(101, "A", 102, "B", 103, "C");
+ map.forEach((k, v) -> System.out.println(k + " - " + v));
+
+ /**
+ * map.put(104, "SS");
+ * Exception in thread "main" java.lang.UnsupportedOperationException
+ at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:142)
+ at java.base/java.util.ImmutableCollections$AbstractImmutableMap.put(ImmutableCollections.java:1072)
+ at java9.MapOf.main(MapOf.java:11)
+ */
+
+ // Immutable Map with Immutable List
+ List imtList1 = List.of("A1", "B1");
+ List imtList2 = List.of("A2", "B2");
+
+ Map> map2 = Map.of(111, imtList1, 222, imtList2);
+ System.out.println(map2);
+
+ // unmodifiable Map with mutable List
+ List list1 = new ArrayList();
+ list1.add("A1");
+ list1.add("B1");
+ List list2 = new ArrayList();
+ list2.add("A2");
+ list2.add("B2");
+
+ Map> map3 = Map.of(111, list1, 222, list2);
+ System.out.println("Mutable List :" + map3);
+
+ list1.add("R1");
+ System.out.println("Mutable List :" + map3);
+
+ // Immutable Map with custom Immutable class
+ CustomImmutableStudent s1 = new CustomImmutableStudent(33, "Vinay");
+ CustomImmutableStudent s2 = new CustomImmutableStudent(24, "Angel");
+
+ Map map4 = Map.of("one", s1, "two", s2);
+ map4.forEach((k, v) -> System.out.println(k + " - " + v.getName()));
+ }
+
+}
+
+final class CustomImmutableStudent {
+ final private int age;
+ final private String name;
+ public CustomImmutableStudent(final int age, final String name) {
+ this.age = age;
+ this.name = name;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/src/main/java/java9/MapOfEntries.java b/src/main/java/java9/MapOfEntries.java
new file mode 100644
index 0000000..c852f8e
--- /dev/null
+++ b/src/main/java/java9/MapOfEntries.java
@@ -0,0 +1,32 @@
+package java9;
+
+import java.util.Map;
+import static java.util.Map.entry;
+
+import java.util.List;
+
+public class MapOfEntries {
+
+ public static void main(String[] args) {
+ // Immutable Map
+ Map map = Map.ofEntries(
+ entry(101, "A"),
+ entry(102, "B"),
+ entry(103, "C")
+ );
+ map.forEach((k, v) -> System.out.println(k + " - " + v));
+
+ // Immutable Map with Immutable List
+ List imtList1 = List.of("A1", "B1");
+ List imtList2 = List.of("A2", "B2");
+
+ Map> map2 = Map.ofEntries(
+ entry(111, imtList1),
+ entry(222, imtList2)
+ );
+ System.out.println(map2);
+
+ // Similar approach to MapOf...
+ }
+
+}
diff --git a/src/main/java/java9/SetOf.java b/src/main/java/java9/SetOf.java
new file mode 100644
index 0000000..a647f08
--- /dev/null
+++ b/src/main/java/java9/SetOf.java
@@ -0,0 +1,67 @@
+package java9;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class SetOf {
+
+ public static void main(String[] args) {
+ // Immutable Set with Immutable Set Objects
+ Set imtSet1 = Set.of("A1", "B1", "C1");
+ Set imtSet2 = Set.of("A2", "B2", "C2");
+
+ Set> imtFinalSet = Set.of(imtSet1, imtSet2);
+ System.out.println(imtFinalSet);
+
+ // unmodifiable Set containing the mutable objects is not the immutable Set
+ Set set1 = new HashSet();
+ set1.add("A1");
+ set1.add("B1");
+ set1.add("C1");
+ Set set2 = new HashSet();
+ set2.add("A2");
+ set2.add("B2");
+ set2.add("C2");
+
+ Set> finalSet = Set.of(set1, set2);
+ System.out.println(finalSet);
+
+ set1.add("D1");
+ System.out.println(finalSet);
+
+ // Immutable Set containing objects of custom immutable class
+ Student s1 = new Student(33, "Moda");
+ Student s2 = new Student(24, "Everest");
+ Student s3 = new Student(0, "Kailani");
+
+ Set imtSet = Set.of(s1, s2, s3);
+ imtSet.forEach(s -> System.out.println(s.getName()));
+ }
+
+}
+class Student {
+ final private int age;
+ final private String name;
+ public Student(final int age, final String name) {
+ this.age = age;
+ this.name = name;
+ }
+ public int getAge() {
+ return age;
+ }
+
+ public String getName() {
+ return name;
+ }
+ @Override
+ public boolean equals(Object ob) {
+ return name.equals(((Student)ob).name) &&
+ age == ((Student)ob).age;
+ }
+ @Override
+ public int hashCode() {
+ int hash = 13;
+ hash = (31 * hash) + (null == name ? 0 : name.hashCode());
+ return hash;
+ }
+ }
diff --git a/src/main/java/java9/UnmodifiableMap.java b/src/main/java/java9/UnmodifiableMap.java
new file mode 100644
index 0000000..dd24dcf
--- /dev/null
+++ b/src/main/java/java9/UnmodifiableMap.java
@@ -0,0 +1,26 @@
+package java9;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+public class UnmodifiableMap {
+
+ /*
+ * If we perform add, update or delete operation on source Map specified to Collections.unmodifiableMap()
+ * then the unmodifiable Map returned by this method will also change.
+ */
+ public static void main(String[] args) {
+ Map map = new HashMap();
+ map.put(101, "A");
+ map.put(102, "B");
+
+ Map unmodMap = Collections.unmodifiableMap(map);
+ System.out.println(unmodMap);
+
+ map.put(103, "C");
+ System.out.println(unmodMap);
+
+ }
+
+}
diff --git a/src/main/java/java9/UnmodifiableSet.java b/src/main/java/java9/UnmodifiableSet.java
new file mode 100644
index 0000000..9f6ae74
--- /dev/null
+++ b/src/main/java/java9/UnmodifiableSet.java
@@ -0,0 +1,28 @@
+package java9;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+public class UnmodifiableSet {
+
+ public static void main(String[] args) {
+
+ /*
+ * Performing add, update or delete operation on source Set specified to Collections.unmodifiableSet()
+ * then the unmodifiable Set returned by this method will also change.
+ */
+ Set set = new HashSet();
+ set.add("A");
+ set.add("B");
+ set.add("C");
+
+ Set unmodSet = Collections.unmodifiableSet(set);
+ System.out.println(unmodSet);
+
+ set.add("D");
+ System.out.println(unmodSet);
+
+ }
+
+}
diff --git a/src/main/java/set/HashSetTest.java b/src/main/java/set/HashSetTest.java
index d1d7d47..850b05a 100644
--- a/src/main/java/set/HashSetTest.java
+++ b/src/main/java/set/HashSetTest.java
@@ -28,7 +28,65 @@ public static void main(String[] args) {
Iterator i = h.iterator();
while (i.hasNext())
System.out.println(i.next());
+
+
+ Employee employee = new Employee("rajeev", 24);
+ Employee employee1 = new Employee("rajeev", 25);
+ Employee employee2 = new Employee("rajeev", 24);
+
+ HashSet employees = new HashSet();
+ employees.add(employee);
+ employees.add(employee1);
+ System.out.println(employees.contains(employee2));
+ System.out.println("employee.hashCode(): " + employee.hashCode()
+ + " employee2.hashCode():" + employee2.hashCode());
}
}
+
+class Employee {
+
+ private String name;
+ private int age;
+
+ public Employee(String name, int age) {
+ this.name = name;
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this)
+ return true;
+ if (!(obj instanceof Employee))
+ return false;
+ Employee employee = (Employee) obj;
+ return employee.getAge() == this.getAge()
+ && this.getName().equals(getName());
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 17;
+ hash = 31 * hash + age;
+ hash = 31 * hash + (name!=null ? name.hashCode():0);
+ return hash;
+ }
+}