Pages

Friday 27 December 2019

Java 8 Date Time API


Why did Java 8 introduce a new date and time API when it already had classes such as Date and Calendar?
Below are the main reasons
1.Bad API design. For example, The Date class has both date and time components, if you only want time information and not date-related information, you have to set the date-related value to zero. Some aspects of the classes are unintuitive as well. For example, in the Date constructor, the range of date values is 1 to 31 but the range of month values is 0 to 11(not 1 to 12).
2.Java.util.Date,java.util.Calendar,java.time.SimpleDateFormatter classes are not thread-safe.

Java 8 provides very good support for date and time-related functionality in the newly introduced package java.time package.
Most of the classes in this package are immutable and thread-safe. We will learn LocalDate, LocalTime, LocalDateTime,Instant,Period, Duration,TemporalUnit and DateTimeFormatter.

The java.time package consists of four sub-packages
java.time.temporal: Access date/time fields and units.
java.time.format: Formats the input and output of date/time objects.
java.time.zone: Handles time zones.
java.time.chrono: Supports calendar systems such as Japanese and Thai Calendars.

LocalDate
java.time.LocalDate represents a date without time or time zone. LocalDate is represented in the ISO-8601 calendar system in a year-month-day format(YYYY-MM-DD). For example,2019-12-27.

How to get today's date?
LocalDate today = LocalDate.now();

LocalTime
java.time.LocalTime class is similar to LocalDate except that LocalTime represents time without dates or time zones. The time is in the ISO-8601 calendar system format HH:MM:SS: nanosecond.

How to get the current time?
LocalTime  currentTime = LocalTime.now();

LocalDateTime
This class java.time.LocalDateTime represents both data and time without time zones.
You can think of LocalDateTime as a logical combination of the LocalTime and LocalDate classes. The date and time formats use the ISO-8601 calendar system:
YYYY-MM-DD HH:MM: SS.nanosecond. For example,
LocalDateTime dateTime =LocalDateTime.now();

Instant
Represents machine time starting from Unix epoch(1970-01-01T00:00:00Z)
Typically used for timestamps
Instant instant = Instant.now();

What is the difference between LocalDateTime and Instant?
LocalDateTime uses the default time zone, but Instant does not.
For examaple,
LocalDateTime dateTime =LocalDateTime.now();//2019-12-27T15:27:27.139835100
Instant instant = Instant.now();//2019-12-27T09:57:27.139835100Z

Period
Represents the amount of time in terms of years, months and days.
Typically used for difference between two LocalDate objects.
How to find out when medicine will expire?
 LocalDate manufactureDate = LocalDate.of(2018,Month.MARCH,15);
 LocalDate expiryDate = LocalDate.of(2021, Month.JULY, 20);
 Period expire = Period.between(manufactureDate, expiryDate);
 System.out.println(expire);//P3Y4M5D, here P-> Period, Y-> Year, M-> Month, D-> Day
System.out.println(expire.getYears()+"Years "+expire.getMonths()+"Months "+expire.getDays()+"Days");//3Years 4Months 5Days

Duration
Represents the amount of time in terms of hours, minutes, seconds and fractions of seconds.
Typically used for difference between two LocalTime objects.

How to find out how many hours to go, to wish your best friend's birthday?
LocalDateTime comingMidnight = LocalDateTime.of(LocalDate.now().plusDays(1),LocalTime.MIDNIGHT);
LocalDateTime now1 = LocalDateTime.now();
Duration duration =Duration.between(now1, comingMidnight);
System.out.println(duration);//PT8H9M29.7853329S, Here PT-> Period Time, H-> Hour, M-> Minute, S->Second

TemporalUnit
The TemporalUnit interface is the part of java.time.temporal package.
It represents date or time units such as seconds, hours, days, months, years, etc.
The enumeration java.util.temporal.ChronoUnit implements TemporalUnit interface.
Instead of using constant values, it is better to use their equivalent enumeration values. Beacuase using enumeration values in ChronoUnit results in more readable code;further, you are less likely to make mistakes. For example,
System.out.println(Duration.of(1, ChronoUnit.MINUTES).getSeconds());//60
System.out.println(Duration.of(1, ChronoUnit.HOURS).getSeconds());//3600
System.out.println(Duration.of(1, ChronoUnit.DAYS).getSeconds());//86400

Time Zone
There are three important classes related to time zones that you need to know in order to work with dates and times across time zones.
  1. ZoneId
  2. ZoneOffset
  3. ZoneDateTime
ZoneId
The java.time.ZoneId class represents time zones. Time zones are typically identified using an offset from Greenwich Mean Time(GMT, also known as UTC/Greenwich).
For example, the time zone of India is Asia/Calcutta
System.out.println(ZoneId.systemDefault());//Asia/Calcutta

ZoneOffset
It represents the time-zone offset from UTC/Greenwich. For example, zone ID "Asia/Calcutta" has a zone offset of +5:30(plus 5 hours and 30 minutes) from UTC/Greenwich.
The ZoneOffset class is the child class of ZoneId class.

ZonedDateTime
If you want all three- date, time, and time zone together. For that, you can use the ZoneDateTime class.
LocalDate currentDate = LocalDate.now();
 LocalTime currentTime = LocalTime.now();
 ZoneId myZone = ZoneId.systemDefault();
 ZonedDateTime zoneDateTime = ZonedDateTime.of(currentDate,currentTime,myZone);
System.out.println(zoneDateTime);//2019-12-27T16:14:59.424905800+05:30[Asia/Calcutta]

Formatting Dates and Times
Using java.time.format.DateTimeFormatter class you can format the date and time according to your requirement.
DateTimeFormatter class provides many predefined constants for formatting date and time values.
Here is a list of a few such predefined formatters.
ISO_DATE(2019-12-27)
ISO_TIME(11:30:25.624)
ISO_ZONED_DATE_TIME(2019-12-27T16:14:59.424905800+05:30[Asia/Calcutta])
RFC_1123_DATE_TIME(Thu,26 Dec 2019 11:27:30+0530)
For example,
  LocalTime wakeupTime = LocalTime.of(6,0,0);
  System.out.println(DateTimeFormatter.ISO_TIME.format(wakeupTime));// 06:00:00

If you want to use a custom format instead of any of the predefined format. To do so, you can use the
ofPattern() method in the DateTimeFormatter class.
DateTimeFormatter customFormat = DateTimeFormatter.ofPattern("dd/MM/yyyy");
System.out.println(customFormat.format(LocalDate.of(2019,Month.MARCH,01)));//01/03/2019

Important letters and their meanings for creating patterns for dates
G(era: BC,AD)
y(year of the era: 2020,20)
Y(week based year: 2020,20)
M(month:3,Mar,November)
w(week in year: 12)
W(week in month: 3)
E(day name in week: Sun, Sunday)
D(day of year: )
d(day of month)

Example:
class DateFormatter{
public static void main(String[] args) {
String[] dateFormats = { "d-M-y",
                                                 "dd-MM-yy",
                                                  "dd-MMM-yyy",
                                                  "dd-MM-yyyy", 
                                                   "D-MM-yyyy",
                                                   "DD-MM-yyyy",
                    "DDD-MM-yyyy",
                                                    "d - MMM- Y",
                                                    "w'th week of' YY",
                                                    "w'th week of' YYY",
                                                   "E, dd'th' MMMM,YYYY",
                    "EE, dd'th' MMMM,YYYY",
                                                    "EEE, dd'th' MMMM,YYYY",
                                                    "EEEE, dd'th' MMMM,YYYY" };
Arrays.stream(dateFormats)
.forEach(i -> System.out.println(DateTimeFormatter.ofPattern(i).format(LocalDate.now())));

}
}

Important letters and their meanings for creating patterns for time
a(marker for the text a.m/p.m marker)
H(hour:value range 0-23)
k(hour value range 1-24)
K(hour in an a.m/p.m :value range 0-11)
h(hour in a.m/p.m : value range 1-12)
m(minute)
s(second)
S(fraction of a second)
z(time zone: general time-zone format)

class TimeFormatter{
public static void main(String[] args) {
String[] timeFormats = {    "h:mm",
                                            "hh 'o''clock'",
                                            "H:mm a",
                                            "hh:mm:ss:SS",
                                            "K:mm:ss a"
                                                          };
Arrays.stream(timeFormats)
.forEach(i -> System.out.println(DateTimeFormatter.ofPattern(i).format(LocalTime.now())));

}
}

Saturday 14 December 2019

Collection

The collection framework is very important for fresher and experienced developers. You must have a good hold on it if you want to crack java interviews. You are supposed to prepare theoretical, coding and scenario-based questions related to this topic. I will try to explain each concept and interview questions of the Collection framework in a simple way. Almost, in all the interview it is asked that what is the difference between List, Set, Map, etc. How will you choose which Collection is suitable for a particular situation? With the help of the below diagram, you can answer the above questions with confidence. So please spend some time in the below diagram.

Collection Framework 

Tuesday 22 October 2019

Dependency Injection


What is Dependency Injection aka Inversion of control?
Let's understand first "coupling". When one class depends on another, they are called coupled.
Coupled class can't be tested in isolation.
For example: Client depends on  BookService, BookService depends on BookDAO, BookDAO depends on JdbcRepository.
  1. class Client{
  2. public static void main(String[] args){
  3. Book book = new Book(1,"Effective Java","Joshua Bloch");
  4. BookService service = new BookService();//dependency
  5. service.add(book);
  6. }
  7. }
  1. class Book{
  2. private int bookId;
  3. private String name;
  4. private String author;
  5. Book(int bookId,String name,String author){
  6. this.bookId=bookId;
  7. this.name=name;
  8. this.author=author;
  9. }
  10. //getters & setters
  11. }
  1. class BookService{
  2. private BookDAO bookDao = new BookDAO();//dependency
  3. public void add(Book book){
  4. bookDao.save(book);
  5. }
  6. }
  1. class BookDAO{
  2. private JdbcRepository repository = new JdbcRepository();//dependency
  3. public void save(Book book){
  4. repository.save(book);
  5. }
  6. }
How can we reduce coupling?
  • Program to interfaces(Still have coupling because of new operator).
  • Dependency Injection(Pass collaborators in as parameters rather than hard-coding them).
  • Centralize Configuration(Capture all the dependencies in one place. Use a "container" to create and configure your objects.)
  1. public class Client {
  2. public static void main(String[] args) {
  3. BookService service = Container.getBookServiceInstance();
  4. Book book = new Book(1,"Effective Java","Joshua Bloch");
  5. service.save(book);
  6. }
  7. }
  1. class Book{
  2. private int bookId;
  3. private String name;
  4. private String author;
  5. Book(int bookId,String name,String author){
  6. this.bookId=bookId;
  7. this.name=name;
  8. this.author=author;
  9. }
  10. //getters & setters
  11. }
  1. interface BookService{
  2. public void save(Book book);
  3. public void delete(int bookId);
  4. public void update(Book book);
  5. }
  1. class BookServiceImpl implements BookService{
  2.  private BookDAO bookDao = Container.getBookDaoInstance();
  3. @Override
  4. public void save(Book book) {
  5. bookDao.save(book);
  6. }
  7. @Overridpublic void delete(int bookId) {
  8. // logic
  9. }
  10. @Override
  11. public void update(Book book) {
  12. // logic
  13. }
  14. }
  1. interface BookDAO{
  2. public void save(Book book);
  3. public void delete(int bookId);
  4. public void update(Book book);
  5. }
  1. class JdbcImpl implements BookDAO{
  2. @Override
  3. public void save(Book book) {
  4. //logic
  5. }
  6. @Override
  7. public void delete(int bookId) {
  8. // logic
  9. }
  10. @Override
  11. public void update(Book book) {
  12. // logic
  13. }
  14. }
  1. class HibernateDao implements BookDAO{
  2. @Override
  3. public void save(Book book) {
  4. System.out.println("Book is saving into the database");
  5. }
  6. @Override
  7. public void delete(int bookId) {
  8. // logic
  9. }
  10. @Override
  11. public void update(Book book) {
  12. // logic
  13. }
  14. }
  1. class Container{
  2. public static BookDAO getBookDaoInstance() {
  3. return new HibernateDao();
  4. }
  5. public static BookService getBookServiceInstance() {
  6. return new BookServiceImpl();
  7. }
  8. }

Sunday 6 October 2019

Expectations

General

General expectation of client from core java developer is he should strong in Data structure , multithreading and fundamental , client expect when complex question asked from candidate he should attempt and try to solve the problem, the idea of asking complex question is they want to see are developer attempting to solve the problem which he has never solved , if trying to solve what approach taking , how  breaking a problem into small  part ,how using design principle and pattern.

some time client asking an open-ended question, the purpose of asking the open-ended question is, the developer should answer based on his past experience if developer answer in totality with confidence the probability of   clearing interview become very high

the idea of asking the ambiguous question  is the developer should be asked a question to clarify the requirement if the requirement is not clear and then try to solve the problem

Problem Solving

The idea of asking problem-solving is to evaluate developer design skills, sometimes client not expecting concrete implementation, they want to understand what approach developer taking to solve the design problem, are they giving up or the attempting to solve the problem

Fundamental

In fundamental client expecting , developer should know purpose of all the keyword , static binding , dynamic binding , overloading rule , overriding rule in terms of access modifier, exception handling, impact of dynamic linking on performance , how to improve performance by using final keyword , whats default implementation of hash code and equal , cloning, immutability, advantage of immutability , importance of final in security , Exception handling rules

Data Structure

In Data structure the expectation is developer should know all basic data structure and how those basic data structures internally working , base on use case developer should answer question which data structure is the best fit for given use case , how hashing concept is working in hash set and map , how to improve map /set performance by optimizing hash code , whats are time complexity of different operation on data structure , how resizing is happening in data structure , how to use comparable comparator , how to implement different sorting algorithm .   How to optimize data structure by changing the capacity and load factor could able to implement one data structure by using another, could able to answer how to implement the data structure

Concurrent API

developer should know how concurrent hash map internally managing a lock how segmentation is working ,how many thread can work on concurrent hash map , benefit of using concurrent hash map over hash table and synchronize map , what kind of business use case can be implemented by using concurrent hash map , how blocking queue is working what kind of problem can be solved by using blocking queue, when we should use linked blocking queue and when array blocking queue whats implementation of blocking queue, how to use blocking queue in inter-thread communication, whats fail-safe iterator

how to implement thread pool, whats advantage of the thread pool, how many types of thread pool do we have, how we can use executor service, how to use executor service to implement parallel /pipeline processing. , what kind of business problem can be solved by a cyclic barrier and count down the latch and how it's working, how to use semaphore, whats CAS concept (Compare and set), how atomic API is working internally

Multithreading

the expectation here is developer should know basic of multithreading, should know how to wait, notify, sleep, join is working, how locking is working , whats class label lock , whats object lock, how to implement inter-thread communication by using wait and notify , how volatile is working , how happen before concept is working in terms of volatile , how to implement thread pool in java 4 , how important is immutability in multithreading , whats code can create deadlock, what code can create starvation,

Serialization

Developer should know the purpose of serialization, purpose of serial version UID, if serial version UID is not defined how JVM generating it, how to customize serialization behavior, how to serialize transient variable how   to improve performance by customizing serialization behavior

Memory management

Developer should know java memory model , should know heap , how garbage collection is working , how to optimize memory , should aware where class metadata storing in memory, should know reason of Perm gen Exception, reason of Out of memory exception, should aware how to do memory profiling, how to identify which code consuming memory

Design Pattern

Developers should know at least 2 to 3 design patterns thoroughly while explaining use case implementation should use some of the design patterns, must know the best way of implementing singleton pattern, factory pattern, strategy pattern, builder pattern, flyweight pattern, decorator and adapter pattern. Should know at-least 1 example of these patterns implementations from JDK.

Design Principle

Developer should know SOLID concept very well, whenever explaining solution design principle should reflect in his solution, how important is code for interface concept

Object-oriented Concept

Developer should know Encapsulation, Polymorphic, Composition, Inheritance, when should use inheritance when should we use composition.

Database

Developer should able to write some of the queries on join and aggregation, Should aware index, type of index and how indexing is working, should aware all key

Spring

Knows basics of Spring-like dependency injection (inversion of control), auto wiring (both XML and annotations), bean life cycle, profiling, transaction management and externalization of properties.

Rest

Basic understanding of REST principles (Uniform interface,  Stateless interactions, Cacheable, Client-Server, Layered System, Code on Demand. HTTP protocol (HTTP methods, Headers, Error codes) and the concept of resources for REST.


Micro-Services

What is MicroServices? How it is different from Monolithic architecture? what are the advantages in Microservices w.r.t Monolithic architecture? Small application using Spring boot.

Java 8 features

Agenda
Lambda Expression a.k.a Anonymous Function.
A function having no
                              1. Name
                              2. Return type
                              3. Modifiers
Let's understand the above concept with the help of an example.
Take a method having name m return type int and modifier public
public  int  m(){};
Note here; is optional

Now apply the Lambda Expression to the above method.
public  int  m(){};
means remove
            1. Name i.e m
            2. Return type i.e int
            3.Access Modifiers i.e public
After removing it becomes
() {}
To make it Lambda express we have a link with arrow symbol -> like below.
()->{};
Note here; is mandatory.

Important points to Remember
  1. The method parameter type is optional, Compiler automatically knows the method parameter type which is called Type Inference. You know Functional Interface contains only one abstract method so the compiler can guess the type of parameter.
  2. If there is only one parameter then parenthesis () is also optional.
  3. If there is only one statement inside the method body then curly braces also optional. But if you are removing {} then also remove the return keyword otherwise you will get a compilation error.
  4. If there is no parameter then parenthesis is mandatory.
  5. If there are more than one parameters then also parenthesis is mandatory.
Convert below methods in lamda expression
Example1
public int add(int a,int b) {
return  a+b;
}
(int a,int b)->{return a+b};//valid
(a,b)->{return a+b};//valid
(a,b)->return a+b;//invalid
(a,b)->a+b;//valid
a,b->{return a+b;};//invalid

Example2
public void method(int a){}

(int a)->{System.out.println(a);};
(a)->{System.out.println(a);};
a->{System.out.println(a);};
a->System.out.println(a);

Example3
public void methodOne(){}

()->{System.out.println("Anu");};
()->System.out.println("Anu"); 


Now think how can you invoke the above lambda express.
The answer is using the Functional Interface.

Functional Interface.
Functional Interfaces are those which will satisfy the below rules.
1. Having only one abstract method.
2. No restriction with the default method
3. No restriction with the static method.
For example
  1. public interface InterF {
  2.     public void m();
  3.     default void m2() {
  4.     }
  5.     default int m3() {
  6.         return 0;
  7.     }
  8.     public static void m4() {
  9.     }
  10.     public static void m5() {
  11.     }
  12. }
Q. How can we invoke Lambda expression?
Ans: Using Functional Interface.

   InterF f=()->{System.out.println("hello");};
   f.m();
  1. public class Test {
  2.   public void m6() {};
  3.     public static void main(String[] args) {
  4.        InterF f=()->{System.out.println("Hello Lambda");};
  5.     f.m();
  6.     }
  7. }
Note: In Java 1.8v @FunctionalInterface annotation is introduced to specify that the interface is Functional interface and if you not abide functional interface rules then you will get compilation error.

Example
@FunctionalInterface
public interface InterF {
    public void m1();
    public void m2();
}//you will get compilation error.
    Functional Interface w.r.t Inheritance
    If an interface extends Functional Interface and child interface doesn't contain any abstract method then the child interface is also a Functional Interface.

    @FunctionalInterface
    public interface InterA {
        public void m1();
    }

    @FunctionalInterface
    public interface InterB extends InterA {
     public void m1();
    }//No compilation error.

    @FunctionalInterface
    public interface InterB extends InterA {
     public void m2();//compilation error
    }

    public interface InterB extends InterA {
     public void m2();//No compilation error because this is not a functional interface. it is a normal interface which can contain any number of abstract methods
     }

    Next Topic: Default Method

    Happy coding.
    You can download the code from Github using the below URL.
    https://github.com/mahendrakr/java8

    Saturday 5 October 2019

    Wrapper classes

    Agenda
    • Wrapper classes
    • The class hierarchy of wrapper class
    • Creating an object of the wrapper classes
    Wrapper classes
    • The wrapper classes are used to wrap primitives in an object. So, they can be added to a collection object.
    • To define utility functions that are required for the primitives.
    • All wrapper classes are immutable.
    • Wrapper classes Byte, Short, Integer and Long cache objects with values in the range of -128 to 127. The Character class caches objects with values 0 to 127.
    • Wrapper classes Float and Double don't cache objects for any range of values.
    Example:
    1. public class Test{
    2. public static void main(String[] args){
    3. Integer a =10;
    4. Integer b=10;
    5. System.out.println(a==b);//true
    6. Integer c=128;
    7. Integer  d =128;
    8. System.out.println(c==d);//false,reason value 128 is out of range of cache objects .So it will create new object.
    9. }
    10. }
    Creating object of the wrapper classes
    You can create objects of all the wrapper classes in multiple ways
    Assignment : By assigning a primitive to a wrapper class variable(Auto-boxing)
    Ex: Integer a =10;
    Constructor: By using wrapper class constructors.
    Ex: Integer a = new Integer(10);
    Static methods: By calling static method of wrapper classes, like valueOf();
    Ex: Integer wrapper = Integer.valueOf(10);

    Wrapper Classes Constructors
    Wrapper Class
    Constructors
    Byte
    Byte(byte a),Byte(String s)
    Short
    Short(short a),Short(String s)
    Integer
    Integer(int a),Integer(String s)
    Long
    Long(long a),Long(String s)
    Float
    Float(float a),Float(String s)
    Double
    Double(double a),Double(String s)
    Character
    Character(char a)
    Boolean
    Boolean(boolean a),Boolean(String s)

    Note: Wrapper class Character has no String argument constructor.
    The class hierarchy of wrapper class




    Conversion of Wrapper Classes to String and Primitive and Vice-Versa
    String to Wrapper Class:
    Integer wrapper= Integer.valueOf("10");

    String to Primitive:
     int primitive = Integer.parseInt("10");

    Wrapper to String:
    String String1= String.valueOf(wrapper);
    String String2 = wrapper.toString();

    Wrapper to primitive:
    int intValue = wrapper.intValue();

    Primitive to Wrapper:
    Integer wrapper = Integer.valueOf(10);

    Primitive to String:
    String string3 = Integer.toString(10);

    Summary of above conversion in Diagram


    Sunday 22 September 2019

    Optional

    Q.What is the alternative to null in Java?
    Java 8 introduces a new class called java.util.Optional<T> that’s inspired by the ideas of Haskell and Scala. It’s a class that encapsulates an optional value.


    Q.How do you model the absence of a value?
    Imagine you have the following nested object structure for a person owning a car and having car insurance.
    The Person / Car / Insurance data model
    If you design your classes like below
    1. class Person{
    2.     private Car car;
    3.     public Car getCar() {
    4.         return car;
    5.     }
    6. }
    1. class Car{
    2.     private Insurance insurance;
    3.     public Insurance getInsurance() {
    4.         return insurance;
    5.     }
    6. }
    1. class Insurance {
    2.     private String name;
    3.     public String getName() {
    4.         return name;
    5.     }
    6. }
    1. class Test {
    2.     public String getCarInsuranceName(Person person) {
    3.         return person.getCar().getInsurance().getName();
    4.     }
    5. public static void main(String[] args) {
    6.     Test t = new Test();
    7.     t.getCarInsuranceName(new Person());
    8. }
    Problems with null
    • It’s a source of error. NullPointerException is by far the most common exception in Java.
    • It bloats your code. It worsens readability by making it necessary to fill your code with often deeply nested null checks.
    • It’s meaningless. It doesn’t have any semantic meaning, and in particular, it represents the wrong way to model the absence of a value in a statically typed language.
    • It breaks Java philosophy. Java always hides pointers from developers except in one case: the null pointer.
    • It creates a hole in the type system. null carries no type or other information, meaning it can be assigned to any reference type. This is a problem because, when it’s propagated to another part of the system, you have no idea what that null was initially supposed to be.

    I argue that using null to represent the absence of a value is the wrong approach.
    What you need is a better way to model the absence and presence of a value.

    Redefining the Person / Car / Insurance data model using Optional
    1. class Person {
    2.     private Optional<Car> car;
    3.     public Optional<Car> getCar() {
    4.         return car;
    5.     }
    6. }
    1. class Car {
    2.     private Optional<Insurance> insurance;
    3.     public Optional<Insurance> getInsurance() {
    4.         return insurance;
    5.     }
    6. }
    1. class Insurance {
    2.     private String name;
    3.     public String getName() {
    4.         return name;
    5.     }
    6. }
    1. class OptionalVersion {
    2. public String getCarInsurance(Optional<Person1> person) {
    3.     return person.flatMap(Person1::getCar).flatMap(Car::getInsurance).map(Insurance::getName).orElse("Unknow");
    4. }
    5.     public static void main(String[] args) {
    6.         OptionalVersion t = new OptionalVersion();
    7.         Optional<Person> p = Optional.empty();
    8.         System.out.println(t.getCarInsurance(p));;
    9.     }

    10. }

    Creating Optional objects
    There are several ways to create  Optional objects.
    Empty optional:
    Optional<Car> optCar = Optional.empty();
    Optional from a non-null value:
    Optional<Car> optCar = Optional.of(car);
    If car were null, a NullPointerException would be immediately thrown (rather than getting a
    latent error once you try to access properties of the car).
    Optional from null:
    Optional<Car> optCar = Optional.ofNullable(car);
    If car were null, the resulting Optional object would be empty

    The methods of the Optional class

    Method Description
    empty Returns an empty Optional instance
    filter If the value is present and matches the given predicate, returns this Optional; otherwise
    returns the empty one
    flatMap If a value is present, returns the Optional resulting from the application of the provided
    mapping function to it; otherwise returns the empty Optional
    get Returns the value wrapped by this Optional if present, otherwise throws a NoSuchElementException
    ifPresent If a value is present, invokes the specified consumer with the value; otherwise does nothing
    isPresent Returns true if there is a value present; otherwise false
    map If a value is present, applies the provided mapping function to it
    of Returns an Optional wrapping the given value or throws a NullPointerException if this value
    is null
    ofNullable Returns an Optional wrapping the given value or the empty Optional if this value is null
    orElse Returns the value if present or the given default value otherwise
    orElseGet Returns the value if present or the one provided by the given Supplier otherwise
    orElseThrow Returns the value if present or throws the exception created by the given Supplier otherwise

    Saturday 21 September 2019

    Double colon operator


    Method and Constructor reference by using "::" operator

    • The functional interface method can be mapped to our specified method by using "::" operator. This is called method reference.
    • Our specified method can be either a static or instance method.
    • The functional interface method and our specified method should have the same argument types except for return-type, method-name, modifiers, etc are not required to match.


    Syntax
    If our specified method is a static method.
    Class-name::method-name

    If the method is an instance method
    Object-reference::method-name

    Constructor references
    We also can use ":: "operator to refer constructors
    Syntax
    Class-name::new

    Example:

    1. class Student{
    2. private String name;
    3. Student(String name){
    4. this.name=name;
    5. }
    6. }
    7. interface A{
    8. public Student getName(String name);
    9. }
    10. class Test{
    11. public static void main(String[] args){
    12. A a= s-> new Sample(s);
    13. a.getName("Anu");
    14. A a1 = Student::new;
    15. a1.getName("Kalawati");
    16. }
    17. }
    Note: In method and constructor references compulsory the argument types must be matched.

    Java 8 in built functions

    IN BUILT FUNCTIONS
    Consumer,Supplier,Function and Predicate all are available under java.util.function package.

    Comparison  of in built functions
    Properties Consumer Supplier Function Predicate
    Purpose To consume some input and perform required operation.It won’t return anything To supply some value base on requirement To take some input and perform the required operation and return the result. To some input and perform some conditional checks
    Interface Declaration interface Consumer<T>{} interface Supplier<R>{} interface Function<T,R>{} interface Predicate<T>{}
    Single abstract method public void accept(T t); public R get(); public R apply(T t); public boolean test(T t);
    Default method andThen() NA andThen(),
    compose()
    and(),or(),
    negate()
    Static method



    identify() isEqual()

    How to call in built functions? 
    1. import java.util.function.Consumer;
    2. import java.util.function.Function;
    3. import java.util.function.Predicate;
    4. import java.util.function.Supplier;
    5. public class Test {
    6.     public static void main(String[] args) {
    7.      //void accept(T t);
    8.     Consumer<String> consumer1 = (String s)->{System.out.println(s);};
    9.     Consumer<String> consumer2=(s)->{System.out.println(s);};
    10.     Consumer<String> consumer3=s->System.out.println(s);
    11.       consumer3.accept("Amit");

    12.     //  T get();
    13.       Supplier<Integer> supplier1 = ()->10;
    14.       System.out.println(supplier1.get());

    15.       //R apply(T t);
    16.       Function<String, Integer> function1 = (String s)->{return 20;};
    17.       Function<String, Integer> function2 = (s)->{return 20;};
    18.       Function<String, Integer> function3 = (s)-> 20;
    19.       Function<String, Integer> function4 = s->20;
    20.       System.out.println(function4.apply("Kalawati"));

    21. //  boolean test(T t);
    22.       Predicate<Integer> predicate1=(Integer i)->{return i%2==0;};
    23.       Predicate<Integer> predicate2=(i)->{return i%2==0;};
    24.       Predicate<Integer> predicate3=(i)->i%2==0;
    25.       Predicate<Integer> predicate4=i-> i%2==0;
    26.       System.out.println(predicate4.test(20));
    27.       System.out.println(predicate4.test(15));       
    28.     }
    29. }
    Predicate chaining
    It is possible to combine predicates into a single predicate by using the following methods.
    • and()
    • or()
    • negate()
    • These are exactly same as logical AND, OR, complement operator
    Function chaining
    It is also possible to combine functions into a single function by using the following methods
    • andThen()
    • compose()
    Consumer chaining
    It is also possible to combine consumers into a single consumer by using andThen() method.

    Example
    1. import java.util.function.Consumer;
    2. import java.util.function.Function;
    3. import java.util.function.Predicate;
    4. public class FunctionChaining {
    5.     public static void main(String[] args) {
    6.         //Predicate  chaining
    7.         Predicate<Integer> p1 = i->i%2==0;
    8.         Predicate<Integer> p2 = i->i%3==0;
    9.         System.out.println(p1.negate().test(10));//false
    10.         System.out.println(p1.or(p2).test(15));//true
    11.         System.out.println(p1.or(p2).test(7));//false
    12.         System.out.println(p1.and(p2).test(12));//true
    13.         System.out.println(p1.and(p2).test(10));//false
    14.        
    15.         //Function chaining
    16.         Function<Integer, Integer> f1= i-> i+2;
    17.         Function<Integer,Integer> f2= i->i*3;
    18.         System.out.println(f1.andThen(f2).apply(4));//18
    19.         //Note in andThen() f1 will apply first then f2
    20.         System.out.println(f1.compose(f2).apply(4));//14
    21.         //Note in compose() f2 will apply first and then f2.

    22.         //Consumer chaining
    23.         Consumer<Integer> c1 = i->System.out.print(i+2);
    24.         Consumer<Integer> c2= i->System.out.print(i*2);
    25.         c1.andThen(c2).accept(4);//68
    26.     }
    27. }

    Friday 20 September 2019

    Default method

    Default Methods
    1. In Java 1.8v onwards, you can also define the default method inside the interface.
    2. You can define the default method using the keyword default.
    3. Default methods are by default available to all implementation classes. Based on our business requirement implementation class can use these default methods directly or override.
    4. You can't override object class methods as default methods inside interface otherwise you will get a compilation error. Because you know Object class methods are by default available to each class/interface hence it is not required to override.
    5. If you try to override Object class methods in the interface, you will get compiler error.
    Note: You can't define the default method inside the concrete class and abstract class, otherwise compilation error.

    Let's understand the above concept through examples.
    Example1:
    1. public default void methodOne(){
    2. System.out.println("methodOne");
    3. }
    4. public default int methodOne(int a){
    5. return 10;
    6. }
    Example2:
    1. interface InterA{
    2. public default int add(int a, int b){
    3. return a+b;
    4. }
    5. }
    6. class Test implements InterA{
    7. public static void main(String[] args){
    8. Test t = new Test();
    9. t.add(10,20);
    10. }
    11. }
    Example3:
    1. interface InterA{
    2. public default void methodOne(){
    3. System.out.println("methodOne of InterA");
    4. }
    5. }
    6. class Test implements InterA{
    7. public void methodOne(){
    8. System.out.println("methodOne of Test");
    9. }
    10. public static void main(String[] args){
    11. Test t = new Test();
    12. t.methodOne();//methodOne of Test
    13. }
    14. }
    Example4:
    1. interface InterA{
    2. public default String toString(){
    3. return null;// compilation error, you can't override Object class methods.
    4. }
    5. }
    Default method w.r.t Inheritance
    If two interfaces contain default method with same method signature then you will get ambiguity problem(diamond problem) in implementation class.To overcome this problem compulsory you should override default method in the implementation class otherwise you will get compilation error.

    Example:
    1. interface A{
    2. default void methodOne(){
    3. System.out.println("Interface A default method");
    4. }
    5. }
    6. interface B{
    7. default void methodOne(){
    8. System.out.println("Interface A default method");
    9. }
    10. }
    11. class Test implements A,B{}//compilation error
    Q. How to override default method?
    In the implementation class, you can override the default method by removing keyword default and abide by overriding rules.

    Example:
    1. class Test implements A,B{
    2. public void methodOne(){
    3. System.out.println("Override default method");
    4. //You can also do as below
    5. A.super.methodOne();
    6. B.super.methodOne();
    7. }
    8. public static void main(String args){
    9. Test t = new Test();
    10. t.methodOne();
    11. }
    12. }

    Tuesday 17 September 2019

    Generic concept

    Agenda
    Introduction
    The generic concept is introduced in Java 1.5v
    To resolve two problems of collection.
    Type safety
    ClassCastException
    ArrayList list = new ArrayList();//Non generic a.k.a raw type version till java 1.4
    ArrayList<String> list = new ArrayList<String>();//Generic Type
    In Java 1.7 diamond operator <> is introuduce to improve code readability
    ArrayList<String> list = new ArrayList<>();//Generic Type,valid from java 1.7 onwards
    Here you can't add elements other than String type othewise you will get compilation error.
    Example:
    list.add("Anu");//valid
    list.add(10);// invalid
    Note1: Polymorphism concept is applicable only for the base type,not for parameter type.
    Note2: Parameter type must not be primitive types. It should be any class or interface
    Example
    ArrayList<int> list = new ArrayList<>();// invalid

    Generic Classes

    Until Java 1.4v ArrayList class is defined as follows.
    Example
    class ArrayList{
    public boolean add(Object o){}
    public Object get(int index){}

    }
    add() method can take Object as the argument and hence we can add any type of the object to the ArrayList. Due to this, we are not getting type of safety.
    The return type of get() method is object hence at the time of retrieval compulsory we should perform typecasting. But in Java 1.5v a generic version of ArrayList class is defined as follows.
    Generic
    Example: class ArrayList<E>{
    public boolen add(E data){}
    public E get(int index){}
    }
    Based on our requirement E will be replaced with our provided type.
    To hold only String type of objects we can create ArrayList object as follow.
    Example
    ArrayList<String> list = new ArrayList<>():
    For this requirement compiler considered ArrayList class is
    Example
    class ArrayList<String>{
    public boolen add(String data){}
    public String get(int index){}
    }
    add() method can take only String type as argument hence we can add only String type of objects to the List.Hence through generics, we are getting type safety.
    At the time of retrieval, it is not required to perform any typecasting.

    How can we create a custom generic class?
    class Student<T>{}

    Bonded Types
    We can bound the type parameter for a particular range by using the extends keyword. such types are called bounded types.
    Example
    class Test<T>{}
    Test<Integer> t1 = new Test<>();
    Test<String> t2 = new Test<>();
    As the type parameter we can pass any type there is no restriction hence it is unbounded type.
    Example
    class Test<T extends X>{}
    If X is a class then as the type parameter we can pass either X or its child classes.
    If X is an interface then as the type parameter we can pass either X or its implementation classes.
    Example
    class Test<T extends Number>{}
    class Test1{
    public static void main(String[] args){
    Test<Integer> t1 = new Test<>();
    Test<String> t1 = new Test<>();// Compilation Error
    }
    }
    Example
    class Test<T extends Runnable>{}
    class Test1{
    public static void main(String[] args){
    Test<Thread> t1 = new Test<>();// Thread class is implementation class of Runnable interface.
    Test<String> t1 = new Test<>();// Compilation Error
    }
    We can't define bounded types by using implements and super keyword.
    Example
    class Test<T implements Runnable>{}//invalid
    class Test<T super String>{}//invalid
    But implements keyword purpose we can replace with extends keyword.
    As the type parameter, we can use any valid java identifier but it is recommended to use
    T for Type
    E for Element
    K for Key
    V for Value
    Example
    class Test<X>{}//valid
    class Test<Anu>{}//valid
    We can pass any number of type parameters, there is no restriction at all.
    Example
    class Map<K,V>{}
    class Test<A,B,C,D,E....>{}
    We can also define bounded types in combination.
    Example
    class Test<T extends Number & Runnable>{}//valid
    As the type parameter, we can pass any type which extends Number class and implements Runnable interface.
    class Test<T extends Number & String>{}// invalid, we can't extend more than one class at a time.
    class Test<T extends Runnable & Comparable>{}//valid
    class Test<T extends Runnable & Number>{}//invalid, we have to take 1st class followed by interface.

    Generic methods and wild card character(?)
    public void methodOne(ArrayList<String> list){
    list.add("Anu");
    list.add(null);
    list.add(10);// invalid, only string type and null is allowed.}

    public void methodOne(ArrayList<?> list){};We can use this method for ArrayList of any type but within method we can't
    add anything except null.
    Example
    list.add(null);//valid
    list.add("Anu");// invalid
    list.add(10);//invalid
    This method is useful whenever we are performing only read operation.

    public void method(ArrayList<? extends X> list):
    • If X is a class then this method is applicable for ArrayList of either X type or its child classes.
    • If X is an interface then this method is applicable for ArrayList of either X type or its implementation classes.
    • Within the method we can add only null value.

    public void methodOne(ArrayList<? super X> list):
    • If X is a class then this method is applicable for ArrayList of either X type or its super-types.
    • If X is an interface then this method is applicable for ArrayList of either X type or its super-types.
    • But within the method, we can add X type objects and null to the List.
    • If X is a class then within the method we can add only X type or its sub-types.
    • If X is an interface then within the method we can add only implementation classes of X.
    Below example will help you to understand the above concept.
    class A{}
    class B extends A{}
    class C extends B{}
    class D extends C{}
    interface X{}
    interface Y extends X{}
    class P  implements Q, Y{}
    interface Q {}
    class R extends P{}
    1. import java.util.ArrayList;
    2. import java.util.List;
    3. class GenericAtMethod {
    4. public static  void m1(List<? extends B> list) {
    5. // We can add only null value
    6. list.add(null);
    7. }
    8. public static  void m2(List<? extends Y> list) {
    9. //we can add only null value
    10. list.add(null);
    11. }
    12. public static  void m3(List<? super B> list) {
    13. // we can add only either B type or its sub-types(C,D) or null
    14. list.add(null);
    15. list.add(new C());
    16. list.add(new D());
    17. }
    18. public static  void m4(List<? super Y> list) {
    19. //we can add only either implementation classes of Y(P,R) or null
    20. list.add(null);
    21. list.add(new P());
    22. list.add(new R());
    23. }
    24. public static void main(String[] args) {
    25. //method m1() will accept only B type or its sub-types(C,D)
    26. List<A> l1= new ArrayList<>();
    27. List<B> l2= new ArrayList<>();
    28. List<C> l3=new ArrayList<>();
    29. List<D> l10=new ArrayList<>();
    30. List<Object> l9=new ArrayList<>();
    31. //m1(l1); invalid because A is super type of B
    32. m1(l2);
    33. m1(l3);
    34. m1(l10);
    35. //method m2() will accept only Y type or its implementation classes(P,R)
    36. List<Y> l4 = new ArrayList<>();
    37. List<P> l5 = new ArrayList<>();
    38. List<R> l6 = new ArrayList<>();
    39. List<X> l7 = new ArrayList<>();
    40. List<Q> l8 = new ArrayList<>();
    41. m2(l4);
    42. m2(l5);
    43. m2(l6);
    44. // m2(l7) invalid
    45. // m2(l8); invalid
    46. //method m3() will accept only List of either B type or its super-types(A,Object)
    47. m3(l1);
    48. m3(l2);
    49. m3(l9);
    50. //m3(l3); invalid
    51. //m3(l10); invalid
    52. //method m4() will accept only List of either Y type or its super types(Y,Object)
    53. m4(l4);
    54. m4(l7 );
    55. m4(l9);
    56. }
    57. }
    Which of the following declarations are valid?
    ArrayList<String> l1 = new ArrayList<String>();//valid
    ArrayList<String> l2= new ArrayList<>();//valid
    ArrayList<?> l3 = new ArrayList<Integer>();//valid
    ArrayList<?> l4 = new ArrayList<String>();//valid
    ArrayList<? extends Number> l5 = new ArrayList<Integer>();//valid
    ArrayList<? extends Number> l6 = new ArrayList<String>();// invalid
    ArrayList<?> l7 = new ArrayList<? extends Number>();// invalid
    ArrayList<?> l8 = new ArrayList<?>();// invalid

    We can declare the type parameter either at the class level or method level.
    Declaring type parameter at class level:
    class Test<T>{
    //we can use T anywhere
    }

    Declaring type parameter at the method level
    We must declare just before return type.
    Example
    public <T> void methodOne(T t){};//valid
    public <T extends Number> void methodOne(T t){};//valid
    public <T extends Number & Runnable> void method(T t){};//valid
    public <T extends Number & Runnable & Comparable> void methodOne(T t){}//valid
    public <T extends Number & Thread> void methodOne(T t){}//invalid
    public <T extends Runnable & Thread> void methodOne(T t){}//invalid

    Conclusion
    The generic concept is applicable only at compile time.Hence the following declarations are equal
    ArrayList<String> list = new ArrayList<>();
    ArrayList<Integer> list1 = new ArrayList<I>();

    You will get compiler Error, because method methodOne have same erasure type.
    public void methodOne(ArrayList<String> l){}
    public void methodOne(ArrayList<Integer> l){}

    How compiler works w.r.t Generic code.
    • The compiler first checks type and value is added the same type or not. If not give you Compilation Error.
    • If the type and added values are of the same type, then it erasure the type and again validate the source file, if found any violation then give you Compilation Error.
    Limitation of Generic Type
    1.You cannot instantiate a generic type using a new operator. For example,
    T  t = new T(); //compiler error

    2.You cannot instantiate an array of a generic type. For example,
    T[] t = new T[3];  //compiler error

    3.You can declare instance fields of type T, but not of static fields of type T. For example,
    Class A<T>{
    T t;
    static T t1; //compiler error
    }

    4.It is not possible to have generic exception classes. For example,
    Class GenericException<T> extends Throwable{} // compiler error

    5.You cannot instantiate a generic type with primitive types. For example,
    List<int> list; // compiler error.