In this article, I have pointed and discussed about five features of Java 8 by which seems more interesting for me.
- Stream and other special features
- Lambda expressions
- Parallel operations
- JavaScript engine
- New date / time APIs
- Stream and other special features
A stream represents a sequence of elements and supports different kind of operations to perform computations upon those elements:
List<String> myList = Arrays.asList("a1", "a2", "b1", "c2", "c1");
myList
.stream()
.filter(s -> s.startsWith("c"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println); // C1 C2
-Stream operations are either intermediate or terminal. Intermediate operations return a stream so we can chain multiple intermediate operations without using semicolons. Terminal operations are either void or return a non-stream result. In the above example filter, map and sorted are intermediate operations whereas forEach is a terminal operation.
Different kind of streams
Streams can be created from various data sources, especially collections. Lists and Sets support new methods stream() and parallelStream() to either create a sequential or a parallel stream.
//Prepare stream from collection
List<String> myList = Arrays.asList("a1", "a2", "b1", "c2", "c1");
myList.stream()//Create a stream from a bunch of object references
Stream.of("d2", "a2", "b1", "b3", "c")//Primitive streams (IntStream,LongStream and DoubleStream)
IntStream.range(1, 4)
Other special feature
Extended Annotations Support
It is possible to annotate mostly everything: local variables, generic types, super-classes and implementing interfaces, even the method’s exceptions declaration.
public class Annotations {
@Retention( RetentionPolicy.RUNTIME )
@Target( { ElementType.TYPE_USE, ElementType.TYPE_PARAMETER } )
public @interface NonEmpty {
}public static class Holder< @NonEmpty T > extends @NonEmpty Object {
public void method() throws @NonEmpty Exception {
}
}public static void main(String[] args) {
final Holder< String > holder = new @NonEmpty Holder< String >();
@NonEmpty Collection< @NonEmpty String > strings = new ArrayList<>();
}
}
Internal vs. External Iteration
External iteration (java7)- where a Collection should be implemented with Iterable, So that Iterator can enumerate its elements and clients use this to step sequentially through the elements of a collection.
List<String> alphabets = Arrays.asList(new String[]{"a","b","b","d"});Iterator<String> iterator = alphabets.listIterator();
while(iterator.hasNext()){
System.out.println(iterator.next().toUpperCase());
}for(String letter: alphabets){
System.out.println(letter.toUpperCase());
}
External iterators may have things to cleanup (like a Thread, Iterator variable)
Internal Iteration (java8):
alphabets.forEach(l -> l.toUpperCase());
advantage of internal iterator is the possibility to implement atomic group operation on the elements of the collection.
Method References
Method references provide the useful syntax to refer directly to exiting methods or constructors of Java classes or objects (instances).
class Car {
public static Car create( final Supplier< Car > supplier ) {
return supplier.get();
}
public void running() {
System.out.println( "Repaired " + this.toString() );
}
}
Car car = Car.create( Car::new );
List< Car > cars = Arrays.asList( car );
cars.forEach(Car::running);
Lambda expressions (,) –>{ ; }
What are all can be method parameters?
java7: instance of any class, Class type, variable, constant, primitives, objects.
java8: functional expression + java7 parameters
These functional expressions, we call it as lambda expression.
Lambda expressions allow us to express instances of single-method interfaces (other-name: functional interfaces) more compactly.
@FunctionalInterface public interface Operation{
public Object doOperation(Object param1,Object param2);
}
Implementation for the above interface can be written as below
Operation instance= (value1,value2) -> { return param1 + param2; }
Lambda could be represented as a comma-separated list of parameters –> symbol and the body.
Java 8 extends interface declarations with two new concepts: default and static methods.
Interface’s Default Methods
@FunctionalInterface public interface FunctionalDefaultMethods {
void method();
default void defaultMethod() {
System.out.println("Default implementation");
}
}
FunctionalDefaultMethods functionalDefaultMethods=()->{ System.out.println(“my implementation”); };
Interface’s Static Methods
@FunctionalInterface
public interface FunctionalStaticMethods {
void method();
static void defaultMethod() {
System.out.println("Default implementation");
}
}
FunctionalStaticMethods functionalStaticMethods=()->{ System.out.println(“my implementation”); };
Parallelism
Java 8 release adds a lot of new methods to allow parallel arrays processing. Arguably, the most important one is parallelSort() which may significantly speedup the sorting on multicore machines.
long[] arrayOfLong = new long [ 20000 ];
Arrays.parallelSetAll( arrayOfLong,
index -> ThreadLocalRandom.current().nextInt( 1000000 ) );
Arrays.stream( arrayOfLong ).limit( 10 ).forEach(
i -> System.out.print( i + " " ) );Arrays.parallelSort( arrayOfLong );
Arrays.stream( arrayOfLong ).limit( 10 ).forEach(
i -> System.out.print( i + " " ) );
* method parallelSetAll() to fill up arrays with 20000 random values. After that, the parallelSort() is being applied. The program outputs first 10 elements before and after sorting so to ensure the array is really ordered.
Parallelism in collection
List<String> myList={..}
myList.parallelStream().<operation>
myList.stream().parallel()
IntStream.range(1,20000).parallel().filter( this::isPrime).count()
…more info on parallelism (no of thread, pool size, ..so on)
ForkJoinPool commonPool = ForkJoinPool.commonPool();
Nashorn JavaScript engine
Java 8 comes with new Nashorn JavaScript engine which allows developing and running certain kinds of JavaScript applications on JVM. Nashorn JavaScript engine is just another implementation of javax. script.ScriptEngine and follows the same set of rules, permitting Java and JavaScript interoperability.
jjs is a command-line based standalone Nashorn engine. It accepts a list of JavaScript source code files as arguments and runs them.
Date/Time API
The Java 8’s New Date-Time API was heavily influenced by Joda-Time and took the best of it. The new java.time package contains all the classes for date, time, date/time, time zones, instants, duration, and clocks manipulation
LocalDate date = LocalDate.now();
LocalTime time = LocalTime.now();
LocalDateTime datetime = LocalDateTime.now();
ZonedDateTime zonedDatetime = ZonedDateTime.now(); /*ZoneId.of( "America/Los_Angeles" )*/dateObject.plusDays(10);
dateObject.minusWeeks(3);//Parsing
LocalDateTime dt = LocalDateTime.parse("27::Apr::2014 21::39::48",
DateTimeFormatter.ofPattern("d::MMM::uuuu HH::mm::ss"));
//Formating
dt.format(DateTimeFormatter.ofPattern("d::MMM::uuuu HH::mm::ss");