JAVA 8 New Features
Java 8 is the greatest release in the Java world since Java 5. It brings lots of new features to the Java as a
language, its compiler, libraries, tools and the JVM (Java virtual machine) itself.
1. New Features in Java Language
2. New Features in Java Compiler
3. New Features in Java Libraries
4. New Features in Java Tools
5. New Features in Java Runtime (JVM)
1. NEW FEATURES IN JAVA LANGUAGE
1. Lambdas and Functional Interfaces
2. Interface’s Default and Static Methods
3. Method References
4. Repeating annotations
5. Better Type Inference
6. Extended Annotations Support
7. forEach() method in Iterable interface
1.1. LAMBDAS AND FUNCTIONAL INTERFACES
‣ Lamdas allow us to treat functionality as a method argument (passing
functions around), or treat a code as data.
Arrays.asList("a", "b", "d").forEach(e -> System.out.println(e));
‣ Please notice the type of argument e is being inferred by the compiler.
In case lambda’s body is more complex, it may be wrapped into square brackets, as
the usual function definition in Java. For example:
Arrays.asList( "a", "b", "d" ).forEach( e -> {
System.out.print( e );
System.out.print( e );
});
1.1. LAMBDAS AND FUNCTIONAL INTERFACES
‣ Lambdas may return a value. The type of the return value will be inferred by
compiler. The return statement is not required if the lambda body is just a one-liner. The two code snippets
below are equivalent:
Arrays.asList(“a”, “b”, “d”).sort((e1, e2) -> e1.compareTo(e2));
and
Arrays.asList(“a”, “b”, “d”).sort(( e1, e2 ) -> {
int result = e1.compareTo( e2 );
return result;
});
1.1. LAMBDAS AND FUNCTIONAL INTERFACES
‣ An Interface that contains exactly one abstract method is known as functional
interface
‣ If you have any interface which has only a single abstract method, then that will
effectively be a functional interface
‣ The functional interface may be implicitly converted to a lambda expression
‣ The java.lang.Runnable and java.util.concurrent.Callable are two great examples
of functional interfaces.
‣ In practice, the functional interfaces are fragile: if someone adds just one
another method to the interface definition, it will not be functional anymore and compilation process will fail.
‣ We don’t need to use @FunctionalInterface annotation to mark an interface as
Functional Interface. @FunctionalInterface annotation is a facility to avoid accidental addition of abstract
methods in the functional interfaces. You can think of it like @Override.
‣ It can have any number of default, static methods but can contain only one
abstract method. It can also declare methods of object class. (hashCode, equals, toString etc.)
1.1. LAMBDAS AND FUNCTIONAL INTERFACES
‣ One of the most important uses of Functional Interfaces is that implementations
of their abstract method can be passed around as lambda expressions. Example:
@FunctionalInterface
public interface Dumper {
void dump(String str);
default void log(String str) {
System.out.println(“I1 logging::” + str);
}
static void print(String str) {
System.out.println(“Printing “ + str);
}
}
Dumper dumper = (s) -> System.out.println(s);
dumper.dump(“Hello”);
1.1. LAMBDAS AND FUNCTIONAL INTERFACES
‣ We can split the Functional Interfaces into 3 category
1. Custom or User defined Functional Interfaces:
These are interfaces defined by the user and have a single abstract method.
These may/may not be annotated by @FunctionalInterface
2. Pre-existing functional interfaces in Java prior to Java 8:
These are interfaces which already exist in Java Language Specification and have a
single abstract method. Eg. java.lang.Runnable, java.lang.Callable<V>
3. Newly defined functional interfaces in Java 8 in java.util.function package:
These are pre-defined Functional Interfaces introduced in Java 8. They are defined
with generic types and are re-usable for specific use cases. One such Functional Interface is the Predicate<T>
interface.
1.2. INTERFACE’S DEFAULT AND STATIC METHODS
‣ Java 8 extends interface declarations with two new concepts: default
and static methods.
‣ The difference between default methods and abstract methods is that
abstract methods are required to be implemented. But default
methods are not.
‣ Instead, each interface must provide so called default implementation
and all the implementers will inherit it by default (with a possibility to
override this default implementation if needed).
1.2. INTERFACE’S DEFAULT AND STATIC METHODS
‣ There is a possibility that a class is implementing two interfaces with same
default methods.
public interface Vehicle {
default void print() {
System.out.println(“I am a vehicle!”);
}
}
public interface FourWheeler {
default void print() {
System.out.println(“I am a four wheeler!”);
}
}
‣ First solution is to create an own method that overrides the default implementation.
public Class Car implements Vehicle, FourWheeler {
@Override
public void print() {
System.out.println(“I am a four wheeler car vehicle!”);
}
}
‣ Second solution is to call the default method of the specified interface using super.
public class Car implements Vehicle, FourWheeler {
public void print() {
Vehicle.super.print();
}
}
‣ Another interesting feature delivered by Java 8 is that interfaces can declare (and provide implementation)
of static methods.
1.3. METHOD REFERENCES
‣ Method references help to point to methods by their names. A
method reference is described using “::” symbol. A method reference can be used to point the following types of
methods:
1. Static methods
2. Instance methods
3. Constructors using new operator (Class::new)
1.4. REPEATING ANNOTATIONS
‣ Since Java 5 introduced the annotations support, this feature became very popular and is very widely used.
However, one of the limitations of annotation usage was the fact that the same annotation cannot be declared
more than once at the same location. Java 8 breaks this rule and introduced the repeating annotations. It allows
the same annotation to be repeated several times in place it is declared.
‣ The repeating annotations should be themselves annotated with @Repeatable annotation.
‣ The Reflection API provides new method getAnnotationsByType() to return repeating annotations of some type
(please notice that Filterable.class.getAnnotation(Filters.class) will return the instance of Filters injected
by the compiler).
1.5. BETTER TYPE INFERENCE
‣ Java 8 compiler has improved a lot on type inference. In many cases the explicit type parameters could be
inferred by compiler keeping the code cleaner.
1.6. EXTENDED ANNOTATIONS SUPPORT
‣ Java 8 extends the context where annotation might be used. Now, it is possible to annotate mostly everything:
local variables, generic types, super-classes and implementing interfaces, even the method’s exceptions
declaration.
1.7. FOREACH() METHOD IN ITERABLE INTERFACE
‣ Java 8 has introduced forEach method in java.lang.Iterable interface so that while writing code we focus on
business logic only
‣ forEach method takes java.util.function.Consumer object as argument, so
it helps in having our business logic at a separate location that we can reuse
‣ Let’s see forEach usage with simple example:
class MyConsumer implements Consumer {
public void accept(Integer p) {
System.out.println(“Consumer impl Value::” + p);
}
}
List myList = new ArrayList();
for (int i = 0; i < 10; i++)
myList.add(i);
// traversing using Iterator
Iterator it = myList.iterator();
while (it.hasNext()) {
Integer i = it.next();
System.out.println(“Iterator Value::” + i);
}
// traversing through forEach method of Iterable with anonymous class
myList.forEach(new Consumer() {
public void accept(Integer i) {
System.out.println(“forEach anonymous class Value::”+i);
}
});
// traversing with Consumer interface implementation
MyConsumer action = new MyConsumer();
myList.forEach(action);
2. NEW FEATURES IN JAVA COMPILER
1. Parameter names
2.1. PARAMETER NAMES
‣ Java developers are inventing different ways to preserve method parameter names in java byte-code and make
them available at runtime (for example, Paranamer library)
‣ Now, Java 8 supports parameter names to be accessible though reflection
‣ Needs to compile with javac -parameters, and the -parameters flag is off by default
2.1. PARAMETER NAMES
/ Requires javac -parameters
public class Main {
public static void foo(String bar, int baz) { }
public static void main(String… args) throws Throwable {
Method method = ArrayList.class.getMethod(“add”, int.class, Object.class);
Arrays.stream(method.getParameters()).forEach(System.out::println);
method = Main.class.getMethod(“foo”, String.class, int.class);
Arrays.stream(method.getParameters()).forEach(System.out::println);
}
}
Output:
int arg0
E arg1
java.lang.String bar
int baz
3. NEW FEATURES IN JAVA LIBRARIES
1. Optional
2. Streams
3. Date-Time API
4. Nashorn JavaScript engine
5. Base64
6. Parallel Arrays
7. Concurrency API improvements
8. Collection API improvements
9. IO API improvements
10. Miscellaneous Core API improvements
3.1. OPTIONAL
‣ Long time ago the great Google Guava project introduced the Optionals as a solution to
NullPointerExceptions
‣ Inspired by Google Guava, the Optional is now a part of Java 8 library
‣ Optional is just a container: it can hold a value of some type T or just be null. It provides a lot of useful
methods so the explicit null checks have no excuse anymore
Optional fullName = Optional.ofNullable(null);
// Optional fullName = Optional.of( “Tom”);
System.out.println(“Full Name is set? ” + fullName.isPresent());
System.out.println(“Full Name: ” + fullName.orElseGet( () -> “[none]”));
System.out.println(fullName.map( s -> “Hey ” + s + “!” ).orElse( “Hey Stranger!”));
‣ The isPresent() method returns true if this instance of Optional has non-null value and false otherwise.
‣ The orElseGet() method provides the fallback mechanism in case Optional has null value by accepting the
function to generate the default one.
‣ The map() method transforms the current Optional’s value and returns the new Optional instance.
‣ The orElse() method is similar to orElseGet() but instead of function it accepts the default value
3.1. OPTIONAL
‣ Before java8:
User user = getUser();
if (user != null) {
Address address = user.getAddress();
If (address != null) {
String street = address.getStreet();
if (street != null) {
return street;
}
}
}
return “not specified”;
‣ After java8:
Optional user = Optional.ofNullable(getUser());
String result = user
.map(User::getAddress)
.map(Address::getStreet)
.orElse(“not specified”);
3.1. OPTIONAL
‣ Imagine that our getters return Optional<T>. So, we should use the flatMap() method instead of the
map():
Optional optionalUser
Optional.ofNullable(getOptionalUser());
String result = optionalUser
.flatMap(OptionalUser::getAddress)
.flatMap(OptionalAddress::getStreet)
.orElse(“not specified”);
3.1. OPTIONAL
‣ Before java8:
String value = null;
String result = “”;
try {
result = value.toUpperCase();
} catch (NullPointerException exception) {
throw new CustomException();
}
‣ After java8:
String value = null;
Optional valueOpt = Optional.ofNullable(value);
String result = valueOpt.orElseThrow(CustomException::new).toUpperCase();
3.2. STREAMS
‣ Stream is a new abstract layer introduced in Java 8.
‣ Using stream, you can process data in a declarative way similar to SQL statements
‣ Stream API performs filter/map/reduce like operations with the collection.
‣ Stream API will allow sequential as well as parallel execution. Collection interface has been extended with
stream() and parallelStream() default methods to get the Stream for sequential and parallel execution
‣ Java Stream doesn’t store data, it operates on the source data structure
(collection and array) and produce pipelined data that we can use and perform specific operations
‣ All the Java Stream API interfaces and classes are in the java.util.stream package
WHAT IS NEW IN JAVA 8 – NEW FEATURES IN JAVA LIBRARIES
3.2. STREAMS
‣ Java Streams are consumable, so there is no way to create a
reference to stream for future usage. Since the data is on-demand,
it’s not possible to reuse the same stream multiple times.
‣ Streams can be created from different element sources e.g. collection
or array with the help of stream() and of() methods:
String[] arr = new String[] {“a”, “b”, “c”};
Stream stream = Arrays.stream(arr);
stream = Stream.of(“a”, “b”, “c”);
List list = new ArrayList<>();
Stream streamFromList = list.stream();
3.2. STREAMS
‣ Stream API also simplifies multithreading by providing the parallelStream() method that runs operations over
stream’s elements in parallel mode.
‣ The code below allows to run method doWork() in parallel for every element of the stream
list.parallelStream().forEach(element -> doWork(element));
‣ Let’s see an example of parallel stream:
3.2. STREAMS
List myList = new ArrayList<>();
for (int i = 0; i < 100; i++) myList.add(i);
System.out.println(“High Numbers Parallel:”);
myList.parallelStream().filter(p -> p > 90).forEach(p -> System.out.print(p + “, “));
System.out.println();
System.out.println(“High Numbers Sequential:”);
myList.stream().filter(p -> p > 90).forEach(p -> System.out.print(p + “, “));
Output:
High Numbers Parallel:
91, 92, 96, 98, 93, 99, 97, 94, 95,
High Numbers Sequential:
91, 92, 93, 94, 95, 96, 97, 98, 99,
Notice that parallel processing values are not in order. Parallel processing will be very helpful while working
with huge
collections
3.2. STREAMS
‣ There are many useful operations that can be performed on a stream
‣ They are divided into intermediate operations (return Stream<T>) and terminal operations (return a
result of definite type). Intermediate operations allow chaining.
‣ It’s also worth noting that operations on streams don’t change the source. Here’s a quick example:
long count = list.stream().distinct().count();
3.2. STREAMS
‣ We can use Stream.generate() and Stream.iterate() methods to create Stream.
Stream s = Stream.generate(() -> {return “abc”;});
Stream s = Stream.iterate(“abc”, (i) -> i);
‣ Note that it doesn’t support auto boxing, so we can’t pass primitive type array.
Stream stream1 = Stream.of(new int[] {1,2,3,4});
// Compile time error
// Type mismatch: cannot convert from Stream to Stream
Stream stream = Stream.of(new Integer[] {1,2,3,4}); // Works fine
Stream stream = Stream.of(1,2,3,4); // Works fine
‣ Using Arrays.stream() and String.chars() methods.
LongStream is = Arrays.stream(new long[]{1,2,3,4});
IntStream is2 = “abc”.chars();
3.2. STREAMS
‣ We can use java Stream collect() method to get List, Map or Set from stream.
Stream.of(1,2,3,4).collect(Collectors.toList()).forEach(System.out::println);
Stream.of(1, 2, 3, 4).collect(Collectors.toMap(i -> i, j -> j + 10)).forEach((k, v) -> System.out.println(k + “=” + v));
‣We can use stream toArray() method to create an array from the stream.
Stream intStream = Stream.of(1,2,3,4);
Integer[] intArray = intStream.toArray(Integer[]::new);
System.out.println(Arrays.toString(intArray)); //prints [1, 2, 3, 4]
3.2. STREAMS
‣ We can use filter() method to test stream elements for a condition and generate filtered list.
Stream intStream = myList.stream().filter(i -> i > 90) // filter numbers greater than 90‣
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 names = Stream.of(“aBc”, “d”, “ef”);
System.out.println(names.map(s -> {return s.toUpperCase();}).collect(Collectors.toList())); // prints [ABC, D, EF]
‣ We can use sorted() to sort the stream elements by passing Comparator argument.
Stream names = Stream.of(“aBc”, “d”, “ef”, “123456”);
System.out.println(names.sorted().collect(Collectors.toList())); // [123456, aBc, d, ef]
names = Stream.of(“aBc”, “d”, “ef”, “123456″);
// We should create new stream. Previous one is closed. !!!
System.out.println(names.sorted(Comparator.reverseOrder()).collect(Collectors.toList())); // [ef, d, aBc, 123456]
‣ We can use flatMap() to create a stream from the stream of list.
Stream.of(Arrays.asList(“Pankaj”), Arrays.asList(“David”, “Lisa”), Arrays.asList(“Amit”))
.flatMap(l -> l.stream()).forEach(System.out::println); // prints Pankaj David Lisa Ami
3.2. STREAMS
‣ Stream reduce() example
Stream numbers = Stream.of(1,2,3,4,5);
Optional intOptional = numbers.reduce((i,j) -> {return i * j;});
System.out.println(“Multiplication = ” + intOptional.orElse(-1)); // 120
‣ Stream count() example
Stream numbers1 = Stream.of(1,2,3,4,5);
System.out.println(“Number of elements in stream = ” + numbers1.count()); // 5
‣ Stream forEach() example
Stream numbers2 = Stream.of(1,2,3,4,5);
numbers2.forEach(i -> System.out.print(i+”,”)); // 1,2,3,4,5,
‣ Stream match() examples
list.stream().anyMatch(element -> element.contains(“h”)); // true
list.stream().allMatch(element -> element.contains(“h”)); // false
list.stream().noneMatch(element -> element.contains(“h”)); // false
‣ Stream findFirst() example
Stream names4 = Stream.of(“Pankaj”,”Amit”,”David”, “Lisa”);
Optional firstNameWithD = names4.filter(i -> i.startsWith(“D”)).findFirst(); if(firstNameWithD.isPresent()){
System.out.println(“First Name starting with D=”+firstNameWithD.get()); //David
}
3.3. DATE/TIME API
‣ Prior to Java 8, Java Date and Time has below drawbacks
A. The existing classes java.util.Date and SimpleDateFormatter are not thread-safe.
B. Poor API design. For example, years in java.util.Date start at 1900, months start at 1, and days start at
0—not very intuitive
C. Date Time classes are not defined consistently, we have Date Class in both java.util as well as java.sql
packages
D. There are no clearly defined classes for time, timestamp, formatting and parsing
E. Date class doesn’t provide internationalization, there is no timezone support. So java.util.Calendar and
java.util.TimeZone classes were introduced, but they also have all the problems listed above.
‣ Java SE 8 will ship with a new date and time API in java.time that offers greatly improved safety and
functionality for developers
‣ Following are some of the important classes introduced in java.time package
‣ Local: Simplified date-time API with no complexity of timezone handling.
‣ Zoned: Specialized date-time API to deal with various timezones.
‣ java.time package is the base package of new Java Date Time API. All the major base classes are part of this
package, such as LocalDate, LocalTime,
LocalDateTime,Instant,Period,Duration etc.
‣All of these classes are immutable and thread safe. Most of the times, these classes will be sufficient for
handling common requirements.
3.3. DATE/TIME API
‣ Over the years, the lack of a good quality Date and Time library in core JDK led to the popularity of non-JDK
date-time libraries such as Joda-Time
‣ Java designers/architects, acknowledging the gradual loss of interest
in core JDK Date-Time classes, and the popularity of non-JDK Date-Time libraries, went back to the drawing
board to design Date and Time API from scratch for Java 8. The Date-Time team also included the architect of
Joda-Time (Stephen Colebourne) . The result was the new java.time package being introduced in Java 8 which has
completely re-built the Date-Time classes from the ground-up, and one which is heavily influenced by the
Joda-Time API
3.3. DATE/TIME API
‣ java.time.chrono package defines generic APIs for non ISO calendar systems such as Japanese or Thai
calendars. We can extend AbstractChronology class to create our own calendar system.
‣ java.time.format package contains classes used for formatting and parsing date time objects. Most of the
times, we would not be directly using them because principle classes in java.time package provide formatting and
parsing methods
‣ java.time.temporal package contains temporal objects and we can use it for find out specific date or time
related to date/time object. For example, we can use these to find out the first or last day of the month. You
can identify these methods easily because they always have format “withXXX”.
‣ java.time.zone package contains classes for supporting different time zones and their rules.
3.3. DATE/TIME API
‣ Important Date-Time classes in Java 8
A. LocalDate : Primary class for holding a date, consisting of year-month-date, without a time zone.
B. LocalTime: Primary class for holding time, consisting of hour:min.seconds.nanoseconds, without a time
zone.
C. LocalDateTime: Holds a date-time value, consisting of year-month-dateThour:min.seconds.nanoseconds, without
a time zone. Can be created using a LocalDate and LocalTime instance taken together.
D. Instant: An instant on the time scale. Consists of an offset in seconds elapsed from Java epoch
(1970-01-01T00:00:00Z), with a nanosecond value storing precision inside the second. Ideal for machine timestamp
capture purposes.
E. ZoneId: Uniquely identifies a time zone.
F. ZonedDateTime: Holds date-time instances with time zone. Can be created by combining LocalDate, LocalTime
and ZoneId instances. Applies ZoneRules to time zone calculations.
G. ZoneOffset: Holds the time zone offset value in +-hours:minutes difference from UTC+00:00 time.
H. ZoneRules: Encapsulates the rules for converting a given Date-Time to a specific ZoneId. (java.time.zone
package class)
3.3. DATE/TIME API
‣ Important Date-Time classes in Java 8
I. ZoneRulesProvider: Responsible for configuring of time zone rules at Java platform-level or environment
level.(java.time.zone package class) J.OffsetDateTime: Contains date-time to nanosecond precision with time zone
offset from UTC+00:00. Doesn’t apply ZoneRules to time zone calculations.
K. OffsetTime: Contains time upto nano second precision with offset from UTC+00:00
L. Period: Holds measure of time between 2 dates in days,months and years.
M. Duration: Holds measure of time in terms of seconds and nanoseconds inside the second. Quantity of time can
be fetched in hours, minutes, days(24 hours),(seconds with nanoseconds inside the second).
N. TemporalAdjuster: Encapsulates the strategy for modifying or adjusting Temporal objects.(Belongs to
java.time.temporal package.)
O. Chronology: Interface Chronology holds together a Calendar system in its implementation. In-built Calendar
systems include ThaiBuddhist, Japanese, Hijrah and ISO.(Belongs to java.time.chrono package.)
P. DateTimeFormatter: Provides ability to print and parse Date and Time classes.(Belongs to java.time.format
package.)
Q. DateTimeFormatterBuilder: Provides ability to build DateTimeFormatter as per your specific needs.(Belongs to
java.time.format package.)
3.4. NASHORN JAVASCRIPT ENGINE
‣ Java 8 comes with new Nashorn JavaScript engine which allows developing and running certain kinds of
JavaScript applications on JVM
‣ Executing JavaScript file in Java Code
ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName(“Nashorn”);
scriptEngine.eval(new FileReader(“js/hello.js”));
‣ Executing JavaScript code in Java Code
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName( “JavaScript” );
System.out.println( engine.getClass().getName() );
System.out.println( “Result:” + engine.eval( “function f() { return 1; }; f() + 1;” ) );
Output:
jdk.nashorn.api.scripting.NashornScriptEngine
2
3.5. BASE64
‣ Finally, the support of Base64 encoding has made its way into Java standard library with Java 8 release.
‣ This class provides three different encoders and decoders to encrypt information at each level. You can use
these methods at the following levels
A. Basic Encoding and Decoding : It uses the Base64 alphabet specified by Java in RFC 4648 and RFC 2045 for
encoding and decoding operations. The encoder does not add any line separator character. The decoder rejects
data that contains characters outside the base64 alphabet.
B. URL and Filename Encoding and Decoding: It uses the Base64 alphabet specified by Java in RFC 4648 for
encoding and decoding operations. The encoder does not add any line separator character. The decoder rejects
data that contains characters outside the base64 alphabet
C. MIME Encoding and Decoding: It uses the Base64 alphabet as specified in RFC 2045 for encoding and decoding
operations. The encoded output must be represented in lines of no more than 76 characters each and uses a
carriage return ‘\r’ followed immediately by a linefeed ‘\n’ as the line separator. No line separator is added
to the end of the encoded output. All line separators or other characters not found in the base64 alphabet table
are ignored in decoding operation.
3.6. PARALLEL ARRAYS
‣ Java 8 release adds a lot of new methods to allow parallel arrays processing
‣ The most important one is parallelSort() which may significantly speedup the sorting on multicore machines.
‣ New methods has added to java.util.Arrays package that use the JSR 166 Fork/Join parallelism common pool to
provide sorting of arrays in parallel
‣ The methods are called parallelSort() and are overloaded for all the primitive data types and Comparable
objects.
‣ First Example:
int[] arr = {5,8,1,0,6,9};
Arrays.stream(arr).forEach(System.out::println);
Arrays.parallelSort(arr);
// Arrays.parallelSort(arr, 0, 4); // also we can sort spesific range of an array
Arrays.stream(arr).forEach(System.out::println);
WHAT IS NEW IN JAVA 8 – NEW FEATURES IN JAVA LIBRARIES
3.7. CONCURRENCY API IMPROVEMENTS
‣ The java.util.concurrent package added two new interfaces and four new classes.
‣ New methods have been added to the java.util.concurrent.ConcurrentHashMap class to support aggregate
operations based on the newly added streams facility and lambda expressions. compute(), forEach(),
forEachEntry(), forEachKey(), forEachValue(), merge(), reduce() and search()
‣ Also, new methods have been added to the java.util.concurrent.ForkJoinPool class to support a common pool
‣ The new java.util.concurrent.locks.StampedLock class has been added to provide a capability-based lock with
three modes for controlling read/write access (it might be considered as better alternative for infamous
java.util.concurrent.locks.ReadWriteLock).
‣ Addition of classes to the java.util.concurrent.atomic package to support scalable updatable variables
‣ DoubleAccumulator
‣ DoubleAdder
‣ LongAccumulator
‣ LongAdder
3.8. COLLECTION API IMPROVEMENTS
‣ We have already seen forEach() method and Stream API for collections. Some new methods added in Collection
API are:
– Iterator default method forEachRemaining(Consumer action) to perform the given action for each remaining
element until all elements have been
processed or the action throws an exception
– Collection default method removeIf(Predicate filter) to remove all of the
elements of this collection that satisfy the given predicate.
– Collection spliterator() method returning Spliterator instance that can be used to traverse and partitioning
elements sequentially or parallel.
– Map replaceAll(), compute(), merge() methods
– Performance Improvement for HashMap class with key collisions
3.9. IO API IMPROVEMENTS
‣ Files.list(Path dir) that returns a lazily populated Stream, the elements of which are the entries in the
directory.
‣ Files.lines(Path path) that reads all lines from a file as a Stream.
‣ Files.find() that returns a Stream that is lazily populated with Path by searching for files in a file tree
rooted at a given starting file
‣ BufferedReader.lines() that return a Stream, the elements of which are lines read from this BufferedReader.
3.10. MISCELLANEOUS CORE API IMPROVEMENTS
‣ ThreadLocal static method withInitial(Supplier supplier) to create instance easily.
‣ Comparator interface has been extended with a lot of default and static
methods for natural ordering, reverse order etc.
‣ min(), max() and sum() methods in Integer, Long and Double wrapper classes.
‣ logicalAnd(), logicalOr() and logicalXor() methods in Boolean class.
‣ ZipFile.stream() method to get an ordered Stream over the ZIP file entries.
Entries appear in the Stream in the order they appear in the central directory of the ZIP file.
‣ Several utility methods in Math class.
‣ JDBC-ODBC Bridge has been removed.
4. NEW FEATURES IN JAVA TOOLS
1. Nashorn Engine (jjs)
2. Class dependency analyzer (jdeps)
4.1. NASHORN ENGINE
‣ jjs is a command line based standalone Nashorn engine
‣ It accepts a list of JavaScript source code files as arguments and runs them
‣ To execute this fie from command, let us pass it as an argument to jjs:
$ jjs filename.js
4.2. CLASS DEPENDENCY ANALYZER
‣ jdeps shows the package-level or class-level dependencies of Java class files.
‣ It accepts .class file, a directory, or JAR file as an input
‣ By default, jdeps outputs the dependencies to the system output (console).
‣ Example:
$ jdeps org.springframework.core-3.0.5.RELEASE.jar
org.springframework.core (org.springframework.core-3.0.5.RELEASE.jar)
-> java.io
-> java.lang
-> java.lang.annotation
-> java.lang.ref
-> java.lang.reflect
-> java.util
-> java.util.concurrent
-> org.apache.commons.logging. not found
-> org.springframework.asm not found
-> org.springframework.asm.commons not found
org.springframework.core.annotation (org.springframework.core-3.0.5.RELEASE.jar)
-> java.lang
-> java.lang.annotation
-> java.lang.reflect
-> java.uti
WHAT IS NEW IN JAVA 8
5. NEW FEATURES IN JAVA RUNTIME
‣ The PermGen space is gone and has been replaced with Metaspace.
‣ The JVM options -XX:PermSize and –XX:MaxPermSize have been replaced by -XX:MetaSpaceSize and –
XX:MaxMetaspaceSize respectively
0 Comments
Share