Notice
Recent Posts
Recent Comments
Link
개발 무지렁이
[JAVA8] 함수라는 새로운 값의 형식과 값으로 귀결되는 메서드 참조, 그로 인한 간결성 (+ 람다) 본문
𐂂 값으로 귀결될 수 있는 일급 자바 시민
클래스를 인스턴스화한 결과는 '값'으로 귀결되자만
클래스나 클래스 안의 메서드는 그 자체로는 값이 아니다.
이 때 값으로 귀결되지 못하는 클래스나 메서드는 이급 자바 시민이라 한다.
⚠️ int, double, ..., 객체 모두 그 자체가 값이거나 값으로 귀결되는 일급 자바 시민(일급값)이다.
메서드는 어떻게 해도 값이 아니다.
하지만 메서드를 일급 자바 시민(값)으로 만들면 프로그래밍에 유용하게 활용할 수 있다.
클래스나 클래스 안의 메서드는 그 자체로는 값이 아니다.
이 때 값으로 귀결되지 못하는 클래스나 메서드는 이급 자바 시민이라 한다.
⚠️ int, double, ..., 객체 모두 그 자체가 값이거나 값으로 귀결되는 일급 자바 시민(일급값)이다.
메서드는 어떻게 해도 값이 아니다.
하지만 메서드를 일급 자바 시민(값)으로 만들면 프로그래밍에 유용하게 활용할 수 있다.
☕ 자바8
: 함수를 새로운 값의 형식으로 추가하고, 함수를 값으로 취급한다.
: 함수를 새로운 값의 형식으로 추가하고, 함수를 값으로 취급한다.
🦉 new 연산자
: new라는 객체생성 연산자로, 객체 참조를 생성하여 인스턴스라는 값을 전달할 수 있다.
: new라는 객체생성 연산자로, 객체 참조를 생성하여 인스턴스라는 값을 전달할 수 있다.
𐁍 메서드 참조 ::
::라는 연산자로, 메서드 참조를 생성해 함수라는 값을 전달할 수 있다.
[ 이급 자바 시민을 일급 자바 시민으로 바꿀 수 있는 기능을 추가했다, 메서드 -> 함수(값) ]
여기서 중요한 것은 메서드는 코드를 포함하고 있다는 것이다.
즉, 메서드를 값으로써 전달할 수 있다는 것은, 코드를 전달할 수 있다는 것을 의미한다.
[ 이급 자바 시민을 일급 자바 시민으로 바꿀 수 있는 기능을 추가했다, 메서드 -> 함수(값) ]
여기서 중요한 것은 메서드는 코드를 포함하고 있다는 것이다.
즉, 메서드를 값으로써 전달할 수 있다는 것은, 코드를 전달할 수 있다는 것을 의미한다.
𖠃 메서드를 값으로 만들면 뭐가 좋을까
🧩 코드가 간결해진다.
🧩 중복코드를 줄일 수 있다.
간결성
📜 자바8이전 코드.java
File[] hiddenFiles = new File(".").listFiles(new FileFilter() {
public boolean accept(File file) {
return file.isHidden();
}
});
🦉 코드 해석
: 자바8 이전에는 메서드는 값으로 취급될 수 없었다.
따라서 인수로 메서드를 전달할 수 없고, 위의 코드 같이
(값으로 취급되는) 객체로 감싼 다음, 이 객체를 인수로써 전달,해야 했다.
: 자바8 이전에는 메서드는 값으로 취급될 수 없었다.
따라서 인수로 메서드를 전달할 수 없고, 위의 코드 같이
(값으로 취급되는) 객체로 감싼 다음, 이 객체를 인수로써 전달,해야 했다.
📜 자바8이후 코드.java
File[] hiddenFiles = new File(".").listFiles(File::isHidden);
🦉 코드 해석
: 자바8 이후로는 메서드는 메서드 참조를 통해 값으로 취급될 수 있다.
:: 연산자를 통해 함수라는 값으로 바꾸면 위의 코드 같이 간결하게 코드를 작성할 수 있다.
: 자바8 이후로는 메서드는 메서드 참조를 통해 값으로 취급될 수 있다.
:: 연산자를 통해 함수라는 값으로 바꾸면 위의 코드 같이 간결하게 코드를 작성할 수 있다.
중복해소
📜 자바8이전 코드.java
// 녹색 사과만을 골라내는 필터
public static List<Apple> filterGreenApples(List<Apple> inventory) {
List<Apple> result = new ArrayList<>();
for(Apple apple : inventory) {
if(GREEN.equals(apple.getColor())) {
result.add(apple);
}
}
return result;
}
// 무거운 사과만을 골라내는 필터
public static List<Apple> filterHeavyApples(List<Apple> inventory) {
List<Apple> result = new ArrayList<>();
for(Apple apple : inventory) {
if(apple.getWeight() > 150) {
result.add(apple);
}
}
return result;
}
🦉 코드 해석
: 위와 같은 필터기능을 하는 2개의 메서드는 사실상
if문을 제외하면 중복된 코드다.
❓ 필터
: 조건에 따라 특정항목을 선택해서 반환하는 동작을 '필터'라고 한다.
: 위와 같은 필터기능을 하는 2개의 메서드는 사실상
if문을 제외하면 중복된 코드다.
❓ 필터
: 조건에 따라 특정항목을 선택해서 반환하는 동작을 '필터'라고 한다.
📜 자바8이후 코드.java
public static boolean isGreenApple(Apple apple) {
return GREEN.equals(apple.getColor());
}
public static boolean isHeavyApple(Apple apple) {
return apple.getWeight() > 150;
}
public interface Predicate<T> {
boolean test(T t);
}
static List<Apple> filterApples(List<Apple> inventory, Predicate<Apple> p) {
List<Apple> result = new ArrayList<>();
for(Apple apple : inventory) {
if(p.test(apple)) {
result.add(apple);
}
}
return result;
}
filterApples(inventory, Apple::isGreenApple);
filterApples(inventory, Apple::isHeavyApple);
🦉 코드 해석
: 위의 코드와 같이 메서드를 값으로써 전달할 수 있다면
메서드 안의 코드도 전달할 수 있으므로,
메서드 참조에 따라 다른 조건으로 필터링하는 하나의 메서드를 만들어, 중복 코드를 제거할 수 있다.
❓ Predicate
: 수학에서는 인수<로 값을 받아 true or false로 반환하는 함수를 '프레디케이트(Predicate)'라고 한다.
: 위의 코드와 같이 메서드를 값으로써 전달할 수 있다면
메서드 안의 코드도 전달할 수 있으므로,
메서드 참조에 따라 다른 조건으로 필터링하는 하나의 메서드를 만들어, 중복 코드를 제거할 수 있다.
❓ Predicate
: 수학에서는 인수<로 값을 받아 true or false로 반환하는 함수를 '프레디케이트(Predicate)'라고 한다.
𖠃 더 간결하게, 람다 (lambda, 익명함수)
만약, isGreenApple과 isHeavyApple가 한두 번만 사용할 메서드라면,
이를 위해 메서드를 매번 정의하는 것은 비효율적이고, 전체적으로 보면 간결하지도 않다.
이럴 때, 익명함수, 람다를 사용하면 더 간결하게 코드를 작성할 수 있다.
이를 위해 메서드를 매번 정의하는 것은 비효율적이고, 전체적으로 보면 간결하지도 않다.
이럴 때, 익명함수, 람다를 사용하면 더 간결하게 코드를 작성할 수 있다.
📜 자바8이후 람다 코드.java
static List<Apple> filterApples(List<Apple> inventory, Predicate<Apple> p) {
List<Apple> result = new ArrayList<>();
for(Apple apple : inventory) {
if(p.test(apple)) {
result.add(apple);
}
}
return result;
}
filterApples(inventory, (Apple a) -> GREEN.equals(a.getColor()));
filterApples(inventory, (Apple a) -> a.getWeight() > 150);
🦉 코드 해석
: 람다 문법에서 위의 코드는 ( 인수 ) -> 리턴값;을 의미한다.
재사용 횟수가 현저히 적은 함수라면, 람다(익명함수)로 구현해, 호출하고 없애는게 효율적이다.
: 람다 문법에서 위의 코드는 ( 인수 ) -> 리턴값;을 의미한다.
재사용 횟수가 현저히 적은 함수라면, 람다(익명함수)로 구현해, 호출하고 없애는게 효율적이다.
'Backend > 자바' 카테고리의 다른 글
[Java] 다른 객체의 인터페이스를 제공하는 프록시(Proxy) 객체 (0) | 2023.09.16 |
---|---|
[Java] 값의 존재여부를 나타내는 컨테이너 클래스, Optional (0) | 2023.09.11 |
[Java] 스레드 개수를 제한하는 스레드풀(ThreadPool)의 생성과 작업처리 요청 (0) | 2023.08.14 |
[Java] 보조 역할을 수행하는 데몬(Daemon) 스레드 (0) | 2023.08.13 |
[Java] 스레드 정상 실행 종료, interrupt( ): 리소스 정리 후 실행 종료 (0) | 2023.08.13 |
Comments