JavaRush /Blog Java /Random-PL /Java 8. Wszystko, czego potrzebujesz
Roman Beekeeper
Poziom 35

Java 8. Wszystko, czego potrzebujesz

Opublikowano w grupie Random-PL

Samouczek Java 8

„Java wciąż żyje i ludzie zaczynają ją rozumieć”.
Witam w moim wprowadzeniu do języka Java 8. Ten artykuł poprowadzi Cię krok po kroku przez wszystkie nowe funkcje od Java 7 do Java 8. Dzięki szybkim i prostym przykładom kodu możemy dowiedzieć się, jak korzystać z domyślnych interfejsów, odwołań do metod i Powtarzalne adnotacje . Na koniec artykułu zapoznamy się z Stream API.
Java 8. Wszystko czego potrzebujesz to 1
Żadnych niepotrzebnych gadań – po prostu kod i komentarze! Do przodu!

Domyślne metody interfejsów

Java 8 pozwala nam dodawać nieabstrakcyjne metody (które są zaimplementowane) do interfejsów poprzez dodanie rozszerzenia default. Ta funkcja jest również znana jako Metody rozszerzania . Poniżej znajduje się pierwszy przykład:
interface Formula {
    double calculate(int a);

    default double sqrt(int a) {
        return Math.sqrt(a);
    }
}
Oprócz metody abstrakcyjnej calculateinterfejs Formuladefiniuje także metodę domyślną sqrt. Klasy implementujące ten interfejs muszą jedynie zaimplementować bibliotekę calculate. Domyślną metodę sqrtmożna zastosować natychmiast po wyjęciu z pudełka.
Formula formula = new Formula() {
    @Override
    public double calculate(int a) {
        return sqrt(a * 100);
    }
};

formula.calculate(100);     // 100.0
formula.sqrt(16);           // 4.0
Interfejs Formulajest zaimplementowany jako klasa anonimowa. Kod jest zbędny: 6 linii do implementacji sqrt(a * 100). Jak zobaczymy w następnej sekcji, istnieje ładniejszy sposób zaimplementowania pojedynczej metody w Javie 8.

Wyrażenia lambda

Zacznijmy od prostego przykładu sortowania listy ciągów w poprzednich wersjach Javy:
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);
    }
});
Metoda statyczna Collections.sortprzyjmuje listę i komparator w kolejności, w jakiej lista ma być posortowana. Zawsze możesz utworzyć anonimową klasę porównawczą i przekazać ją dalej. Zamiast tworzyć anonimową klasę, w Javie 8 możesz utworzyć krótszą notację, wyrażenie lambda.
Collections.sort(names, (String a, String b) -> {
    return b.compareTo(a);
});
Jak widać kod jest znacznie krótszy i łatwiejszy do odczytania. Ale można to zrobić jeszcze krócej:
Collections.sort(names, (String a, String b) -> b.compareTo(a));
W przypadku treści z jedną linią możesz pominąć {}słowo return. Ale możesz zrobić to jeszcze krócej:
Collections.sort(names, (a, b) -> b.compareTo(a));
Kompilator Java wie o typach argumentów, więc można je również pominąć. Przyjrzyjmy się bliżej wyrażeniom lambda i zobaczmy, jak można ich używać.

Interfejsy funkcjonalne

Jak wyrażenia lambda pasują do systemu typów Java? Każda lambda odpowiada typowi opisanemu w interfejsie. Dlatego interfejs funkcjonalny powinien zawierać tylko jedną metodę abstrakcyjną. Każde wyrażenie lambda tego typu będzie odpowiadać tej abstrakcyjnej metodzie. Ponieważ metody domyślne nie są abstrakcyjne, możesz w razie potrzeby tworzyć metody domyślne w interfejsach funkcjonalnych. Możemy również używać dowolnych interfejsów jako wyrażeń lambda, jeśli w tym interfejsie istnieje tylko jedna metoda abstrakcyjna. Aby spełnić te wymagania należy dodać @FucntionalInterfaceadnotację. Kompilator o tym wie i zgłosi wyjątek, jeśli chcesz podać więcej niż jedną metodę abstrakcyjną. Przykład:
@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
Należy pamiętać, że kod zostanie również skompilowany, jeśli @FunctionalInterfacepominie się adnotację.

Odniesienia do metod i konstruktorów

Powyższy przykład można również zmniejszyć, używając odwołań do metod:
Converter<String, Integer> converter = Integer::valueOf;
Integer converted = converter.convert("123");
System.out.println(converted);   // 123
Java 8 umożliwia przekazywanie referencji do metody lub konstruktora poprzez dodanie ::. Powyższy przykład pokazuje, jak możemy odwoływać się do metody statycznej, chociaż możemy również odwoływać się do metod niestatycznych:
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"
Zobaczmy jak ::to działa z konstruktorami. Na początek zdefiniujemy przykładową klasę z różnymi konstruktorami:
class Person {
    String firstName;
    String lastName;

    Person() {}

    Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}
Następnie zdefiniujemy interfejs do tworzenia nowych obiektów:
interface PersonFactory<P extends Person> {
    P create(String firstName, String lastName);
}
Zamiast wdrażać fabrykę kreacji, połączymy to wszystko w jedną całość przy ::pomocy konstruktora:
PersonFactory<Person> personFactory = Person::new;
Person person = personFactory.create("Peter", "Parker");
Stworzyliśmy link do konstruktora poprzez Person::new. Kompilator Java automatycznie wybierze poprawny konstruktor pasujący do sygnatury metody PersonFactory.create. ... Ciąg dalszy nastąpi. Niestety nie znalazłem sposobu na zapisanie wersji roboczej artykułu, a to jest naprawdę dziwne, a czas na tłumaczenie się skończył - więc dokończę później. Dla każdego, kto zna i rozumie język angielski – artykuł oryginalny . Jeśli masz sugestie dotyczące poprawienia tłumaczenia, napisz w dowolny dostępny Ci sposób. Moje konto na Githubie
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION