Операторът на двоеточие в Java 8

1. Общ преглед

В тази бърза статия ще обсъдим оператора с двойно двоеточие ( : :) в Java 8 и ще разгледаме сценариите, където операторът може да се използва.

2. От Lambdas до Double Colon Operator

С изразите на Lambdas видяхме, че кодът може да стане много кратък.

Например, за да създадете компаратор , е достатъчен следният синтаксис:

Comparator c = (Computer c1, Computer c2) -> c1.getAge().compareTo(c2.getAge()); 

След това, с извод за тип:

Comparator c = (c1, c2) -> c1.getAge().compareTo(c2.getAge());

Но можем ли да направим горния код още по-изразителен и четим? Нека погледнем:

Comparator c = Comparator.comparing(Computer::getAge); 

Използвахме оператора :: като стенография за ламбди, извикващи определен метод - по име. И в крайна сметка резултатът, разбира се, е още по-четлив синтаксис.

3. Как работи

Много просто казано, когато използваме препратка към метод - целевата препратка се поставя преди разделителя :: и името на метода се предоставя след него.

Например:

Computer::getAge;

Разглеждаме препратка към метод към метода getAge, дефиниран в класа Computer .

След това можем да работим с тази функция:

Function getAge = Computer::getAge; Integer computerAge = getAge.apply(c1); 

Забележете, че правим препратка към функцията - и след това я прилагаме към правилния вид аргумент.

4. Референции на методите

Можем да използваме добре този оператор в доста сценарии.

4.1. Статичен метод

Първо ще използваме статичен полезен метод :

List inventory = Arrays.asList( new Computer( 2015, "white", 35), new Computer(2009, "black", 65)); inventory.forEach(ComputerUtils::repair); 

4.2. Метод на инстанция на съществуващ обект

След това нека разгледаме интересен сценарий - препратка към метод на съществуващ екземпляр на обект .

Ще използваме променливата System . out - обект от типа PrintStream, който поддържа метода на печат :

Computer c1 = new Computer(2015, "white"); Computer c2 = new Computer(2009, "black"); Computer c3 = new Computer(2014, "black"); Arrays.asList(c1, c2, c3).forEach(System.out::print); 

4.3. Метод на инстанция на произволен обект от определен тип

Computer c1 = new Computer(2015, "white", 100); Computer c2 = new MacbookPro(2009, "black", 100); List inventory = Arrays.asList(c1, c2); inventory.forEach(Computer::turnOnPc); 

Както можете да видите, ние препращаме метода turnOnPc не към конкретен екземпляр, а към самия тип.

На ред 4 методът на екземпляра turnOnPc ще бъде извикан за всеки обект от инвентара .

И това естествено означава, че - за c1 методът turnOnPc ще бъде извикан в екземпляра на компютъра, а за c2 в екземпляра на MacbookPro .

4.4. Супер метод на определен обект

Да предположим, че имате следния метод в суперкласа Компютър :

public Double calculateValue(Double initialValue) { return initialValue/1.50; } 

и този в подклас MacbookPro :

@Override public Double calculateValue(Double initialValue){ Function function = super::calculateValue; Double pcValue = function.apply(initialValue); return pcValue + (initialValue/10) ; } 

Поканата към calculateValue метод на MacBookPro например:

macbookPro.calculateValue(999.99); 

ще изведе също така извикване за изчисляване на стойност на компютърния суперклас.

5. Препратки към конструктора

5.1. Създайте нов екземпляр

Препращането към конструктор за създаване на екземпляр на обект може да бъде съвсем просто:

@FunctionalInterface public interface InterfaceComputer { Computer create(); } InterfaceComputer c = Computer::new; Computer computer = c.create(); 

Ами ако имате два параметъра в конструктор?

BiFunction c4Function = Computer::new; Computer c4 = c4Function.apply(2013, "white"); 

Ако параметрите са три или повече, трябва да дефинирате нов функционален интерфейс:

@FunctionalInterface interface TriFunction { R apply(A a, B b, C c); default  TriFunction andThen( Function after) { Objects.requireNonNull(after); return (A a, B b, C c) -> after.apply(apply(a, b, c)); } } 

След това инициализирайте обекта си:

TriFunction  c6Function = Computer::new; Computer c3 = c6Function.apply(2008, "black", 90); 

5.2. Създайте масив

И накрая, нека видим как да създадем масив от Компютърни обекти с пет елемента:

Function  computerCreator = Computer[]::new; Computer[] computerArray = computerCreator.apply(5); 

6. Заключение

Както започваме да виждаме, операторът с двойно двоеточие - въведен в Java 8 - ще бъде много полезен в някои сценарии и особено във връзка с потоци.

Също така е доста важно да разгледате функционалните интерфейси за по-добро разбиране на това, което се случва зад кулисите.

Пълният изходен код за примера е наличен в този проект на GitHub - това е проект на Maven и Eclipse, за да може да се импортира и използва такъв, какъвто е.