Java 8 – Date Api

Java 8 introduced a new date-time API to overcome some of the drawbacks of old date-time API :

What were those drawbacks ?

  1. Thread Safety – The Date and Calendar classes are not thread safe, leaving developers to deal with the headache of hard to debug concurrency issues and to write additional code to handle thread safety. On the contrary the new Date and Time APIs introduced in Java 8 are immutable and thread safe, thus taking that concurrency headache away from developers.
  2. ZonedDate and Time – Developers had to write additional logic to handle timezone logic with the old APIs, whereas with the new APIs, handling of timezone can be done with Local and ZonedDate/Time APIs.
  3. APIs Design and Ease of Understanding – The Date and Calendar APIs are poorly designed with inadequate methods to perform day-to-day operations. The new Date/Time APIs is ISO centric and follows consistent domain models for date, time, duration and periods. There are a wide variety of utility methods that support the commonest operations.

Java 8 under the package java.time introduced a new date-time API, most important classes among them are :
1. Local : Simplified date-time API with no complexity of timezone handling.
2. Zoned : Specialized date-time API to deal with various timezones.

1. LocalDate/LocatTime and LocalDateTime API : Use it when time zones are NOT required.

      
// Java code for LocalDate 
// LocalTime Function 
import java.time.*; 
import java.time.format.DateTimeFormatter; 
 
public class Date { 

public static void LocalDateTimeApi() 
{ 
 
  // the current date 
  LocalDate date = LocalDate.now(); 
  System.out.println("the current date is "+ 
                      date); 
 
 
  // the current time 
  LocalTime time = LocalTime.now(); 
  System.out.println("the current time is "+ 
                      time); 
     
 
  // will give us the current time and date 
  LocalDateTime current = LocalDateTime.now(); 
  System.out.println("current date and time : "+ 
                      current); 
 
 
  // to print in a particular format 
  DateTimeFormatter format =  
    DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");   
  
  String formatedDateTime = current.format(format);   
   
  System.out.println("in foramatted manner "+ 
                      formatedDateTime); 
 
 
  // printing months days and seconds 
  Month month = current.getMonth(); 
  int day = current.getDayOfMonth(); 
  int seconds = current.getSecond(); 
  System.out.println("Month : "+month+" day : "+ 
                      day+" seconds : "+seconds); 
 
  // printing some specified date 
  LocalDate date2 = LocalDate.of(1950,1,26); 
  System.out.println("the repulic day :"+date2); 
 
  // printing date with current time. 
  LocalDateTime specificDate =  
      current.withDayOfMonth(24).withYear(2016); 

  System.out.println("specfic date with "+ 
                     "current time : "+specificDate); 
} 

  // Driver code 
  public static void main(String[] args)  
  { 
      LocalDateTimeApi(); 
  } 
} 

Output:

the current date is 2018-04-09
the current time is 06:21:10.409
current date and time : 2018-04-09T06:21:10.410
in foramatted manner 09-04-2018 06:21:10
Month : APRIL day : 9 seconds : 10
the repulic day :1950-01-26
specfic date with current time : 2016-04-24T06:21:10.410

2. Zoned date-time API : Use it when time zones are to be considered.

      
// Java code for Zoned date-time API 
import java.time.LocalDateTime; 
import java.time.ZoneId; 
import java.time.ZonedDateTime; 
import java.time.format.DateTimeFormatter; 

public class Zone { 

// Function to get Zoned Date and Time 
public static void ZonedTimeAndDate() 
{ 
  LocalDateTime date = LocalDateTime.now(); 
  DateTimeFormatter format1 =  
    DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");  
    
  String formattedCurrentDate = date.format(format1); 
    
  System.out.println("formatted current Date and"+ 
                    " Time : "+formattedCurrentDate);  

  // to get the current zone 
  ZonedDateTime currentZone = ZonedDateTime.now();  
  System.out.println("the current zone is "+ 
                      currentZone.getZone());  

  // getting time zone of specific place 
  // we use withZoneSameInstant(): it is 
  // used to return a copy of this date-time  
  // with a different time-zone,   
  // retaining the instant. 
  ZoneId tokyo = ZoneId.of("Asia/Tokyo"); 

  ZonedDateTime tokyoZone = 
          currentZone.withZoneSameInstant(tokyo); 
                  
  System.out.println("tokyo time zone is " +  
                      tokyoZone); 

  DateTimeFormatter format =  
      DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");  
    
  String formatedDateTime = tokyoZone.format(format);  

  System.out.println("formatted tokyo time zone "+ 
                      formatedDateTime); 
    
} 
    
  // Driver code 
  public static void main(String[] args)  
  { 
        
      ZonedTimeAndDate(); 
        
  } 
} 

Output:

formatted current Date and Time : 09-04-2018 06:21:13
the current zone is Etc/UTC
tokyo time zone is 2018-04-09T15:21:13.220+09:00[Asia/Tokyo]
formatted tokyo time zone 09-04-2018 15:21:13

Summary

In this article we learnt about the Java 8 Date Time Apis and its examples.
Hope you liked the article !


Java 8 – Stream Api

Stream Apis is used to process collections of objects, a stream is a sequence of objects that supports many methods which can be pipelined to get the desired result.

Difference between Java 8 Stream and same operations perfomed in old java sequential way.

This will help you understand the need of Java 8 stream and its usefulness.

Before Java 8 streamsIn Java 8 stream way
// Sum of number of a list greater than 20
private static int sumNumbers(List<Integer> list) {
Iterator<Integer> it = list.iterator();
int sum = 0; while (it.hasNext()) {
int num = it.next();
if (num > 20) {
sum += num;
}
}
return sum;
}
// Sum of number of a list greater than 20 private static int sumUsingStream(List<Integer> list) {
return list.stream().
filter(i -> i > 20).mapToInt(i -> i).sum();
}
This is also called external iteration because client program is handling the algorithm to iterate over the list.Java Stream API to implement internal iteration, that is better because java framework is in control of the iteration
The program is sequential in nature, there is no way we can do this in parallel easily and a lot of code to be written for a simple task.Internal iteration provides several features such as sequential and parallel execution, filtering based on the given criteria, mapping etc and at the same time very less lines of code.

Converting Java Stream to Collection or Array

  1. We can use java Stream collect() method to get List, Map or Set from stream.
    Example:
    List<Integer> intList = intStream.collect(Collectors.toList());
    Map<Integer,Integer> intMap = intStream.collect(Collectors.toMap(i -> i, i -> i+10));
  2. We can use stream toArray() method to create an array from the stream.
    Example:
    Streamt<Integert> intStream = Stream.of(1,2,3,4);
    Integer[] intArray = intStream.toArray(Integer[]::new);
  3. We can use Collection stream() to create sequential stream and parallelStream() to create parallel stream.
    Example:
    //sequential stream
    Stream<Integer> sequentialStream = myList.stream();
    //parallel stream
    Stream<Integer> parallelStream = myList.parallelStream();

Java Stream Intermediate Operations

  1. Stream filter() example: We can use filter() method to test stream elements for a condition and generate filtered list.
    List<Integer> myList = new ArrayList<>();
    for(int i=0; i<100; i++)
    myList.add(i);
    Stream<Integer> sequentialStream = myList.stream();
    Stream<Integer> highNums = sequentialStream.filter(p -> p > 90); //filter numbers greater than 90
    System.out.print(“High Nums greater than 90=”);
    highNums.forEach(p -> System.out.print(p+” “)); //prints “High Nums greater than 90=91 92 93 94 95 96 97 98 99 ”
  2. Stream map() example: We can use map() to apply functions to an stream. Let’s see how we can use it to apply upper case function to a list of Strings.
    Stream<String> names = Stream.of(“adc”, “f”, “kl”);
    System.out.println(names.map(s -> { return s.toUpperCase(); }).collect(Collectors.toList())); //prints [ADC, F, KL]
  3. Stream sorted() example: We can use sorted() to sort the stream elements by passing Comparator argument.
    Stream<String> names2 = Stream.of(“aBc”, “d”, “ef”, “123456”);
    List<String> reverseSorted = names2.sorted(Comparator.reverseOrder()).collect(Collectors.toList()); System.out.println(reverseSorted); // [ef, d, aBc, 123456]
    Stream<String> names3 = Stream.of(“aBc”, “d”, “ef”, “123456”);
    List<String> naturalSorted = names3.sorted().collect(Collectors.toList()); System.out.println(naturalSorted); //[123456, aBc, d, ef]
  4. Stream flatMap() example: We can use flatMap() to create a stream from the stream of list. Let’s see a simple example to clear this doubt.
    Stream<List<String>> namesOriginalList = Stream.of( Arrays.asList(“Pankaj”), Arrays.asList(“David”, “Lisa”), Arrays.asList(“Amit”)); //flat the stream from List<String> to String stream
    Stream<String> flatStream = namesOriginalList.flatMap(strList -> strList.stream()); flatStream.forEach(System.out::println);

Java Stream Terminal Operations

  1. Stream reduce() example: We can use reduce() to perform a reduction on the elements of the stream, using an associative accumulation function, and return an Optional. Let’s see how we can use it multiply the integers in a stream. Stream<Integer> numbers = Stream.of(1,2,3,4,5); Optional<Integer> intOptional = numbers.reduce((i,j) -> {return i*j;}); if(intOptional.isPresent()) System.out.println(“Multiplication = “+intOptional.get()); //120
  2. Stream count() example: We can use this terminal operation to count the number of items in the stream. Stream<Integer> numbers1 = Stream.of(1,2,3,4,5); System.out.println(“Number of elements in stream=”+numbers1.count()); //5
  3. Stream forEach() example: This can be used for iterating over the stream. We can use this in place of iterator. Let’s see how to use it for printing all the elements of the stream. Stream<Integer> numbers2 = Stream.of(1,2,3,4,5); numbers2.forEach(i -> System.out.print(i+”,”)); //1,2,3,4,5,
  4. Stream match() examples: Let’s see some of the examples for matching methods in Stream API. Stream<Integer> numbers3 = Stream.of(1,2,3,4,5); System.out.println(“Stream contains 4? “+numbers3.anyMatch(i -> i==4)); //Stream contains 4? true Stream<Integer> numbers4 = Stream.of(1,2,3,4,5); System.out.println(“Stream contains all elements less than 10? “+ numbers4.allMatch(i -> i<10)); //Stream contains all elements less than 10? true Stream<Integer> numbers5 = Stream.of(1,2,3,4,5); System.out.println(“Stream doesn’t contain 10? “+numbers5.noneMatch(i -> i==10)); //Stream doesn’t contain 10? true
  5. Stream findFirst() example: This is a short circuiting terminal operation, let’s see how we can use it to find the first string from a stream starting with D. Stream<String> names4 = Stream.of(“Pankaj”,”Amit”,”David”, “Lisa”); Optional<String> firstNameWithD = names4.filter(i -> i.startsWith(“D”)).findFirst(); if(firstNameWithD.isPresent()){ System.out.println(“First Name starting with D=”+firstNameWithD.get()); //David }

Summary

In this article we learnt about Java 8 Stream API, converting stream to various java collections , stream apis various other methods and its examples. We suggest you try it out.
Hope you liked the article !


Java 8 Overview

Java version 8 was released on march 2014 with supports for functional programming, new nashorn javascript engine, stream apis, introducing lambdas, new date time apis and more.

Few of the features are :

  1. Lambda Expressions − a new language feature allowing treating actions as objects
  2. Method References − enable defining Lambda Expressions by referring to methods directly using their names
  3. Optional − special wrapper class used for expressing optionality
  4. Functional Interface – an interface with maximum one abstract method, implementation can be provided using a Lambda Expression
  5. Default methods − give us the ability to add full implementations in interfaces besides abstract methods
  6. Nashorn, JavaScript Engine − Java-based engine for executing and evaluating JavaScript code
  7. Stream API − a special iterator class that allows processing collections of objects in a functional manner
  8. Date API − an improved, immutable JodaTime-inspired Date API

Summary

In this article we saw an overview about the Java 8 features. In further articles we will have a detailed look into each feature.
Hope you liked the article !


Java 8 – Optional

A new class Optional in java.util package used to represent a value is present or absent, its main purpose it to keep us away from too many null checks and NullPointerExceptions

Advantages of using Java 8 Optional :

  1. No more NullPointerException at run-time.
  2. Develop clean and neat APIs.
  3. No more Boiler plate code.
  4. Null checks are not required.

Various methods in Optional object

1. Code to retrieve the wrapped value using get API

Optional<String> opt = Optional.of("programmertoday");
String name = opt.get();

2. Basic Methods from Optional

Optional.ofNullable() method : returns a Non-empty Optional if a value present in the given object. Otherwise returns empty Optional.
Optional.empty() method : useful to create an empty Optional object.

import java.util.Optional;

public class OptionalBasicExample {
    public static void main(String[] args) {
        Optional<String> gender = Optional.of("MALE");
        String answer1 = "Yes";
        String answer2 = null;
        System.out.println("Non-Empty Optional:" + gender);
        System.out.println("Non-Empty Optional: Gender value : " + gender.get());
        System.out.println("Empty Optional: " + Optional.empty());
        System.out.println("ofNullable on Non-Empty Optional: " + Optional.ofNullable(answer1));
        System.out.println("ofNullable on Empty Optional: " + Optional.ofNullable(answer2));   // java.lang.NullPointerException   System.out.println("ofNullable on Non-Empty Optional: " +    Optional.of(answer2));     
       
        } }
        Output:
        Non - Empty Optional:
        Optional[MALE]
        Non - Empty Optional:
        Gender value :MALE
        Empty Optional:Optional.empty

        ofNullable on Non - Empty Optional:
        Optional[Yes]
        ofNullable on Empty Optional:Optional.empty

        Exception in thread "main" java.lang.NullPointerExceptio
        at java.util.Objects.requireNonNull(Objects.java:203)
        at java.util.Optional.<init> (Optional.java:96)
        at java.util.Optional.of(Optional.java:108)

3. Optional – map and flatMap methods

Optional.ofNullable() method returns a Non-empty Optional if a value present in the given object. Otherwise returns empty Optional.
Optionaal.empty() method is useful to create an empty Optional object.

import java.util.Optional;

public class OptionalMapFlatMapExample {
    public static void main(String[] args) {
        Optional<String> nonEmptyGender = Optional.of("male");
        Optional<String> emptyGender = Optional.empty();
        System.out.println("Non-Empty Optional:: " + nonEmptyGender.map(String::toUpperCase));
        System.out.println("Empty Optional    :: " + emptyGender.map(String::toUpperCase));
        Optional<Optional<String>> nonEmptyOtionalGender = Optional.of(Optional.of("male"));
        System.out.println("Optional value   :: " + nonEmptyOtionalGender);
        System.out.println("Optional.map     :: " + nonEmptyOtionalGender.map(gender -> gender.map(String::toUpperCase)));
        System.out.println("Optional.flatMap :: " + nonEmptyOtionalGender.flatMap(gender -> gender.map(String::toUpperCase)));
    }
}

Output:
        Non-Empty Optional::Optional[MALE]
        Empty Optional::Optional.empty
        Optional value::Optional[Optional[male]]
        Optional.map::Optional[Optional[MALE]]
        Optional.flatMap::Optional[MALE]

4. Optional – filter method

import java.util.Optional;

public class OptionalFilterExample {
    public static void main(String[] args) {
        Optional<String> gender = Optional.of("MALE");
        Optional<String> emptyGender = Optional.empty(); //Filter on Optional   
        System.out.println(gender.filter(g -> g.equals("male"))); //Optional.empty   
        System.out.println(gender.filter(g -> g.equalsIgnoreCase("MALE"))); //Optional[MALE]   
        System.out.println(emptyGender.filter(g -> g.equalsIgnoreCase("MALE"))); //Optional.empty   
        } 
}
        
Output:
        Optional.empty
        Optional[MALE]
        Optional.empty

5. Optional – isPresent and ifPresent methods

Optional.isPresent() returns true if the given Optional object is non-empty. Otherwise it returns false.
Optional.ifPresent() performs given action if the given Optional object is non-empty. Otherwise it returns false

import java.util.Optional;

public class OptionalIfPresentExample {
    public static void main(String[] args) {
        Optional<String> gender = Optional.of("MALE");
        Optional<String> emptyGender = Optional.empty();
        if (gender.isPresent()) {
            System.out.println("Value available.");
        } else {
            System.out.println("Value not available.");
        }
        gender.ifPresent(g -> System.out.println("In gender Option, value available."));   //condition failed, no output print   
        emptyGender.ifPresent(g -> System.out.println("In emptyGender Option, value available."));
    }
}

Output:
        Value available.
        In gender Option,value available.

6. Optional – orElse and orElseGet methods

It returns the value if present in Optional Container. Otherwise returns given default value.

import java.util.Optional;

public class OptionalOrElseExample {
    public static void main(String[] args) {
        Optional<String> gender = Optional.of("MALE");
        Optional<String> emptyGender = Optional.empty();
        System.out.println(gender.orElse("<N/A>")); //MALE   
        System.out.println(emptyGender.orElse("<N/A>")); //<N/A>   
        System.out.println(gender.orElseGet(() -> "<N/A>")); //MALE   
        System.out.println(emptyGender.orElseGet(() -> "<N/A>")); //<N/A>   
    }
}

Output:
        MALE
        <N/A>
        MALE
        <N /A>

Summary

In this article we learnt about Java 8 Optional package, its advantages and its variuos methods and implementations.
Hope you liked the article !