functional interface란 하나의 추상 메소드만을 가진 인터페이스를 말한다.
functional 인터페이스는 하나의 추상 메소드만을 가지기 때문에 구현할 때 그 메소드의 이름을 생략해도 된다.
standard functional interface를 사용하므로 코드사용을 더욱 줄일 수 있다.
A lambda expression consists of the following:
lamda expression은 다음을 포함하고 있다.
괄호 안에 콤마로 나뉜 파라미터 리스트
화살표 token, ->
하나의 expression이거나 statement 블록을 담은 body
하나의 expression을 정의하면 자바 런타임이 expression을 평가 후 value를 return 한다.
return statement로 대체할 수 있다.
return statement는 expression이 아니므로 {}사이의 statement를 닫아야한다.
void 메소드일 경우엔 닫지 않아도 된다.
// single expression
p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
// return statement
p -> { return p.getGen == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25;
}
Arrays.sort(rosterAsArray, new PersonAgeComparator());
sort 2번째 파라미터는 Comparator 함수형 인터페이스
함수형 인터페이스므로 Comparator를 구현한 클래스를 정의후 인스턴스를 생성하는 대신 람다 표현식을 사용할 수 있다.
Arrays.sort(rosterAsArray,
(Person a, Person b) -> {
return a.getBirthday().compareTo(b.getBirthday());
}
);
만약 Person 클래스에 나이를 compare하는 함수가 이미 존재한다면 람다 표현식의 body 대신 사용할 수 있다.
Arrays.sort(rosterAsArray,
(a, b) -> Person.compareByAge(a, b)
);
Because this lambda expression invokes an existing method, you can use a method reference instead of a lambda expression:
이 람다 표현식은 존재하는 함수를 호출하는 것이므로 람다표현식 대신 메소드 레퍼런스를 사용할 수 있다.
Arrays.sort(rosterAsArray,Person::compareByAge);
The method reference Person::compareByAge is semantically the same as the lambda expression (a, b) -> Person.compareByAge(a, b). Each has the following characteristics:
1. Its formal parameter list is copied from Comparator<Person>.compare, which is (Person, Person).
2. Its body calls the method Person.compareByAge.
4가지의 of method references:
Reference to a static method
Reference to an instance method of a particular object
Reference to an instance method of an arbitrary object of a particular type
Reference to a constructor
nested 클래스들은 한곳에서만 사용되는 클래스들을 논리적 그룹으로 묶고, 캡슐화를 증가시키며, 읽기 쉽고 유지가능한 코드를 만든다.
각각의 클래스들은 이러한 공통된 장점과 특정 상황에 사용되도록 의도됐다.
Local class
Anonymous class
Lambda expression
Use it if you are encapsulating a single unit of behavior that you want to pass to other code. For example, you would use a lambda expression if you want a certain action performed on each element of a collection, when a process is completed, or when a process encounters an error.
Use it if you need a simple instance of a functional interface and none of the preceding criteria apply (for example, you do not need a constructor, a named type, fields, or additional methods).
Nested class
Use it if your requirements are similar to those of a local class, you want to make the type more widely available, and you don't require access to local variables or method parameters.
Use a non-static nested class (or inner class) if you require access to an enclosing instance's non-public fields and methods. Use a static nested class if you don't require this access.