람다식
람다식은 메서드를 하나의 식(expression)으로 표현하는 것을 의미합니다.
- 객체 지향 언어보다는 함수 지향 언어에 가깝습니다.
- 함수를 간략하면서도 명확한 식으로 표현할 수 있도록 해줍니다.
- 메서드를 람다식으로 표현하면 메서드의 이름 및 반환 값이 없어지므로 익명 함수 라고도 합니다.
- 람다식의 형태는 매개 변수를 가진 코드 블록이지만 런타임 시에는 익명 구현 객체를 생성합니다.
함수형 인터페이스
함수형 인터페이스는 람다식을 다루기 위한 인터페이로 하나의 추상 메서드만 정의되어 있어야 합니다. (단, static 메서드와 default 메서드의 개수에는 제약이 없음) 단순하게 하나의 interface 를 만들고, 거기에 추상화 메소드를 만들면, 람다식이 가능하게 됩니다. 보통 new 객체를 만들 었을 때 추상화 객체에 대한 Anonymous 객체가 생성되었던 부분을 조금더 간결하게 만들어지는 것입니다.
- 함수형 인터페이스 타입의 매개변수 및 반환 타입이 함수형 인터페이스 타입이라면 람다식을 참조하는 참조변수를 매개변수로 지정하고 람다식을 가리키는 참조변수를 반환하거나 또는 람다식 자체를 반환할 수 있습니다.
- 람다식은 Object 타입으로 형변환 할 수 없으며, 오직 함수형 인터페이스로만 형변환이 가능합니다.
- 람다식 내에서 참조하는 지역변수는 final이 붙어 있지 않아도 상수로 간주되며, 외부 지역변수와 같은 이름의 매개변수를 허용하지 않습니다.
- 함수형 인터페이스는 @FuntionalInterface 라는 어노테이션을 붙일 수 있습니다. (컴파일러에서 추상메서드를 갖춘 인터페이스인지 검사, javadoc 페이지에서 해당 인터페이스가 함수형 인터페이스임을 알 수 있도록 한다)
메서드 참조
저는 위의 함수형 인터페이스는 업무에서 거의 사용하고 있지는 않습니다. 오히려 static method를 호출하는 용도로 메서드 참조를 자주 사용합니다. 아직 실업무보다는 개인업무 혹은 배치쪽 작업할때 간혈적으로 사용합니다.
(a, b) -> Math.max(a, b);
Math::max
메서드를 참조해서 매개변수의 정보 및 리턴 타입을 알아내어 람다식에서 불필요한 매개 변수를 제거하는 것이 목적으로,
람다식의 매개 변수는 메서드의 매개값을 전달하는 역할만 하기 때문에 메서드 참조를 이용하면 깔끔하게 처리할 수 있습니다.
스트림
String[] strArr = {"aaa", "ddd", "ccc"};
List<String> strList = Arrys.asList(strArr);
Stream<String> strStreamArr = Arrays.stream(strArr);
스트링배열을 List배열로 바꿔주는 방법입니다. 보통 굳이 저렇게 객체를 두개나 만들 필요없이,
Stream<String> strStreamArr = Stream.of("aaa", "ddd", "ccc");
Stream.of 로 Stream 처리를 하는게 저는 편합니다. 물론 Arrays를 사용하여 java.util.Arrays.ArrayList(java.util.ArrayList 클래스와는 다른 클래스)를 리턴하여 사용할 이유가 있다면 위와같이 처리해야하지만, 보통 그냥 sort 하거나 강제적으로 변경되는 로직을 처리할 용도로만 사용하기 위해서 사용하는 부분이라 그렇게까지 처리할 이유가 없습니다.
String[] sortList = { "01", "02", "03", "04", "05" };
Stream.of(sortList).map(CodeUtils::getAdVrtsTpCode);
CodeUtils 의 static 메소드를 통해, 내가 원하는 코드값으로 변경하는 로직입니다. 예전에는 for문으로 돌리면서 일일이 mapping 처리를 해야했지만, 정말 편하게 변경이 가능합니다. 성능이라든가, 효율적인 부분에 있어, 많은 부분을 람다로 바꿔 개발하진 않겠지만, Stream 은 간혹 사용할 거 같아 약간 정리해봅니다.