Java 8 Features with Examples


Java 8 was discharged in eighteenth March 2014, so the opportunity has already come and gone to investigate Java 8 Features. In this instructional exercise, we will investigate Java 8 highlights with models.

Java 8 Features

Some of the critical Java 8 highlights are;

  1. forEach() strategy in Iterable interface
  2. default and static strategies in Interfaces
  3. Functional Interfaces and Lambda Expressions
  4. Java Stream API for Bulk Data Operations on Collections
  5. Java Time API
  6. Collection API improvements
  7. Concurrency API improvements
  8. Java IO improvements
  9. Miscellaneous Core API improvements

Let's have a short look on these Java 8 highlights. I will give some code bits to better seeing, so on the off chance that you need to run projects in Java 8, you should setup Java 8 condition by following steps.

  • Download JDK8 and introduce it. Establishment is basic like other java renditions. JDK establishment is required to compose, arrange and run the program in Java.
  • Download most recent Eclipse IDE, it offers help for java 8 now. Ensure your tasks fabricate way is utilizing Java 8 library.

forEach() strategy in Iterable interface

Whenever we have to navigate through a Collection, we have to make a Iterator whose entire reason for existing is to emphasize over and after that we have business rationale in a circle for every one of the components in the Collection. We may get ConcurrentModificationException if iterator isn't utilized properly.

Java 8 has presented forEach strategy in java.lang.Iterable interface so that while composing code we center around business rationale as it were. forEach technique takes java.util.function.Consumer object as contention, so it helps in having our business rationale at a different area that we can reuse. How about we see forEach use with basic example.

 

package com.journaldev.java8.foreach; 

import java.util.ArrayList; 

import java.util.Iterator; 

import java.util.List; 

import java.util.function.Consumer; 

import java.lang.Integer; 

public class Java8ForEachExample { 

public static void main(String[] args) { 

//making test Collection 

List<Integer> myList = new ArrayList<Integer>(); 

for(int i=0; i<10; i++) myList.add(i); 

//navigating utilizing Iterator 

Iterator<Integer> it = myList.iterator(); 

while(it.hasNext()){ 

Whole number I = it.next(); 

System.out.println("Iterator Value::"+i); 

} 

//navigating through forEach strategy for Iterable with mysterious class 

myList.forEach(new Consumer<Integer>() { 

public void accept(Integer t) { 

System.out.println("forEach mysterious class Value::"+t); 

} 

}); 

//navigating with Consumer interface implementation 

MyConsumer activity = new MyConsumer(); 

myList.forEach(action); 

} 

} 

//Consumer execution that can be reused 

class MyConsumer implements Consumer<Integer>{ 

public void accept(Integer t) { 

System.out.println("Consumer impl Value::"+t); 

} 

} 

The number of lines may increment yet forEach strategy helps in having the rationale for cycle and business rationale at isolated spot bringing about higher partition of concern and cleaner code.

  • default and static strategies in Interfaces

    If you read forEach strategy subtleties cautiously, you will see that it's characterized in Iterable interface however we realize that interfaces can't have technique body. From Java 8, interfaces are upgraded to have strategy with usage. We can utilize default and static watchword to make interfaces with technique execution. forEach strategy execution in Iterable interface is:

     
    
    default void forEach(Consumer<? super T> action) { 
    
    Objects.requireNonNull(action); 
    
    for (t : this) { 
    
    action.accept(t); 
    
    } 
    
    } 
    
    

    We realize that Java doesn't give multiple legacy in Classes in light of the fact that it prompts Diamond Problem. So how it will be taken care of with interfaces now, since interfaces are currently like conceptual classes. The arrangement is that compiler will toss exemption in this situation and we should give usage rationale in the class executing the interfaces.

     
    
    bundle com.journaldev.java8.defaultmethod; 
    
    @FunctionalInterface 
    
    public interface Interface1 { 
    
    void method1(String str); 
    
    default void log(String str){ 
    
    System.out.println("I1 logging::"+str); 
    
    } 
    
    static void print(String str){ 
    
    System.out.println("Printing "+str); 
    
    } 
    
    //endeavoring to abrogate Object strategy gives gather time blunder as 
    
    //"A default technique can't abrogate a strategy from java.lang.Object" 
    
    //	default String toString(){ 
    
    //		return "i1"; 
    
    //	} 
    
    } 
    
    
    Copy
    package com.journaldev.java8.defaultmethod; @FunctionalInterface public interface Interface2 { void method2(); default void log(String str){ System.out.println("I2 logging::"+str); } }

    Notice that both the interfaces have a typical technique log() with usage logic.

     
    
    package com.journaldev.java8.defaultmethod; 
    
    public class MyClass implements Interface1, Interface2 { 
    
    @Override 
    
    public void method2() { 
    
    } 
    
    @Override 
    
    public void method1(String str) { 
    
    } 
    
    //MyClass won't assemble without having it's own log() implementation 
    
    @Override 
    
    public void log(String str){ 
    
    System.out.println("MyClass logging::"+str); 
    
    Interface1.print("abc"); 
    
    } 
    
    } 
    
    

    As you can see that Interface1 has static technique execution that is utilized in MyClass.log() strategy usage. Java 8 utilizes default and static strategies intensely in Collection API and default techniques are included so our code stays in reverse compatible.

    If any class in the pecking order has a strategy with same signature, at that point default strategies end up insignificant. Since any class actualizing an interface as of now has Object as superclass, in the event that we have parallels(), hashCode() default techniques in interface, it will end up unessential. That is the reason for better lucidity, interfaces are not permitted to have Object class default methods.

    For complete subtleties of interface changes in Java 8, if it's not too much trouble perused Java 8 interface changes.

  • Functional Interfaces and Lambda Expressions

    If you see above interfaces code, you will see @FunctionalInterface annotation. Practical interfaces are new idea presented in Java 8. An interface with precisely one conceptual strategy ends up Functional Interface. We don't have to utilize @FunctionalInterface explanation to check an interface as Functional Interface. @FunctionalInterface comment is an office to stay away from unintentional expansion of conceptual strategies in the utilitarian interfaces. You can consider it like @Override annotation and it's best practice to utilize it. java.lang.Runnable with single unique strategy run() is an incredible case of useful interface.

    One of the real advantages of utilitarian interface is the likelihood to utilize lambda expressions to instantiate them. We can instantiate an interface with anonymous class yet the code looks bulky.

     
    
    Runnable r = new Runnable(){ 
    
    @Override 
    
    public void run() { 
    
    System.out.println("My Runnable"); 
    
    }}; 
    
    

    Since practical interfaces have just a single technique, lambda articulations can without much of a stretch give the strategy usage. We simply need to give technique contentions and business rationale. For instance, we can compose above usage utilizing lambda articulation as:

     
    
    Runnable r1 = () - > { 
    
    System.out.println("My Runnable"); 
    
    }; 
    
    

    If you have single articulation in strategy execution, we don't require wavy props moreover. For instance above Interface1 mysterious class can be instantiated utilizing lambda as follows:

     
    
    Interface1 i1 = (s) - > System.out.println(s); 
    
    i1.method1("abc"); 
    
    

    So lambda articulations are intends to make mysterious classes of practical interfaces effectively. There are no runtime advantages of utilizing lambda articulations, so I will utilize it circumspectly in light of the fact that I wouldn't fret composing couple of additional lines of code.

    A new bundle java.util.function has been included with cluster of utilitarian interfaces to give target types to lambda articulations and strategy references. Lambda articulations are a gigantic theme, I will compose a different article on that in future.

    You can peruse total instructional exercise at Java 8 Lambda Expressions Tutorial.

  • Java Stream API for Bulk Data Operations on Collections

    A new java.util.stream has been included Java 8 to perform channel/map/decrease like activities with the gathering. Stream API will permit consecutive just as parallel execution. This is a standout amongst the best component for me since I work a great deal with Collections and as a rule with Big Data, we have to sift through them dependent on some conditions.

    Collection interface has been stretched out with stream() and parallelStream() default techniques to get the Stream for consecutive and parallel execution. We should see their utilization with basic example.

     
    
    package com.journaldev.java8.stream; 
    
    import java.util.ArrayList; 
    
    import java.util.List; 
    
    import java.util.stream.Stream; 
    
    public class StreamExample { 
    
    public static void main(String[] args) { 
    
    List<Integer> myList = new ArrayList<>(); 
    
    for(int i=0; i<100; i++) myList.add(i); 
    
    //consecutive stream 
    
    Stream<Integer> sequentialStream = myList.stream(); 
    
    //parallel stream 
    
    Stream<Integer> parallelStream = myList.parallelStream(); 
    
    //utilizing lambda with Stream API, channel example 
    
    Stream<Integer> highNums = parallelStream.filter(p - > p > 90); 
    
    //utilizing lambda in forEach 
    
    highNums.forEach(p - > System.out.println("High Nums parallel="+p)); 
    
    Stream<Integer> highNumsSeq = sequentialStream.filter(p - > p > 90); 
    
    highNumsSeq.forEach(p - > System.out.println("High Nums sequential="+p)); 
    
    } 
    
    }

    If you will keep running above model code, you will get yield like this:

     
    
    High Nums parallel=91 
    
    High Nums parallel=96 
    
    High Nums parallel=93 
    
    High Nums parallel=98 
    
    High Nums parallel=94 
    
    High Nums parallel=95 
    
    High Nums parallel=97 
    
    High Nums parallel=92 
    
    High Nums parallel=99 
    
    High Nums sequential=91 
    
    High Nums sequential=92 
    
    High Nums sequential=93 
    
    High Nums sequential=94 
    
    High Nums sequential=95 
    
    High Nums sequential=96 
    
    High Nums sequential=97 
    
    High Nums sequential=98 
    
    High Nums sequential=99 
    
    

    Notice that parallel handling esteems are not all together, so parallel preparing will be useful while working with tremendous collections.
    Covering everything about Stream API is beyond the realm of imagination in this post, you can peruse everything about Stream API at Java 8 Stream API Example Tutorial.

  • Java Time API

    It has dependably been difficult to work with Date, Time and Time Zones in java. There was no standard methodology or API in java for date and time in Java. One of the pleasant expansion in Java 8 is the java.time bundle that will streamline the way toward working with time in java.

    Just by seeing Java Time API bundles, I can detect that it will be anything but difficult to utilize. It has some sub-bundles java.time.format that gives classes to print and parse dates and times and java.time.zone offers help for time-zones and their rules.

    The new Time API lean towards enums over whole number constants for quite a long time and days of the week. One of the valuable class is DateTimeFormatter for changing over datetime items to strings.

    For complete instructional exercise, head over to Java Date Time API Example Tutorial.

  • Collection API improvements

    We have just observed forEach() strategy and Stream API for accumulations. Some new techniques included Collection API are:

    • Iterator default strategy forEachRemaining(Consumer action) to play out the given activity for each residual component until the sum total of what components have been handled or the activity tosses a special case.
    • Collection default technique removeIf(Predicate filter) to evacuate the majority of the components of this accumulation that fulfill the given predicate.
    • Collection spliterator() technique returning Spliterator case that can be utilized to cross components consecutively or parallel.
    • Map replaceAll(), compute(), merge() methods.
    • Performance Improvement for HashMap class with Key Collisions
  • Concurrency API improvements

    Some imperative simultaneous API upgrades are:

    • ConcurrentHashMap process(), forEach(), forEachEntry(), forEachKey(), forEachValue(), consolidate(), lessen() and seek() methods.
    • CompletableFuture that might be expressly finished (setting its esteem and status).
    • Executors newWorkStealingPool() strategy to make a work-taking string pool utilizing every single accessible processor as its objective parallelism level.
  • Java IO improvements

    Some IO upgrades known to me are:

    • Files.list(Path dir) that profits a sluggishly populated Stream, the components of which are the sections in the directory.
    • Files.lines(Path path) that peruses all lines from a document as a Stream.
    • Files.find() that profits a Stream that is sluggishly populated with Path via looking for records in a document tree established at a given beginning file.
    • BufferedReader.lines() that arrival a Stream, the components of which are lines perused from this BufferedReader.
  • Miscellaneous Core API improvements

    Some misc API enhancements that may come convenient are:

    1. ThreadLocal static technique withInitial(Supplier provider) to make case easily.
    2. Comparator interface has been reached out with a great deal of default and static techniques for normal requesting, turn around request etc.
    3. min(), max() and aggregate() techniques in Integer, Long and Double wrapper classes.
    4. logicalAnd(), logicalOr() and logicalXor() techniques in Boolean class.
    5. ZipFile.stream() technique to get an arranged Stream over the ZIP document passages. Sections show up in the Stream according to the pattern in which they show up in the focal index of the ZIP file.
    6. Several utility strategies in Math class.
    7. jjs order is added to summon Nashorn Engine.
    8. jdeps order is added to break down class files
    9. JDBC-ODBC Bridge has been removed.
    10. PermGen memory space has been removed
  • That's totally supportive of Java 8 highlights with precedent projects. On the off chance that I have missed some imperative highlights of Java 8, if you don't mind let me know through remarks.






    journaldev is optimized for learning.© journaldev .
    All Right Reserved and you agree to have read and accepted our term and condition