자바8 람다. 메서드 전달
![](https://blog.kakaocdn.net/dn/6VfrD/btrW6qPFYUF/IH8PXuKb86dT3kdibOvmM0/img.png)
요즘 신규 프로젝트에서 일하게 됐다. 이곳은 자바8을 사용하는 곳.
내 생애 처음 자바8 이상을 사용하는 곳에 왔다.
끄적끄적 도서관에서 자바8과 스프링5 관련 책들을 빌려 람다식, 스트리밍, 리액티브 프로그램 맛보기만 했었다.
개발 시작 전인 분석 및 설계 단계이긴한데 실제 개발이 시작되면 솔직히 람다식이나 스트림 형태로 해도 될지 모르겠다.
프로젝트 관리 파트에서 가이드가 나올텐데...
사용하든 말든 사실 난 관계없다. 뭘로 해도 장단점이 있다고 생각한다.
사용하지 말라하면 하던 데로 하면 되고, 사용해도 된다고 하면 좋은 기회가 되겠지.
이번 포스팅은 오로지 "나"를 위한 포스팅이다.
"모던 자바 인 액션" 한빛미디어에서 출판한 책 속 예제를 올려두고 수시로 확인하며 익숙해지고자 함이다. 도서관에서 3번째 빌려온 책이다. Rx JAVA나 WebFlux 관련 Spring5 책과 함께 보니, 확실히 람다식과 스트림이 익숙해진다.
1. Apple 데이터 객체를 만든다. 무게와 색 정보를 갖고 있다. FilteringApples 클래스 안에 정의했다.
public static class Apple {
private int weight = 0;
private String color = "";
public Apple(int weight, String color) {
this.weight = weight;
this.color = color;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@SuppressWarnings("boxing")
@Override
public String toString() {
return String.format("Apple{color='%s', weight=%d}", color, weight);
}
}
2. FilteringApples 안에 FilterGreenApples 메서드를 만든다.
자바 8 이전 방식의 메서드다.
제목 그대로 Apple List 모음을 받아서 Green 사과를 필터링한다.
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;
}
3. FilteringApples 안에 FilterHeavyApples 메서드를 만든다.
자바 8 이전 방식의 메서드다.
제목 그대로 Apple List 모음을 받아서 무게 150 이상의 사과를 필터링한다.
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;
}
4. FilteringApples의
public class FilteringApples {
public static void main(String[] args) {
// 3개 정도의 사과 리스트를 만든다.
List<Apple> inventory = Arrays.asList(
new Apple(80, "green"),
new Apple(155, "green"),
new Apple(120, "red")
);
// 1. 예전 방식 녹색 사과 필터링
List<Apple> greenApples = FilteringApples.filterGreenApples(inventory);
System.out.println(greenApples);
//2. 150 이상 사과 필터링
List<Apple> HeavyApples = FilteringApples.filterHeavyApples(inventory);
System.out.println(HeavyApples);
.....
자바8 이전의 지식을 갖고 있는 개발자들은 위와 같이 필터를 만든다.
실행 모습
![](https://blog.kakaocdn.net/dn/JVHfz/btrW764rAXX/U5I2vsbTI6ijA1T6qvTV70/img.png)
자바8의 람다식 그리고 Predicate를 인자로 받는 함수.
리스트가 아닌 1개의 Apple 객체를 인자로 받아 녹색 사과와 무게 150 이상의 사과를 리턴하는 boolean 펑션이다.
이 두 함수를 자바 8에 새로 생성된 Predicate 펑셔널 함수를 이용해 구현해 본다.
public 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;
}
public static boolean isGreenApple(Apple apple){
return "green".equals(apple.getColor());
}
public static boolean isHeavyApple(Apple apple){
return apple.getWeight() > 150;
}
FilteringApples의 main 메서드 안에 필터를 적용해 본다.
List<Apple> greenApples2 = FilteringApples.filterApples(inventory, FilteringApples::isGreenApple);
System.out.println(greenApples2);
List<Apple> HeavyApples2 = FilteringApples.filterApples(inventory, FilteringApples::isHeavyApple);
System.out.println(HeavyApples2);
메서드 레퍼런스는 람다의 축약 표현이다.
다음과 같이 사용할 수 있습니다.
클래스 이름::메서드 이름
생성자::new
메서드를 값으로 전달했다. isHeavyApple, isGreenApple... 비효율적이다. 한두 번 사용하고 만다.
isHeavyApple, isGreenApple 메서드를 정의하거나 만들지 않고 자바 8의 익명 함수(람다) 개념으로 구현할 수 있다.
List<Apple> greenApples3 =FilteringApples.filterApples(inventory,(Apple a)-> a.getColor().equals("green") );
System.out.println(greenApples3);
List<Apple> HeavyApples3 = FilteringApples.filterApples(inventory,(Apple a)-> a.getWeight() > 150);
System.out.println(HeavyApples3);
List<Apple> filterApples = FilteringApples.filterApples(inventory, (Apple a) -> a.getWeight() < 80 ||
"red".equals(a.getColor()));
System.out.println(filterApples);
처음 이 코드를 봤을 때... 난해했다. 예제를 8번 정도 보고, 이런저런 예제를 따라 하다 보니 이제야 편해지고 어떻게 사용하는지 감이 온다.
스프링 5의 webFlux, 그리고 리액티브 프로그래밍 방식을 습득하려면 꼭 람다식에 익숙해져야 한다. 물론 Must는 아니지만...
전체 소스코드
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
public class FilteringApples {
public static void main(String[] args) {
//System.out.println("================");
List<Apple> inventory = Arrays.asList(
new Apple(80, "green"),
new Apple(155, "green"),
new Apple(120, "red")
);
// 1. 예전 방식 녹색 사과 필터링
List<Apple> greenApples = FilteringApples.filterGreenApples(inventory);
System.out.println(greenApples);
//2. 150 이상 사과 필터링
List<Apple> HeavyApples = FilteringApples.filterHeavyApples(inventory);
System.out.println(HeavyApples);
System.out.println("================================================");
System.out.println("자바8 방식으로 변경");
System.out.println("================================================");
System.out.println("자바8 예제 1");
List<Apple> greenApples2 = FilteringApples.filterApples(inventory, FilteringApples::isGreenApple);
System.out.println(greenApples2);
List<Apple> HeavyApples2 = FilteringApples.filterApples(inventory, FilteringApples::isHeavyApple);
System.out.println(HeavyApples2);
System.out.println("자바8 예제 2 축약형");
List<Apple> greenApples3 =FilteringApples.filterApples(inventory,(Apple a)-> a.getColor().equals("green") );
System.out.println(greenApples3);
List<Apple> HeavyApples3 = FilteringApples.filterApples(inventory,(Apple a)-> a.getWeight() > 150);
System.out.println(HeavyApples3);
List<Apple> filterApples = FilteringApples.filterApples(inventory, (Apple a) -> a.getWeight() < 80 ||
"red".equals(a.getColor()));
System.out.println(filterApples);
}
public static void myPrint(List<Apple> apples){
for(Apple apple : apples){
System.out.println(apple.toString());
}
}
// 1.예전 방식
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;
}
// 2.예전 방식
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;
}
// 3. 자바8 방식
public static boolean isGreenApple(Apple apple){
return "green".equals(apple.getColor());
}
//4. 자바8 방식
public static boolean isHeavyApple(Apple apple){
return apple.getWeight() > 150;
}
//5. 3과 4를 이용
// 메서드가 p라는 이름의 프레디케이트 파라미터로 전달됨
/*
참고로
public interface Predicate<T>{
boolean test(T t);
}
*/
public 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;
}
public static class Apple {
private int weight = 0;
private String color = "";
public Apple(int weight, String color) {
this.weight = weight;
this.color = color;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@SuppressWarnings("boxing")
@Override
public String toString() {
return String.format("Apple{color='%s', weight=%d}", color, weight);
}
}
}
'슬기로운 자바 개발자 생활 > 모던 자바와 Reactive' 카테고리의 다른 글
자바8 함수형 인터페이스 (0) | 2023.03.20 |
---|---|
인텔리J에서 Reactivex RX Java 시작하기 (0) | 2023.02.11 |
네티 Netty 프레임워크 공부 02 양방향 통신 (예제 첨부) (0) | 2022.12.21 |
네티 Netty 프레임워크 공부 01 (예제 첨부) (0) | 2022.12.21 |
댓글