JavaRush /Java Blog /Random EN /Java 8. Everything you need

Java 8. Everything you need

Published in the Random EN group

Java 8 Tutorial

"Java is still alive and people are starting to understand it."
Welcome to my introduction to Java 8. This article will take you step-by-step through all the new features from Java 7 to Java 8. With quick and simple code examples, we can learn how to use Default Interfaces, Method references , and Repeatable annotations . At the end of the article we will get acquainted with the Stream API.
Java 8. All you need is 1
No unnecessary chatter - just code and comments! Forward!

Default Methods for Interfaces

Java 8 allows us to add non-abstract methods (that are implemented) to interfaces by adding the default. This feature is also known as Extention Methods . Below is the first example:
interface Formula {
    double calculate(int a);

    default double sqrt(int a) {
        return Math.sqrt(a);
    }
}
In addition to the abstract method calculate, the interface Formulaalso defines a default method sqrt. Classes that implement this interface only need to implement the calculate. The default method sqrtcan be used out of the box.
Formula formula = new Formula() {
    @Override
    public double calculate(int a) {
        return sqrt(a * 100);
    }
};

formula.calculate(100);     // 100.0
formula.sqrt(16);           // 4.0
The interface Formulais implemented as an anonymous class. The code is redundant: 6 lines for implementation sqrt(a * 100). As we'll see in the next section, there is a prettier way to implement a single method in Java 8.

Lambda expressions

Let's start with a simple example of sorting a list of strings in previous versions of Java:
List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");

Collections.sort(names, new Comparator<String>() {
    @Override
    public int compare(String a, String b) {
        return b.compareTo(a);
    }
});
The static method Collections.sortaccepts a list and a comparator in the order in which the list is to be sorted. You can always create an anonymous comparator class and pass it along. Instead of creating an anonymous class, in Java 8 you can create a shorter notation, a lambda expression.
Collections.sort(names, (String a, String b) -> {
    return b.compareTo(a);
});
As you can see the code is much shorter and easier to read. But this can be made even shorter:
Collections.sort(names, (String a, String b) -> b.compareTo(a));
For a body with one line, you can skip {}the word return. But you can make it even shorter:
Collections.sort(names, (a, b) -> b.compareTo(a));
The Java compiler knows about argument types, so you can skip them as well. Let's dig deeper into lambda expressions and understand how they can be used.

Functional Interfaces

How do lambda expressions fit into the Java type system? Each lambda corresponds to a type described in the interface. Therefore, a functional interface should contain only one abstract method. Each lambda expression of this type will correspond to this abstract method. Since default methods are not abstract, you are free to create default methods in functional interfaces as needed. We can also use arbitrary interfaces as lambda expressions if there is only one abstract method in this interface. To meet these requirements you need to add @FucntionalInterfacean annotation. The compiler knows about it and will throw an exception if you want to provide more than one abstract method. Example:
@FunctionalInterface
interface Converter<F, T> {
    T convert(F from);
}
Converter<String, Integer> converter = (from) -> Integer.valueOf(from);
Integer converted = converter.convert("123");
System.out.println(converted);    // 123
Keep in mind that the code will also compile if @FunctionalInterfacethe annotation is omitted.

Method and Constructor References

The example above can also be made even smaller by using method references:
Converter<String, Integer> converter = Integer::valueOf;
Integer converted = converter.convert("123");
System.out.println(converted);   // 123
Java 8 allows you to pass references to a method or constructor by adding ::. The example above shows how we can reference a static method, although we can also reference non-static methods:
class Something {
    String startsWith(String s) {
        return String.valueOf(s.charAt(0));
    }
}
Something something = new Something();
Converter<String, String> converter = something::startsWith;
String converted = converter.convert("Java");
System.out.println(converted);    // "J"
Let's see how ::it works with constructors. To begin, we will define an example class with different constructors:
class Person {
    String firstName;
    String lastName;

    Person() {}

    Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}
Next, we will define an interface for creating new objects:
interface PersonFactory<P extends Person> {
    P create(String firstName, String lastName);
}
Instead of implementing a creation factory, we'll tie it all together with ::constructor help:
PersonFactory<Person> personFactory = Person::new;
Person person = personFactory.create("Peter", "Parker");
We created a link to the constructor via Person::new. The Java compiler will automatically select the correct constructor that matches the method signature PersonFactory.create. ... To be continued. Unfortunately, I didn’t find a way to save a draft of the article, and this is really strange, and the time for translation is over - so I’ll finish it later. For everyone who knows and understands English - Original Article . If you have suggestions for correcting the translation, write in any way available to you. My Github account
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION