728x90
public class LamdaIsBetter {
public static void main(String[] args) {
List<String> words = new ArrayList<>();
Collections.sort(words, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
}); // 익명 클래스
Collections.sort(words, (s1,s2)-> -s1.compareTo(s2)); //람다
Collections.sort(words, comparingInt(String::length)); //메소드 참조
words.sort(comparingInt(String::length)); // Java 8 List.sort 메서드 이용
}
}
- 익명 클래스 방식은 코드가 너무 길기 때문에 함수형 프로그래밍에 적합하지 않음
- 익명 클래스는 컴파일 타임에 클래스가 만들어짐(람다는 런타임에 만들어진다.)
- 대신 람다를 사용하자
- 타입을 명시해야 코드가 더 명확할 때를 제외하고는, 람다의 모든 매개변수 타입은 생략하자.(컴파일러의 타입 추론 기능 활용)
- "타입을 알수 없다"는 오류를 낼때만 해당 타입을 명시한다.
- 컴파일러는 타입추론하는데 필요한 타입 정보 대부분을 제네릭에서 얻어온다.(제네릭의 로 타입을 쓰지 말자)
enum Operation {
PLUS("+") {
public double apply(double x, double y) { return x + y; }
},
MINUS("-") {
public double apply(double x, double y) { return x - y; }
},
TIMES("*") {
public double apply(double x, double y) { return x * y; }
},
DIVIDE("/") {
public double apply(double x, double y) { return x * y; }
};
private final String symbol;
Operation(String symbol) { this.symbol = symbol; }
@Override public String toString() { return symbol; }
public abstract double apply(double x, double y);
}
/*
람다
*/
enum Operation {
PLUS("+", (x, y) -> x + y),
MINUS("-", (x, y) -> x - y),
TIMES("*", (x, y) -> x * y),
DIVIDE("/", (x, y) -> x / y);
private final String symbol;
private final DoubleBinaryOperator op;
Operation(String symbol, DoubleBinaryOperator op) {
this.symbol = symbol;
this.op = op;
}
@Override
public String toString() { return symbol; }
public double apply(double x, double y) {
return op.applyAsDouble(x, y);
}
}
public class Main {
public static void main(String[] args) {
// 사용은 아래와 같이
Operation.PLUS.apply(2, 3);
}
}
람다의 단점 , 한계
- 람다는 이름이 없고 문서화도 못한다. 코드 자체로 동작이 명확히 설명되지 않거나 코드 줄수가 길어지면 사용 x(코드 길이 : 1~3줄이 적당)
- 열거 타입 생성자 안의 람다는 열거 타입의 인스턴스 멤버에 접근불가 ( 인스턴스는 런타임에 생성, 인수타입은 컴파일 타입에 추론됨)
- 한개의 메소드만 가질 수 잇음
- this
람다의 this는 람다를 둘러싸고 있는 클래스를 가르키고,
익명 클래스의 this 는 익명 클래스의 인스턴스를 가르킨다.
함수 객체가 자기 자신을 참조한다면, 반드시 익명 클래스를 사용해야한다.
Collections.sort(words, new Comparator<String>() {
String a="boo";
@Override
public int compare(String o1, String o2) {
System.out.println(this.getClass() + " " + this.a);
return o1.compareTo(o2);
}
}); // 익명 클래스
Collections.sort(words, (s1,s2)->{
System.out.println(this.getClass());
return -s1.compareTo(s2);
} ); //람다
/*
class Probe$1 boo
class Probe
*/
'JAVA > Effective Java' 카테고리의 다른 글
item 50) 적시에 방어적 복사본을 만들라 (0) | 2021.03.06 |
---|---|
item 46) 스트림에서는 부작용 없는 함수를 사용하라 (0) | 2021.02.27 |
item 64) 객체는 인터페이스를 사용해 참조하라. (0) | 2021.02.07 |
item 36) 비트 필드 대신 EnumSet을 사용하라 (0) | 2021.02.06 |
item 35) ordinal 메소드 대신에 인스턴스 필드를 사용하라. (0) | 2021.02.06 |