Java 8 Features With Examples

In March 18, 2014, Oracle introduced Java 8, marking a significant milestone in the evolution of Java as a software development platform. This release brought about groundbreaking enhancements to Java programming, JVM, tools, and libraries.

Java 8 Programming Language Enhancements

Java 8 provides following features for Java Programming:

  • Lambda expressions,
  • Method references,
  • Functional interfaces,
  • Stream API,
  • Default methods,
  • Base64 Encode Decode,
  • Static methods in interface,
  • Optional class,
  • Collectors class,
  • ForEach method,
  • Nashorn JavaScript Engine,
  • Parallel Array Sorting,
  • Type and Repating Annotations,
  • IO Enhancements,
  • Concurrency Enhancements,
  • JDBC Enhancements etc.
  • Lambda Expressions

The lambda expression is a useful feature that allows us to adopt a functional programming approach in our code. It offers a succinct and explicit method to implement Single Abstract Method (SAM) interfaces through expressions. This functionality proves particularly beneficial within collection libraries, enabling streamlined iteration, filtering, and data extraction processes.

For more information and examples: click here

Syntax

The basic syntax of a lambda expression is:

Example

(argument-list) -> {body}
  • argument-list: It can be empty or non-empty as well. It represents the parameters used by the expression.
  • arrow-token (->): It links the arguments to the body of the expression.
  • body: It contains expressions and statements for the lambda expression.

Filename: LambdaExample.java

Example

import java.util.Arrays;

import java.util.List;

import java.util.function.Predicate;

public class LambdaExample {

    public static void main(String[] args) {

        List<String> languages = Arrays.asList("Java", "Python", "JavaScript", "C++");

        System.out.println("Languages which starts with 'J':");

        filter(languages, (str) -> str.startsWith("J"));

    }

    public static void filter(List<String> names, Predicate<String> condition) {

        for(String name: names)  {

            if(condition.test(name)) {

                System.out.println(name + " ");

            }

        }

    }

}

Output:

Output

Languages which starts with 'J':

Java 

JavaScript

Method References

The Java 8 Method reference allows us to point to a method of a functional interface. It provides a concise and simple alternative to lambda expressions. Whenever we find ourselves using a lambda expression solely to reference a method, we have the option to substitute it with a method reference.

For more information and examples: click here

Types of Method References

There are four primary categories of method references in Java:

  1. Static Method References: These refer to methods that are static within classes.

Syntax:

Example

ClassName::staticMethodName
  1. Method References for a Specific Object: These references point to methods of a particular instance within a class.

Syntax:

Example

instance::instanceMethodName

Consider a scenario where an object

  1. is a String instance. When we use
  2. ::length, we are actually referring to the length method of the
  3. object.

Instance Method References for a Specific Type of Object: These references are used to point to methods of a particular instance that is provided during the method invocation.

Syntax:

Example

ClassName::methodName

Example: String::toLowerCase points to the toLowerCase method of a String instance that will be identified during runtime.

  1. Constructor References: These refer to the constructors of classes.

Syntax:

Example

ClassName::new

The syntax ArrayList::new refers to the constructor of the ArrayList class.

Filename: MethodReferenceExample.java

Example

import java.util.ArrayList;

import java.util.Arrays;

import java.util.List;

import java.util.function.Function;

import java.util.function.Supplier;

import java.util.stream.Collectors;

public class MethodReferenceExample {

    public static void main(String[] args) {

        List<String> words = Arrays.asList("Java", "Stream", "Method", "References");

        // Static Method Reference: Converting all strings to uppercase

        List<String> upperCaseWords = words.stream()

                                           .map(String::toUpperCase) // static method reference

                                           .collect(Collectors.toList());

        System.out.println("Uppercase Words: " + upperCaseWords);

        // Instance Method Reference of an Arbitrary Object of a Particular Type

        System.out.println("Printing each word:");

        words.forEach(System.out::println); // instance method reference

        // Constructor Reference: Creating new instances

        Supplier<List<String>> listSupplier = ArrayList::new; // constructor reference

        List<String> newList = listSupplier.get();

        newList.addAll(words);

        System.out.println("New List: " + newList);

        // Additional Example: Using Function Interface for Constructor Reference

        Function<String, Integer> stringToInteger = Integer::new; // constructor reference

        Integer number = stringToInteger.apply("100");

        System.out.println("String to Integer: " + number);

    }

}

Output:

Output

Uppercase Words: [JAVA, STREAM, METHOD, REFERENCES]

Printing each word:Java

Stream

Method

References

New List: [Java, Stream, Method, References]

String to Integer: 100

Functional Interface

A functional interface is defined as an interface that consists of just a single abstract method. It has the flexibility to include multiple default and static methods, as well as the ability to define methods from the object class.

Functional interfaces are commonly referred to as Single Abstract Method Interfaces (SAM Interfaces).

For more information and examples: click here

Filename: FunctionalInterfaceExample.java

Example

@FunctionalInterface

interface Converter<F, T> {

    T convert(F from);

}

public class FunctionalInterfaceExample {

    public static void main(String[] args) {

        // Using the Converter functional interface with a lambda expression

        Converter<String, Integer> stringToInteger = Integer::valueOf;

        // Applying the converter to convert a string to an integer

        int convertedValue = stringToInteger.convert("123");

        System.out.println("Converted Value: " + convertedValue);

        // Another example, converting case of a string

        Converter<String, String> upperCaseConverter = String::toUpperCase;

        String convertedString = upperCaseConverter.convert("java");

        System.out.println("Converted String: " + convertedString);

    }

}

Output:

Output

Converted Value: 123

Converted String: JAVA

Optional

In Java 8, a novel class called Optional was introduced to address issues related to NullPointerException in Java programs. To utilize this class, it is necessary to import the java.util package. Optional offers functionalities for verifying the existence of a value for a specific variable.

For more information and examples: click here

Filename: OptionalMain.java

Example

import java.util.Optional;

public class OptionalMain {

    public static void main(String[] args) {

        String[] str = new String[10]; // Initialize an array of strings with default null values.

        str[5] = "Hello, Optional!"; // Uncomment this line to test with a non-null value.

        // Create an Optional object from the value of str[5].

        Optional<String> checkNull = Optional.ofNullable(str[5]);

        // Check if the Optional object contains a value.

        if (checkNull.isPresent()) {

            // Convert the string to lowercase if it's not null.

            String word = str[5].toLowerCase();

            System.out.println(word); // Print the lowercase string.

        } else {

            System.out.println("string is null"); // Indicate that the string is null.

        }

    }

}

Output:

Output

hello, optional!

forEach

A fresh method in Java, forEach, has been introduced to traverse through elements. This method is specified within the interfaces Iterable and Stream.

The forEach method is a built-in function specified in the Iterable interface. Any collection classes that inherit from the Iterable interface have the capability to employ the forEach method to traverse through elements.

This function accepts a functional interface as its sole parameter, allowing you to provide a lambda expression as input.

For more information and examples: click here

Filename: ForEachMapExample.java

Example

import java.util.Map;

import java.util.HashMap;

public class ForEachMapExample {

    public static void main(String[] args) {

        // Create a map of Integer keys and String values

        Map<Integer, String> map = new HashMap<>();

        map.put(1, "One");

        map.put(2, "Two");

        map.put(3, "Three");

        map.put(4, "Four");

        // Use forEach to iterate over the map and print each key-value pair

        map.forEach((key, value) -> System.out.println("Key: " + key + ", Value: " + value));

    }

}

Output:

Output

Key: 1, Value: One

Key: 2, Value: Two

Key: 3, Value: Three

Key: 4, Value: Four

Date/Time API

Java 8 has brought forth a fresh Date and Time API. The assortment of Java 8 Date and Time classes can be found within the java.time package.

For more information and examples: click here

API Specification

  • java.time: Core classes for dates, times, combined date and time, instants, durations, periods, and clocks using the ISO-8601 system.
  • java.time.chrono: Supports non-ISO calendar systems with predefined and custom chronologies.
  • java.time.format: For formatting and parsing date-time objects.
  • java.time.temporal: Advanced features for date-time manipulation, aimed at library developers.
  • java.time.zone: Handles time zones, offsets, and rules.

Filename: DateTimeApiShortExample.java

Example

import java.time.LocalDate;

import java.time.format.DateTimeFormatter;

public class DateTimeApiShortExample {

    public static void main(String[] args) {

        // Current Date

        LocalDate today = LocalDate.now();

        System.out.println("Today: " + today);

        // Adding 5 days

        LocalDate futureDate = today.plusDays(5);

        System.out.println("Future Date: " + futureDate);

        // Formatting the future date

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");

        String formattedDate = futureDate.format(formatter);

        System.out.println("Formatted Future Date: " + formattedDate);

        // Parsing a date string

        String dateString = "25-12-2024";

        LocalDate parsedDate = LocalDate.parse(dateString, formatter);

        System.out.println("Parsed Date: " + parsedDate);

    }

}

Output:

Output

Today: 2024-02-13

Future Date: 2024-02-18

Formatted Future Date: 18-02-2024

Parsed Date: 2024-12-25

Static Method in Interface in Java

Static methods within interfaces function similarly to static methods within classes. They are declared using the static keyword and are accessible without needing an instance of the implementing class. These methods are inherent to the interface itself rather than the instances that adhere to the interface. Consequently, they serve as a practical location for utility methods associated with the interface.

Filename: ActionExecutor.java

Example

// Define an interface for displaying messages.

interface MessageDisplay {

    // Static method to display a static greeting message.

    static void showStaticMessage() {

        // Print a static greeting message to the console.

        System.out.println("Static Greeting: Welcome!");

    }

    // Abstract method to be implemented by classes for executing a custom action with a string input.

    void executeCustomAction(String input);

}

// Class that implements the MessageDisplay interface to execute actions.

public class ActionExecutor implements MessageDisplay {

    // Main method - the entry point of the program.

    public static void main(String[] args) {

        // Create an instance of the ActionExecutor class.

        ActionExecutor executor = new ActionExecutor();

        // Call the static method from the MessageDisplay interface to show the static message.

        MessageDisplay.showStaticMessage();

        // Call the implemented abstract method with a custom message.

        executor.executeCustomAction("Overridden Message: Action Completed.");

    }

    // Implementation of the abstract method from the MessageDisplay interface.

    @Override

    public void executeCustomAction(String inputData) {

        // Print the input data to the console.

        System.out.println(inputData);

    }

}

Output:

Output

Static Greeting: Welcome!

Overridden Message: Action Completed.

IO Enhancements

Java 8 brought in numerous improvements to the Input/Output (IO) and New Input/Output (NIO) frameworks with a key emphasis on enhancing the user-friendliness and effectiveness of file and stream management. These advancements are integrated into the java.nio package and consist of the subsequent significant functionalities:

Stream API Enhancements for IO

  • list(Path dir): This method returns a lazily filled stream of Path objects, where each element represents a directory entry in the specified directory (dir).
  • lines(Path path): This method reads all lines from a file specified by the path parameter and returns them as a Stream<String>. Each element of the stream represents a line of text from the file.
  • find: This method is used to search for files in the file tree rooted at a provided starting file. It returns a stream filled with Path objects representing the files found during the search. However, you haven't provided the complete method signature, so it's unclear how this method is used.
  • lines: This method returns a stream containing all of the lines from the BufferedReader's input source. Each element of the stream represents a line of text from the input source. This method is useful for processing text data in a file or from any other input source.
  • Type and Repeating Annotations

Type Annotations

Type Annotations enhance Java's type system by enabling the utilization of annotations wherever a type is employed. This extension empowers programmers to provide additional details to the compiler, thereby assisting in identifying and avoiding errors during the compilation phase. For instance, to protect against NullPointerException, a variable declaration can be annotated to guarantee that it does not contain a null value:

Example

@NonNull String str;

Further examples of Type Annotations include:

Ensuring a list does not contain null elements:

Example

@NonNull List<String>

Declaring that the elements within a list should not be empty:

Example

List<@NonNull String> str

Specifying that an array is intended to exclusively hold non-negative integers:

Example

Arrays<@NonNegative Integer> sort

Designating a file as encrypted to enhance its security:

Example

@Encrypted File file

Signaling that a connection is active and requires proper handling:

Example

@Open Connection connection

Defining an error that is raised in a specific scenario, like when attempting to divide by zero:

Example

void divideInteger(int a, int b) throws @ZeroDivisor ArithmeticException

Repeating Annotations

The concept of Repeating Annotations was introduced in Java 8, enabling the application of a single annotation multiple times to one element in your code. This functionality proves valuable in scenarios where it is necessary to annotate an element several times with the same annotation to communicate multiple details or implement various configurations.

In Java, in order to utilize Repeating Annotations, two essential components are needed:

  1. Define a Repeatable Annotation Type:

Initially, we define the annotation @Review and specify it as repeatable by employing the @Repeatable meta-annotation. The @Repeatable is configured with the container annotation type, which, in this instance, is denoted as Reviews.

Example

import java.lang.annotation.Repeatable;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

@Repeatable(Reviews.class)

@Retention(RetentionPolicy.RUNTIME) // Make this annotation available at runtime.

@interface Review {

    String reviewer();

    String date();

    String comment();

}

Within this instance, the @Review annotations are capable of encompassing the reviewer's identity, the review's date, and a feedback statement.

How to: Define the Enclosing Annotation Type:

The Reviews container annotation is defined with a value element that should contain an array of the repeatable annotation type (Review). This annotation serves the purpose of collecting all the @Review annotations that are assigned to a single element.

Example

@Retention(RetentionPolicy.RUNTIME) // Make this annotation available at runtime.

@interface Reviews {

    Review[] value();

}

Filename: EmployeeRoles.java

Example

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

import java.lang.annotation.Repeatable;

// Define the repeatable annotation type

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.TYPE) // Apply to class level

@Repeatable(Roles.class)

@interface Role {

    String value();

}



// Define the container annotation for the repeatable annotation

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.TYPE) // Apply to class level

@interface Roles {

    Role[] value();

}



// Use the repeating annotation on a class

@Role("Developer")

@Role("Lead")

@Role("Manager")

public class EmployeeRoles {

    public static void main(String[] args) throws NoSuchMethodException {

        // Access and print the repeated annotations

        if (EmployeeRoles.class.isAnnotationPresent(Roles.class)) {

            Roles rolesAnnotation = EmployeeRoles.class.getAnnotation(Roles.class);

            for (Role role : rolesAnnotation.value()) {

                System.out.println("Role: " + role.value());

            }

        } else {

            System.out.println("No Roles Annotation present.");

        }

    }

}

Output:

Output

Role: Developer

Role: Lead

Role: Manager

Default Methods

In Java, there is a feature that allows the creation of default methods within interfaces. Default methods are methods that are specified within an interface and marked with the default keyword. They are considered non-abstract methods and are able to include a method body.

For more information and examples: click here

Filename: DefaultMethodsExample.java

Example

interface Vehicle {

    // Abstract method

    String getBrand();

    // Default method

    default void turnAlarmOn() {

        System.out.println("The vehicle alarm is now on.");

    }

    // Another default method

    default void turnAlarmOff() {

        System.out.println("The vehicle alarm is now off.");

    }

}

class Car implements Vehicle {

    private String brand;

    Car(String brand) {

        this.brand = brand;

    }

    @Override

    public String getBrand() {

        return brand;

    }

    // The class can choose to override a default method

    @Override

    public void turnAlarmOn() {

        System.out.println("The car alarm is now on.");

    }

}

public class DefaultMethodsExample {

    public static void main(String[] args) {

        Vehicle myCar = new Car("Tesla");

        System.out.println("Brand: " + myCar.getBrand());

        myCar.turnAlarmOn(); // Overridden method

        myCar.turnAlarmOff(); // Inherited default method

    }

}

Output:

Output

Brand: Tesla

The car alarm is now on.

The vehicle alarm is now off.

Nashorn JavaScript Engine

Nashorn JavaScript Engine

Nashorn serves as a JavaScript engine employed for dynamically running JavaScript code within the Java Virtual Machine (JVM). Java includes a command-line utility called jjs, which facilitates the execution of JavaScript code.

JavaScript code can be run in two ways:

  • By utilizing the jjs command-line tool
  • By incorporating it into Java source code.

For more information and examples: click here

Filename: NashornExample.java

Example

import javax.script.ScriptEngine;

import javax.script.ScriptEngineManager;

import javax.script.ScriptException;

public class NashornExample {

    public static void main(String[] args) {

        // Create a script engine manager

        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();

        // Obtain a Nashorn script engine instance

        ScriptEngine nashorn = scriptEngineManager.getEngineByName("nashorn");

        try {

            // Evaluate JavaScript code from String

            nashorn.eval("print('Hello, Nashorn');");

            // Evaluate JavaScript code that returns a value

            Object result = nashorn.eval("10 + 2");

            System.out.println("Result of 10 + 2: " + result);

            // Define a JavaScript function and call it from Java

            nashorn.eval("function sum(a, b) { return a + b; }");

            Object sumResult = nashorn.eval("sum(10, 15);");

            System.out.println("Result of sum(10, 15): " + sumResult);

        } catch (ScriptException e) {

            System.err.println("ScriptException: " + e.getMessage());

        }

    }

}

Output:

Output

Hello, Nashorn

Result of 10 + 2: 12

Result of sum(10, 15): 25

StringJoiner

In the java.util package, Java introduced a fresh final class named StringJoiner. This class serves the purpose of building a series of characters that are divided by a specified delimiter. With this class, it is possible to generate strings by specifying delimiters such as comma (,) or hyphen (-).

For more information and examples: click here

Filename: StringJoinerExample.java

Example

import java.util.StringJoiner;

public class StringJoinerExample {

    public static void main(String[] args) {

        // Create a StringJoiner with a delimiter, prefix, and suffix

        StringJoiner joiner = new StringJoiner(", ", "[", "]");

        // Add strings to the StringJoiner

        joiner.add("Apple");

        joiner.add("Banana");

        joiner.add("Cherry");

        joiner.add("Date");

        // Convert the StringJoiner to String and print the result

        String result = joiner.toString();

        System.out.println(result);

    }

}

Output:

Output

[Apple, Banana, Cherry, Date]

Collectors

The Collectors class is a concrete class that inherits from the Object class in Java. It offers functionalities for reducing operations, like gathering elements into collections and summarizing elements based on different criteria.

For more information and examples: click here

Filaname: CollectorsExample.java

Example

import java.util.Arrays;

import java.util.List;

import java.util.Map;

import java.util.stream.Collectors;

public class CollectorsExample {

    public static void main(String[] args) {

        // Example list of people's names

        List<String> names = Arrays.asList("John", "Sara", "Mark", "Sara", "Chris", "Paula");

        // Collecting into a List

        List<String> nameList = names.stream().collect(Collectors.toList());

        System.out.println("Names List: " + nameList);

        // Grouping names by the first letter

        Map<Character, List<String>> namesByFirstLetter = names.stream()

            .collect(Collectors.groupingBy(name -> name.charAt(0)));

        System.out.println("Names Grouped by First Letter: " + namesByFirstLetter);

        // Joining names into a single string separated by commas

        String allNames = names.stream().collect(Collectors.joining(", "));

        System.out.println("All Names Joined: " + allNames);

        // Counting the distinct names

        long distinctNameCount = names.stream().distinct().count();

        System.out.println("Distinct Names Count: " + distinctNameCount);

    }

}

Output:

Output

Names List: [John, Sara, Mark, Sara, Chris, Paula]

Names Grouped by First Letter: {J=[John], S=[Sara, Sara], M=[Mark], C=[Chris], P=[Paula]}

All Names Joined: John, Sara, Mark, Sara, Chris, Paula

Distinct Names Count: 5

Stream API

The java.util.stream package in Java 8 comprises various classes, interfaces, and an enum that facilitate functional-style manipulation of elements through lazy computation, meaning the operations are executed only when necessary.

For more information and examples: click here

Filename: StreamApiExample.java

Example

import java.util.Arrays;

import java.util.List;

import java.util.stream.Collectors;



public class StreamApiExample {

    public static void main(String[] args) {

        // A list of integers

        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);



        // Use Stream API to filter, map, and collect operations

        List<Integer> evenSquares = numbers.stream()

                                           .filter(n -> n % 2 == 0) // Filter even numbers

                                           .map(n -> n * n) // Map to their squares

                                           .collect(Collectors.toList()); // Collect results into a list



        // Print the resulting list

        System.out.println(evenSquares);

    }

}

Output:

Output

[4, 16, 36, 64, 100]

Stream Filter

In Java, the stream feature includes a function called filter that allows for the selection of stream elements based on a specified predicate. For instance, if you aim to extract solely the even elements from a list, you can effortlessly achieve this objective by leveraging the filter function.

The method accepts a predicate as a parameter and produces a stream of elements that meet the specified condition.

For more information and examples: click here

Syntax:

The filter function takes a Predicate<T> as input. A Predicate<T> is a functional interface that defines a single method that returns a boolean value and takes one argument of type T.

Example

Stream<T> filter(Predicate<? super T> predicate)

Filename: StreamFilterExample.java

Example

import java.util.Arrays;

import java.util.List;

import java.util.stream.Collectors;

public class StreamFilterExample {

    public static void main(String[] args) {

        // A list of names

        List<String> names = Arrays.asList("John", "Sara", "Mark", "Jennifer", "Paul", "Jane");

        // Use Stream API to filter names that start with "J"

        List<String> namesStartingWithJ = names.stream()

                                               .filter(name -> name.startsWith("J")) // Filter names starting with "J"

                                               .collect(Collectors.toList()); // Collect results into a list

        // Print the filtered list

        System.out.println(namesStartingWithJ);

    }

}

Output:

Output

[John, Jennifer, Jane]

Java Base64 Encoding and Decoding

Java offers a class called Base64 for handling encryption and decryption tasks. To utilize the functionalities provided by this class, you must import the java.util.Base64 class into your source file.

The class offers a variety of encoders and decoders to secure data at various stages.

For more information and examples: click here

Filename: Base64Example.java

Example

import java.util.Base64;

public class Base64Example {

    public static void main(String[] args) {

        // Original String

        String originalString = "Hello, World!";

        // Encode using basic encoder

        String encodedString = Base64.getEncoder().encodeToString(originalString.getBytes());

        System.out.println("Encoded String (Basic) : " + encodedString);

        // Decode the base64 encoded string

        byte[] decodedBytes = Base64.getDecoder().decode(encodedString);

        String decodedString = new String(decodedBytes);

        System.out.println("Decoded String : " + decodedString);

        // URL and Filename safe encoding

        String urlEncodedString = Base64.getUrlEncoder().encodeToString(originalString.getBytes());

        System.out.println("Encoded String (URL) : " + urlEncodedString);

        // MIME encoder example

        String mimeEncodedString = Base64.getMimeEncoder().encodeToString(originalString.getBytes());

        System.out.println("Encoded String (MIME) : " + mimeEncodedString);

    }

}

Output:

Output

Encoded String (Basic) : SGVsbG8sIFdvcmxkIQ==

Decoded String : Hello, World!

Encoded String (URL) : SGVsbG8sIFdvcmxkIQ==

Encoded String (MIME) : SGVsbG8sIFdvcmxkIQ==

Java Parallel Array Sorting

A new enhancement in the Arrays class in Java allows for sorting array elements concurrently. The parallelSort method has been introduced in the java.util.Arrays class, leveraging the JSR 166 Fork/Join parallelism common pool for array sorting. This method is overloaded for different types of sorting functionalities.

For more information and examples: click here

Filename: ParallelArraySortingExample.java

Example

import java.util.Arrays;

import java.util.Comparator;

public class ParallelArraySortingExample {

    public static void main(String[] args) {

        // Parallel sorting for an array of primitives

        int[] numbers = {9, 3, 1, 5, 13, 12, 7, 4, 11, 6};

        System.out.println("Original array: " + Arrays.toString(numbers));

        Arrays.parallelSort(numbers);

        System.out.println("Sorted array: " + Arrays.toString(numbers));

        // Parallel sorting for an array of objects with a custom comparator

        String[] fruits = {"Peach", "Apple", "Orange", "Banana", "Grape", "Pear"};

        System.out.println("\nOriginal array: " + Arrays.toString(fruits));

        // Using a lambda expression for the comparator to sort in reverse alphabetical order

        Arrays.parallelSort(fruits, Comparator.reverseOrder());

        System.out.println("Sorted array in reverse order: " + Arrays.toString(fruits));

    }

}

Output:

Output

Original array: [9, 3, 1, 5, 13, 12, 7, 4, 11, 6]

Sorted array: [1, 3, 4, 5, 6, 7, 9, 11, 12, 13]

Original array: [Peach, Apple, Orange, Banana, Grape, Pear]

Sorted array in reverse order: [Pear, Peach, Orange, Grape, Banana, Apple]

JDBC Enhancements

Java Database Connectivity (JDBC) is a Java application programming interface (API) responsible for facilitating connections to databases, executing SQL queries and statements, as well as managing the retrieval and processing of result sets acquired from the database.

JDBC Improvements

1) Removal of the JDBC-ODBC Bridge

Beginning from Java 8 onwards, the JDBC-ODBC Bridge, which allowed JDBC applications to connect to databases using ODBC drivers, has been eliminated. This move promotes the adoption of native JDBC drivers to enhance performance, dependability, and utilization of contemporary database functionalities.

2) New Features in JDBC 4.2

Java 8 unveiled JDBC 4.2, which included various notable improvements to the JDBC API to enhance the flexibility, capability, and security of working with databases. One of the notable enhancements is the introduction of support for REF_CURSOR.

Support for the SQL REF CURSOR type was introduced in JDBC 4.2. This enhancement enables JDBC to manage cursor types that are returned by stored procedures and functions in databases, simplifying the process of retrieving intricate data structures.

  1. Inclusion of the java.sql.DriverAction Interface

This interface offers a way for JDBC drivers to execute cleanup tasks upon driver deregistration. It improves driver management, particularly in situations where JDBC drivers are dynamically loaded and unloaded.

Within JDBC 4.2, a security validation was added to the DriverManager.deregisterDriver(Driver driver) function. This validation guarantees that solely the entity who initially registered a driver has the authority to deregister it, thereby thwarting any unauthorized attempts to deregister and ultimately bolstering the overall security measures in place.

This interface acts as the foundation for JDBC types, offering a standardized method to recognize SQL types by their names and associate them with JDBC Types. This shift represents a step towards adopting a more object-oriented strategy for managing SQL types.

  1. Introduction of the Enum java.sql.JDBCType

In association with the SQLType interface, the JDBCType enum serves as its implementation, offering a practical list of JDBC types. This simplifies the process of managing SQL data types in JDBC tasks with increased clarity and type safety.

  1. Enhanced Assistance for Extensive Update Counts

The JDBC 4.2 version introduces enhancements to the API to handle substantial update counts, suitable for SQL actions impacting a significant quantity of rows that exceed the capacity of an integer. Functions such as Statement.getLargeUpdateCount and Statement.executeLargeUpdate serve as illustrations.

  1. Updates to Current Interfaces

Numerous interfaces have been modified to incorporate additional functionalities, including the ability to handle extensive update numbers and the introduction of the Date and Time API. These adjustments guarantee the alignment of JDBC with the most recent SQL norms and enhancements in Java.

  1. Improvements in RowSet 1.2

The JDBC RowSet 1.2 version has been enhanced to boost its capabilities and alignment with the JDBC 4.2 functionalities. These enhancements encompass enhanced backing for the java.sql.SQLType and the recently introduced Date and Time API, among other improvements.

Java JDBC DriverAction

In Java 8, the JDBC 4.2 version introduces the java.sql.DriverAction interface, which allows JDBC drivers to specify cleanup tasks during deregistration. This feature improves resource handling and security measures in Java programming.

DriverAction Method

Method Description
void deregister() Called by DriverManager.deregisterDriver(Driver) to notify the JDBC driver that it has been de-registered. This method should contain the necessary clean-up logic to release resources and perform any finalization needed by the driver upon deregistration.

Java JDBC SQLType

Method Description
String getName() Returns the SQL type name as a String, typically corresponding to the SQL type name used in databases.
String getVendor()* Returns the name of the vendor for the custom SQL type, applicable for types that are specific to a particular database vendor.
Integer getVendorTypeNumber() Returns an integer value representing the vendor-specific SQL type code, useful for handling database-specific types.

Java JDBCType

JDBCType is an enumeration that specifies constants for identifying generic SQL types, known as JDBC types. This enumeration extends java.lang.Enum and implements the java.sql.SQLType interface.

JDBCType Fields

The table below outlines the JDBCType enumeration constants and their respective descriptions, offering information on the general SQL types they signify:

Enum Constant Description
ARRAY Represents an array of values in a SQL database.
BIGINT Represents a large integer value, typically mapping to a 64-bit integer.
BINARY Represents an array of bytes, for binary values.
BIT Represents a single bit value, often used for boolean values in SQL databases.
BLOB Represents a Binary Large Object stored as a collection of binary data.
BOOLEAN Represents a boolean value, for true/false data.
CHAR Represents a fixed-length character string.
CLOB Represents a Character Large Object, for large text data.
DATALINK Represents a link to data outside of a SQL database.
DATE Represents a date value (year, month, day).
DECIMAL Represents a numeric value with fixed precision and scale.
DISTINCT Represents a distinct type, a unique data type defined in SQL.
DOUBLE Represents a double precision floating point number.
FLOAT Represents a floating point number.
INTEGER Represents an integer value, typically mapping to a 32-bit integer.
JAVA_OBJECT Represents an object in the Java programming language that is stored in the database.
LONGNVARCHAR Represents a long string value in the National character set.
LONGVARBINARY Represents a long array of bytes for binary values.
LONGVARCHAR Represents a long string of characters.
NCHAR Represents a fixed-length string that uses the National character set.
NCLOB Represents a Large Object of National characters.
NULL Special type representing a NULL SQL type.
NUMERIC Represents a numeric value with precision and scale.
NVARCHAR Represents a variable-length string that uses the National character set.
OTHER Represents a type that is database-specific and not defined by JDBC.
REAL Represents a single precision floating point number.
REF Represents a reference to an SQL structured type instance in the database.
REF_CURSOR Represents a cursor or a reference to a cursor.
ROWID Represents a row id used by SQL databases.
SMALLINT Represents a small integer value.
SQLXML Represents SQL XML values.
STRUCT Represents an SQL structured type.
TIME Represents a time value (hour, minute, second).
TIMEWITHTIMEZONE Represents a time value with timezone information.
TIMESTAMP Represents a timestamp (date and time).
TIMESTAMPWITHTIMEZONE Represents a timestamp with timezone information.
TINYINT Represents a very small integer value.
VARBINARY Represents a variable array of bytes for binary values.
VARCHAR Represents a variable-length character string.

JDBCType Methods

Method Description Return Type
getName() Returns the SQLType name that represents a SQL data type. String
getVendor() Returns the name of the vendor that supports this data type. String
getVendorTypeNumber() Returns the vendor-specific type number for the data type. Integer
valueOf(int type) Returns theJDBCTypethat corresponds to the specifiedjava.sql.Typesvalue. ThrowsIllegalArgumentExceptionif this enum type has no constant with the specifiedTypesvalue. JDBCType
valueOf(String name) Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. ThrowsIllegalArgumentExceptionif no constant with the specified name, andNullPointerExceptionif the argument is null. JDBCType
values() Returns an array containing the constants of this enum type, in the order they are declared. This method may be used to iterate over the constants. JDBCType[]

Java 8 Security Enhancements

1) By default, the Java Secure Socket Extension (JSSE) provider activates Transport Layer Security (TLS) 1.1 and TLS 1.2 protocols on the client side.

2) An enhanced functionality called AccessController.doPrivileged has been introduced, allowing code to affirm a portion of its privileges while still permitting the complete inspection of the stack for additional permissions.

3) The SunJCE provider now includes Advanced Encryption Standard (AES) and Password-Based Encryption (PBE) algorithms like PBEWithSHA256AndAES128 and PBEWithSHA512AndAES256.

4) The Java Secure Socket Extension (SunJSSE) has automatically activated the Server Name Indication (SNI) extension for client applications in JDK 7. In JDK 8, support for the SNI extension is available for server applications. This extension enhances the SSL/TLS protocols by specifying the server name that the client intends to connect to during the handshaking process.

5) The SunJSSE has been improved to include support for Authenticated Encryption with Associated Data (AEAD) algorithms. Enhancements to the Java Cryptography Extension (SunJCE) provider now allow for the implementation of AES/GCM/NoPadding cipher and the utilization of Galois/Counter Mode (GCM) algorithm parameters.

6) The keytool utility now includes a fresh command flag, -importpassword, that enables the acceptance of a password for secure storage as a secret key. Additionally, new classes like java.security.DomainLoadStoreParameter and java.security.PKCS12Attribute have been introduced to provide support for the DKS keystore type.

7) Within JDK 8, advancements have been made to the cryptographic algorithms by introducing the SHA-224 variation from the SHA-2 collection of message-digest implementations.

8) Enhanced support for NSA Suite B Cryptography which includes:

  • OID registration for NSA Suite B cryptography algorithms
  • Support for 2048-bit DSA key pair generation and additional signature algorithms for 2048-bit DSA keys such as SHA224withDSA and SHA256withDSA.
  • Lifting of the keysize restriction from 1024 to 2048 for Diffie-Hellman (DH) algorithm.

The SecureRandom class is responsible for creating highly secure random numbers that are suitable for applications like private or public keys, ciphers, and signed messages. In JDK 8, the getInstanceStrong method was added to retrieve the most robust SecureRandom instance. This method is particularly useful when generating RSA private and public keys. Additionally, SecureRandom has undergone the following updates:

  • Two new implementations have been added for UNIX systems, offering both blocking and non-blocking functionalities.

A fresh addition to the toolkit is the PKIXRevocationChecker class, designed to verify the revocation status of certificates using the PKIX algorithm. This class offers a range of functionalities including best effort verification, end-entity certificate validation, and customization options specific to different mechanisms.

11) The Public Key Cryptography Standards 11 (PKCS) have recently been enhanced to incorporate support for 64-bit systems on the Windows platform.

12) Kerberos 5 has introduced two additional rcache variations. The "none" type signifies the absence of an rcache, while the "dfl" type denotes the DFL-style file-based rcache. Additionally, support for the acceptor requested subkey has been incorporated. Configuration settings for these can be found in the sun.security.krb5.rcache and sun.security.krb5.acceptor.subkey system properties.

13) Within JDK 8, the support for Kerberos 5 protocol transition and constrained delegation is available in a unified manner within the identical realm.

Java 8 now has strong encryption enabled by default, disabling weak encryption. The DES-related encryption types used in Kerberos 5 are no longer supported out of the box. To enable these encryption types, you can include allowweakcrypto=true in the krb5.conf configuration file.

You have the option to assign a server name as null to indicate that the server is not bound to any specific name. This allows a client to seek the service from any server name. Once a context is defined, the server can access the name as a negotiated attribute using the identifier SASL.BOUNDSERVERNAME.

16) The Mac OS X now supports the Java Native Interface (JNI) bridge to the native Java Generic Security Service (JGSS). To activate this feature, you can enable it by setting the system property sun.security.jgss.native to true.

A recently introduced system property, jdk.tls.ephemeralDHKeySize, allows for the customization of ephemeral DH key sizes. The DH key size must be at least 1024 bits, with the exception of exportable cipher suites or when operating in legacy mode (when jdk.tls.ephemeralDHKeySize is set to 'legacy').

The Java Secure Socket Extension (JSSE) provider defaults to respecting the client's cipher suite preference. It is possible to alter this behavior to prioritize the server's cipher suite preference by invoking SSLParameters.setUseCipherSuitesOrder(true) on the server.

Java 8 Tools Enhancements

1) An executable command called jjs is presented, enabling the activation of the Nashorn engine for interactive shell usage or for interpreting script files.

2) When the Java command is executed, it has the ability to launch JavaFX applications as long as the JavaFX application has been packaged appropriately.

3) The documentation for the java command, available in both nroff and HTML formats, has undergone a significant overhaul. The more sophisticated settings are now categorized into Runtime, Compiler, Garbage Collection, and Serviceability based on their respective domains of impact. Numerous options that were previously undocumented are now explained thoroughly. Additionally, there is a dedicated segment outlining the options that have been deprecated or eliminated since the last version release.

4) The latest jdeps tool on the command line enables developers to inspect class files to identify dependencies at the package or class level.

5) Remote access to diagnostic commands, traditionally limited to local accessibility through the jcmd tool, is now attainable from a distance. The Java Management Extensions (JMX) facilitate this remote access by exposing diagnostic commands through a platform MBean connected to the platform MBean server. This MBean adheres to the com.sun.management.DiagnosticCommandMBean interface.

6) The jarsigner tool now offers a fresh feature called -tsapolicyid, allowing users to solicit a signed timestamp from a Time Stamping Authority and affix it to a signed JAR file.

7) The introduction of the java.lang.reflect.Executable.getParameters method provides the capability to retrieve the names of the formal parameters for any method or constructor. It is important to note that formal parameter names are not stored in .class files by default. To include formal parameter names in a specific .class file and allow the Reflection API to access them, it is necessary to compile the source file using the -parameters option of the javac compiler.

8) The Java Language Specification (JLS) Section 15.21 will now ensure proper enforcement of the type rules for binary comparisons within the Java programming language by the javac compiler.

9) The recent update has eliminated the apt tool and its corresponding API that were previously found in the com.sun.mirror package.

Javadoc Enhancements

In Java SE 8, the following new APIs were added to the Javadoc tool.

  • A new DocTree API introduce a scanner which enables you to traverse source code that is represented by an abstract syntax tree. This extends the Compiler Tree API to provide structured access to the content of javadoc comments.
  • The javax.tools package contains classes and interfaces that enable you to invoke the Javadoc tool directly from a Java application, without executing a new process.
  • The "Method Summary" section of the generated documentation of a class or interface has been restructured. Method descriptions in this section are grouped by type. By default, all methods are listed. You can click a tab to view methods of a particular type (static, instance, abstract, concrete, or deprecated, if they exist in the class or interface).
  • The javadoc tool now has support for checking the content of javadoc comments for issues that could lead to various problems, such as invalid HTML or accessibility issues, in the files that are generated by javadoc. The feature is enabled by default, and can also be controlled by the new -Xdoclint option.
  • Pack200 Enhancements

The Java class file format has undergone modifications due to JSR 292, which facilitates the integration of Dynamically Typed Languages with the Java Platform.

The Pack200 mechanism has been enhanced to optimize the compression of Java SE 8 class files efficiently. It is now capable of identifying constant pool entries and recently added bytecodes from JSR 292. Consequently, archives compressed using this iteration of the pack200 utility will not work with earlier editions of the unpack200 utility.

Java 8 I/O Enhancements

In Java 8, there are several improvements to the java.nio.charset.Charset and extended charset implementations. It includes the following:

  • A New SelectorProvider which may improve performance or scalability for server. The /dev/poll SelectorProvider continues to be the default. To use the Solaris event port mechanism, run with the system property java.nio.channels.spi.Selector set to the value sun.nio.ch.EventPortSelectorProvider.
  • The size of <JDK_HOME>/jre/lib/charsets.jar file is decreased.
  • Performance has been improvement for the java.lang.String(byte, ∗) constructor and the java.lang.String.getBytes method.
  • Java 8 Networking Enhancements

1) The latest addition in Java is the introduction of the java.net.URLPermission class, which serves as a permission model for accessing resources specified by a designated URL.

2) The addition of the package jdk.net introduces platform-specific socket options and a method for configuring these options across all standard socket types. These socket options are specified in jdk.net.ExtendedSocketOptions.

3) When using the HttpURLConnection class, in the presence of a security manager, if a method call is made that leads to an effort to establish a connection, the calling code must have either a "connect" SocketPermission for the host/port pair of the target URL or a URLPermission that authorizes such an action.

In the case of automatic redirection being activated, it is essential for the requester to possess the authorization to establish a connection with the redirected host or URL if the request is directed to a different location.

Java 8 Concurrency Enhancements

The java.util.concurrent package included the introduction of two additional interfaces and four fresh classes.

Java.util.concurrent Interfaces

Interface Description
public static interface CompletableFuture.AsynchronousCompletionTask It is a marker interface which is used to identify asynchronous tasks produced by async methods. It may be useful for monitoring, debugging, and tracking asynchronous activities.
public interface CompletionStage<T> It creates a stage of a possibly asynchronous computation, that performs an action or computes a value when another CompletionStage completes.

Java.util.concurrent Classes

Class Description
public class CompletableFuture<T> extends Object implements Future<Future<T>>, CompletionStageCompletionStage It is aFuture that may be explicitly completed, and may be used as a CompletionStage, supporting dependent functions and actions that trigger upon its completion.
public static class ConcurrentHashMap.KeySetView<K,V> extends Object implements Set<K>, Serializable It is a view of a ConcurrentHashMap as a Set of keys, in which additions may optionally be enabled by mapping to a common value.
public abstract class CountedCompleterCountedCompleter<T> extends ForkJoinTaskForkJoinTask A ForkJoinTask with a completion action performed when triggered and there are no remaining pending actions.
public class CompletionException extends RuntimeException It throws an exception when an error or other exception is encountered in the course of completing a result or task.

New Methods in java.util.concurrent.ConcurrentHashMap class

The most recent release of the ConcurrentHashMap class brings forth a range of fresh methods. These consist of multiple forEach techniques (forEach, forEachKey, forEachValue, and forEachEntry), exploration techniques (search, searchKeys, searchValues, and searchEntries), and a plethora of reduction techniques (reduce, reduceToDouble, reduceToLong, and more). Additionally, several other miscellaneous methods (mappingCount and newKeySet) have also been integrated into the class.

New classes in java.util.concurrent.atomic

The most recent update brings in expanded, adjustable, variable support via a limited collection of fresh classes DoubleAccumulator, DoubleAdder, LongAccumulator, and LongAdder. These classes utilize techniques to reduce contention internally, resulting in significant enhancements in throughput when contrasted with Atomic variables.

Class Description
public class DoubleAccumulator extends Number implements Serializable It is used for one or more variables that together maintain a running double value updated using a supplied function.
public class DoubleAdder extends Number implements Serializable It is used for one or more variables that together maintain an initially zero double sum.
public class LongAccumulator extends Number implements Serializable It is used for one or more variables that together maintain a running long value updated using a supplied function.
public class LongAdder extends Number implements Serializable It is used for one or more variables that together maintain an initially zero long sum.

New methods in java.util.concurrent.ForkJoinPool Class

The class now includes two additional functions: retrieveCommonPoolParallelism and accessCommonPool. These methods are designed to provide the specific parallelism level of the common pool and the instance of the common pool, respectively.

Method Description
public static ForkJoinPool commonPool() It returns the common pool instance.
Public static int getCommonPoolParallelism() It returns the targeted parallelism level of the common pool.

New class java.util.concurrent.locks.StampedLock

An additional class called StampedLock has been introduced to enable the implementation of a capability-based locking mechanism. It offers three modes for managing read and write access, namely writing, reading, and optimistic reading. This class is equipped with functionalities that allow for conditional transitions between the different modes.

Class Description
public class StampedLock extends Object implements Serializable This class represents a capability-based lock with three modes for controlling read/write access.

Java API for XML Processing (JAXP) 1.6 Enhancements

Java 8 introduced Java API for XML Processing (JAXP) 1.6, which mandates the utilization of the service provider loader mechanism specified by java.util.ServiceLoader for loading services from service configuration files.

The reason behind this decision is to enable potential modularization of the Java SE platform in the future, allowing service providers to be deployed using methods other than JAR files and potentially without the need for service configuration files.

Java Virtual Machine Enhancements

The validation of invokespecial commands has been enhanced to allow invocation of only a constructor in the current class or its immediate superclass.

Java Mission Control 5.3 is included in Java 8

Java Mission Control (JMC) is a sophisticated collection of utilities that allows for effective and thorough data examination, offering advanced, non-intrusive monitoring and administration capabilities for Java applications. Within JMC, there are dedicated segments focused on key analysis categories like code execution efficiency, memory usage, and response time.

The Java Mission Control bundled with JDK 8 now comes with Babel Language Packs in Japanese and Simplified Chinese as part of its default installation.

Java 8 Internationalization Enhancements

1) Unicode Enhancements

The JDK 8 includes support for Unicode 6.2.0. It contains the following features.

  • 733 new characters including Turkish Lira sign.
  • 7 new scripts: Meroitic Hieroglyphs Meroitic Cursive Sora Sompeng Chakma Sharada Takri Miao
  • Meroitic Hieroglyphs
  • Meroitic Cursive
  • Sora Sompeng
  • Chakma
  • Sharada
  • Takri
  • Miao
  • 11 new blocks: including 7 blocks for the new scripts listed above and 4 blocks for the following existing scripts:
  • Arabic Extended-A
  • Sundanese Supplement
  • Meetei Mayek Extensions
  • Arabic Mathematical Alphabetical Symbols
  • Adoption of Unicode CLDR Data and the java.locale.providers System Property

The Common Locale Data Repository (CLDR) project, developed by the Unicode Consortium, is aimed at providing comprehensive locale data support for various languages globally. It is recognized as the leading repository for standard locale data worldwide. Even though the JDK 8 release has integrated the XML-based locale data from CLDR, it is initially inactive.

There are four distinct sources for locale data:

  • CLDR represents the locale data provided by the Unicode CLDR project.
  • HOST represents the current user's customization of the underlying operating system's settings. It works only with the user's default locale, and the customizable settings may vary depending on the OS, but primarily Date, Time, Number, and Currency formats are supported.
  • SPI represents the locale sensitive services implemented in the installed SPI providers.
  • JRE represents the locale data that is compatible with the prior JRE releases.

In order to specify the preferred locale data source, you can utilize the java.locale.providers system property where you list the data sources in the order of preference. For instance, java.locale.providers=HOST,SPI,CLDR,JRE. The default setting is the same as java.locale.providers=JRE,SPI.

Java 8 New Calendar and Locale APIs

Within the JDK 8 release, there have been introductions of two fresh classes, multiple additional methods, and a novel return value for a preexisting static method.

The java.util.spi package has been expanded with the inclusion of two additional abstract classes tailored for service providers.

Class Description
public abstract class CalendarDataProvider extends LocaleServiceProvider It is an abstract class for service providers that provide locale-dependent Calendar parameters.
public abstract class CalendarNameProvider extends LocaleServiceProvider It is an abstract class for service providers that provide localized string representations (display names) of Calendar field values.

A static method is now able to recognize Locale.UNICODELOCALEEXTENSION for the numbering system.

Method Description
public static final DecimalFormatSymbols getInstance(Locale locale) It is used to get the DecimalFormatSymbols instance for the specified locale. This method provides access to DecimalFormatSymbols instances for locales supported by the Java runtime itself as well as for those supported by installed DecimalFormatSymbolsProvider implementations. It throws NullPointerException if locale is null.

Added New methods in calender API:

Method Description
public boolean isSupportedLocale(Locale locale) It returns true if the given locale is supported by this locale service provider. The given locale may contain extensions that should be taken into account for the support determination. It is define in java.util.spi.LocaleServiceProvider class
public String getCalendarType() It returns the calendar type of this Calendar. Calendar types are defined by the Unicode Locale Data Markup Language (LDML) specification. It is defined in java.util.Calendar class.

New style specifiers are added for the Calendar.getDisplayName and Calendar.getDisplayNames methods to determine the format of the Calendar name.

Specifier Description
public static final int SHORT_FORMAT It is a style specifier for getDisplayName and getDisplayNames indicating a short name used for format.
public static final int LONG_FORMAT It is a style specifier for getDisplayName and getDisplayNames indicating a long name used for format.
public static final int SHORT_STANDALONE It is a style specifier for getDisplayName and getDisplayNames indicating a short name used independently, such as a month abbreviation as calendar headers.
public static final int LONG_STANDALONE It is a style specifier for getDisplayName and getDisplayNames indicating a long name used independently, such as a month name as calendar headers.

Two new Locale methods for dealing with a locale's (optional) extensions.

Method Description
public boolean hasExtensions() It returns true if this Locale has any extensions.
public Locale stripExtensions() It returns a copy of this Locale with no extensions. If this Locale has no extensions, this Locale is returned itself.

Two new Locale.filter methods return a list of Locale instances that match the specified criteria, as defined in RFC 4647:

Method Description
public static ListList<Locale> filter(ListList<Locale> priorityList,Collection<Locale> locales) It returns a list of matching Locale instances using the filtering mechanism defined in RFC 4647. This is equivalent to filter(List, Collection, FilteringMode) when mode is Locale.FilteringMode.AUTOSELECT_FILTERING.
public static ListList<Locale> filter(ListList<Locale> priorityList,CollectionCollection<Locale> locales locales, Locale.FilteringMode mode) It returns a list of matching Locale instances using the filtering mechanism defined in RFC 4647.

Two new Locale.filterTags methods return a list of language tags that match the specified criteria, as defined in RFC 4647.

Method Description
public static ListList filterTags(ListList priorityList, CollectionCollection<Tag> tags) It returns a list of matching languages tags using the basic filtering mechanism defined in RFC 4647. This is equivalent to filterTags(List, Collection, FilteringMode) when mode is Locale.FilteringMode.AUTOSELECT_FILTERING.
public static ListList<Tag> filterTags(ListCollection<Tag> priorityList, Collection<Collection<Tag>> tags, Locale.FilteringMode mode) It returns a list of matching languages tags using the basic filtering mechanism defined in RFC 4647.

Two new lookup methods return the best-matching locale or language tag using the lookup mechanism defined in RFC 4647.

Method Description
public static Locale lookup(ListList<Locale> priorityList, CollectionCollection locales) It returns a Locale instance for the best-matching language tag using the lookup mechanism defined in RFC 4647.
Public static String lookupTag(ListList<Locale> priorityList,CollectionCollection<Locale> tags) It returns the best-matching language tag using the lookup mechanism defined in RFC 4647.

Other Java 8 Version Enhancements

Enhancements in JDK 8u5

1) There has been a decrease in the frequency at which security prompts are displayed for an application.

Enhancements in JDK 8u11

1) Users have the ability to disable promotions from sponsors during the installation or update of JRE by accessing the Advanced section within the Java Control Panel.

2) In the JAR file manifest, you can specify the Entry-Point attribute to designate one or multiple classes as the legitimate entry point(s) for your Rich Internet Application (RIA).

Enhancements in JDK 8u20

1) The tool formerly known as javafxpackager has now been rebranded as javapackager. This utility has been updated to include additional parameters for self-contained application bundlers.

Follwing enhancements are related to the java tool:

  • An experimental JIT compiler option related to Restricted Transactional Memory (RTM) has been added.
  • Several options related to string deduplication have been added.
  • Several options related to Advanced Encryption Standard (AES) intrinsics have been added.
  • Combinations of garbage collection options have been deprecated.

2) The Java HotSpot Virtual Machine now features the Garbage Collection Tuning Guide, offering insights into the various garbage collectors integrated within the Java HotSpot VM. This resource assists in determining the most suitable garbage collector for enhancing the efficiency of your application, particularly when dealing with extensive data volumes (several gigabytes), numerous threads, and high transaction frequencies.

Enhancements in JDK 8u31

1) The latest update eliminates the SSLv3 protocol from the Advanced settings in the Java Control Panel.

Enhancements in JDK 8u40

Java tool

1) The addition of the -XX:+CheckEndorsedAndExtDirs flag addresses the deprecation of the endorsed-standards override mechanism (JDK-8065675) and the extension mechanism (JDK-8065702). This option assists in detecting any current implementations of these mechanisms and is compatible with JDK 7u80 and JDK 8u40.

2) Java Flight Recorder (JFR) provides several methods for accessing premium features and activating JFR while an application is running.

Java Mission Control offers a range of Java command line options, like jcmd diagnostic commands, and Graphical User Interface (GUI) controls. This versatility allows you to set the necessary options when starting up or engage with JFR at a later time.

3) A new parameter, dumponexit={true|false}, can now be used with the -XX:StartFlightRecording=parameter=value option. This parameter determines if a dump file containing JFR data should be created upon the JVM's controlled termination.

4) The features associated with Restricted Transactional Memory (RTM) have transitioned from being in an experimental phase. These features encompass -XX:RTMAbortRatio=abortratio, -XX:RTMRetryCount=numberof_retries, -XX:+UseRTMDeopt, and -XX:+UseRTMLocking.

5) Java 8 brought about the introduction of Application Class Data Sharing (AppCDS) as an extension of CDS (Class Data Sharing). AppCDS allows for classes from both the standard extensions directories and the application class path to be included in the shared archive. It's worth noting that this feature, previously considered experimental, is now a stable, commercial offering.

6) Additional choices, such as -XX:+ResourceManagement and -XX:ResourceManagementSampleInterval=value, have been included in the updated version.

7) Further details have been included regarding large pages, which are also referred to as huge pages. These memory pages are considerably larger than the regular memory page size and are designed to enhance the performance of processor Translation-Lookaside Buffers. The Linux features -XX:+UseHugeTLBFS, -XX:+UseSHM, and -XX:+UseTransparentHugePages have been recorded.

8) The flag -XX:ObjectAlignmentInBytes=alignment is now officially documented.

JJS tool

A new feature has been introduced which allows users to enable or disable optimistic type assumptions with deoptimizing recompilation using the --optimistic-types=[true|false] flag.

2) A new feature has been introduced to the jjs tool which allows users to specify the ECMAScript language version using the --language=[es5] option.

Javapackager tool

1) Fresh arguments have been introduced for OS X bundlers, with the mac.CFBundleVersion argument serving to specify the internal version number.

2) The mac.dmg.simple argument indicates if DMG customization steps that depend on executing AppleScript code are skipped.

Jcmd tool

The Jcmd utility is utilized for real-time communication with Java Flight Recorder (JFR). It allows users to activate premium functionalities, initiate/cease flight recordings, and retrieve different system status updates.

Jstat tool

The jstat utility has been enhanced to include details regarding the compressed class space, a unique component within the metaspace.

Virtual machine

The Scalable Native Memory Tracking feature in the HotSpot VM assists in identifying memory leaks within the VM and distinguishing when memory leaks are not originating from the VM itself. The Native Memory Tracker can operate continuously on extensive systems without automatically shutting down and without introducing a notable performance degradation exceeding what is deemed tolerable for smaller applications.

The following enhancements were introduced in JDK 8:

  • A new command, jjs, was added to the JDK. This command initiates the Nashorn JavaScript engine, allowing users to run JavaScript code either through an interactive shell or by executing script files.
  • Enhancements to the java command now enable it to launch JavaFX applications, assuming the JavaFX application is correctly packaged. Guidance on how classes are located can be found in the relevant documentation.
  • Significant updates were made to the java command's manual pages (available in both nroff and HTML formats), with a comprehensive reorganization of advanced options into categories such as Runtime, Compiler, Garbage Collection, and Serviceability, depending on their area of impact. This update includes descriptions of several options that were previously undocumented, along with a section dedicated to options that have been deprecated or removed in the current release.
  • JDK 8 introduces the jdeps command-line tool, designed to help developers analyze class files for dependencies at the package or class level.
  • Remote access to diagnostic commands, which were previously only available locally via the jcmd tool, has been enabled in JDK 8 through the Java Management Extensions (JMX). These diagnostic commands are now accessible through the com.sun.management.DiagnosticCommandMBean interface, with further details available in the jcmd tool documentation for different operating systems.
  • The jarsigner tool has been updated with a new -tsapolicyid option, allowing users to request and attach a timestamp from a Time Stamping Authority (TSA) to a signed JAR file.
  • JDK 8 allows the retrieval of formal parameter names of any method or constructor via the java.lang.reflect.Executable.getParameters method. To enable this feature, .class files must store formal parameter names, which can be achieved by compiling the source file with the -parameters option in the javac compiler.
  • The Java Language Specification (JLS) Section 15.21's type rules for binary comparisons have been strictly enforced by the javac compiler starting from JDK 8. This corrects previous behavior where javac accepted certain Object-primitive comparisons that did not align with JLS 15.21, marking them as type errors now.
  • JDK 8 sees the removal of the apt tool and its associated API in the com.sun.mirror package. Developers are advised to use the javac tool and the APIs in javax.annotation.processing and javax.lang.model packages for annotation processing instead.
  • Java 8 Features MCQ

  1. What is the main advantage of using Lambda expressions in Java 8?
  • They reduce the need for exception handling.
  • They allow for creating threads more easily.
  • They enable functional programming constructs.
  • They automatically handle memory management.

Explanation: Lambda expressions facilitate the implementation of functional interfaces, enabling functional programming paradigms in Java. They provide a concise way to express instances of single-method interfaces (functional interfaces) without the need for creating anonymous classes.

  1. Which interface annotation is used to designate a functional interface in Java 8?
  • @Functional
  • @FunctionalInterface
  • @SingleMethod
  • @LambdaInterface

Explanation: In Java 8, @FunctionalInterface is an optional annotation that can be used to indicate that an interface is intended to be a functional interface. It helps to prevent developers from accidentally adding more than one abstract method to the interface, which would invalidate its functional status.

  1. What is a benefit of using the Stream API introduced in Java 8?
  • It allows direct access to hardware-level resources.
  • It simplifies the use of graphical user interfaces (GUIs).
  • It provides a declarative way to process collections of data.
  • It improves memory allocation techniques.

Explanation: The Stream API in Java 8 allows for functional-style operations on streams of elements, such as filtering, mapping, and reducing. It offers a declarative approach to processing data collections, improving readability and maintainability of code.

  1. Which feature of Java 8 allows interfaces to have method implementations?
  • Lambda expressions
  • Stream API
  • Default methods
  • Functional interfaces

Explanation: Default methods in interfaces were introduced in Java 8 to allow interfaces to provide method implementations. This feature enables backward compatibility by allowing interfaces to evolve without breaking the implementing classes.

  1. What does method reference provide in Java 8?
  • A way to invoke static methods only.
  • A concise syntax for referring to methods or constructors.
  • An alternative to Lambda expressions for defining functions.
  • A mechanism to overload methods with different signatures.

In Java 8, method reference is a functionality that offers a concise way to reference methods or constructors without actually running them. This functionality improves code clarity by cutting down on redundant code when utilizing Lambda expressions to invoke methods.

Input Required

This code uses input(). Please provide values below: