Java의 Lambda 🀔

Libienz·2023년 11월 21음
1

Stream&Lambda

목록 볎Ʞ
1/2
post-thumbnail

안녕하섞요 🀗 늬비엔슈입니닀 👊
였늘 포슀팅에서는 자바의 람닀에 대핎서 닀룚얎 볎렀고 í•Žìš” 😎

람닀는 자바 8에서 등장하게 된 개념윌로 람닀륌 읎용하멎 메서드륌 간펞하게 표Ʞ할 수 있고 음꞉ 컬렉션의 읎점도 누멮 수 있게 된답니닀!

람닀의 장점곌 핚께 사용 명섞까지 읎핎하싀 수 있도록 제가 엎심히 섀명 한 번 드렀볎겠습니닀!

람닀란❔

람닀식은❗익명 핚수❗륌 생성하Ʞ 위한 식을 지칭하는 용얎입니닀.
쉬욎 말로 표현하멎 메서드륌 하나의 식 윌로 축앜 표현한 것읎띌고 볌 수 있얎요
바로 예시륌 뎅시닀!

public int addOperation(int a, int b) {
	return a + b;
}

위의 메서드는 정수 두개륌 파띌믞터로 받아서 더하는 ê°„ë‹ší•œ 메서드입니닀.
람닀식윌로 바꟞멎 아래처럌 표현읎 가능핎집니닀

(int a, int b) -> a + b

읎전볎닀 훚씬 간닚하게 표현할 수 있죠?
로직을 위핎서 메서드륌 작성할 필요 없읎 필요한 곳에서 바로 메서드 Ʞ능을 람닀로 작성하여 깔끔하게 사용할 수 있게 되었넀요!

❗하지만 람닀의 장점은 깔끔하게 쀄음 수 있닀가 전부가 아닙니닀❗

간닚하게 표현된 람닀식은 음꞉ 객첎로썚 닀양하게 활용될 수 있고 읎로 읞한 장점을 추가적윌로 누멮 수 있게 된답니닀.

음꞉ 객첎로썚 람닀식읎 파띌믞터로 전달 될 수도 있고 반환 타입윌로도 닀룰 수 있게 되며 Ʞ졎의 메서드볎닀 많은 역할을 할 수 있게 된 것읎죠 😊

음꞉ 객첎로썚의 람닀식의 장점 바로 읎얎서 예시로 볎시죠!

람닀의 장점 - 예시

우늬가 Person의 컬렉션에서 나읎 속성읎 25ì‚Ž 읎상읞 사람듀을 따로 몚윌고 싶닀고 비슈니슀 상황을 가정핎뎅시닀!
람닀륌 사용하지 않는닀멎 닀음곌 같은 메서드륌 만듀겠죠 🀔

	public List<Person> collectAgeOver24(List<Person> people) {
		List<Person> res = new ArrayList<>();
		for (Person p : people) {
			if (p.getAge() > 24) {
				res.add(p);
			}
		}
		return res;
	}

위의 윔드는 핚수 ❗낎부에서❗ 필요한 동작듀을 몚두 정의하고 있는 것을 확읞할 수 있습니닀.

귞런데 요구사항읎 변겜되얎서 25ì‚Ž 믞만읞 사람듀도 몚을 필요가 있닀고 핎뎅시닀!
저희는 핚수 낎부에 로직을 고정하였Ʞ에 새로욎 핚수륌 만듀얎알 합니닀 😢

	public List<Person> collectAgeOver24(List<Person> people) {
		List<Person> res = new ArrayList<>();
		for (Person p : people) {
			if (p.getAge() > 24) {
				res.add(p);
			}
		}
		return res;
	}
    
	public List<Person> collectAgeUnder24(List<Person> people) {
		List<Person> res = new ArrayList<>();
		for (Person p : people) {
			if (p.getAge() <= 24) {
				res.add(p);
			}
		}
		return res;
	}

결곌적윌로 굉장히 비슷하게 생ꞎ 메서드륌 추가핎알만 했습니닀..!

읎와 같읎 메서드륌 추가하는 확장은 요구사항읎 추가될 때마닀 계속 적용되얎알만 하겠죠!
쀑복되는 age 부분을 파띌믞터로 추출하더띌도 크거나 같을 때도 필요핎요! 작거나 같을 겜우도 따젞알핎요! 와 같은 요구사항에 대핎서는 반복적읞 윔드륌 품고 있는 메서드가 추가될 수 밖에 없을 것입니닀.

저희가 프로귞래뚞륌 꿈꟞는 읎상 쀑복 윔드에는 얎느정도 거부감을 가젞알겠죠!
우선은 람닀로 메서드륌 바꟞얎 뎅시닀.


//나읎가 24ì‚Ž 쎈곌만 필터링
public List<Person> collectAgeOver24(List<Person> people) {
  personList.stream()
      .filter(person -> person.getAge() > 24)
      .toList();
}
    
//나읎가 24ì‚Ž 읎하만 필터링
public List<Person> collectAgeUnder24(List<Person> people) {
  personList.stream()
      .filter(person -> person.getAge() <= 24)
      .toList();
}

여전히 비슷하게 생ꞎ 메서드가 두개읎ꞎ 하지만 상당히 볌륚읎 쀄었넀요 🀗

여Ʞ에서!! 람닀식은 음꞉ 객첎읎Ʞ 때묞에 filter()메서드의 파띌믞터로 전달읎 가능한 몚습읎 볎읎시죠!?

결곌적윌로 람닀식을 통핎서 ì–Žë–€ 조걎윌로 필터링할 지륌 filter 메서드의❗왞부에서❗ 정핎쀄 수 있게 된 몚습입니닀!

왞부에서 동작을 지정할 수 있닀는 점을 좀 더 읎용핎서 쀑복되는 부분을 더 쀄여뎅시닀 🀔

public List<Person> filterByAge(List<Person> persons, Predicate<Integer> ageCondition) {
        return persons.stream()
                .filter(person -> ageCondition.test(person.getAge()))
                .collect(Collectors.toList());
}

ì–Žë–€ 방식윌로 필터링 할지륌 파띌믞터로 받아서 적용하도록 수정된 윔드입니닀.

filterByAge()메서드는 앞윌로 닀양한 람닀륌 받윌멎서 필터링 조걎을 변겜핎나갈 수 있게 되었습니닀!

// 추출한 메서드 사용
List<Person> filteredList = filterByAge(personList, age -> age <= 24);
List<Person> filteredList = filterByAge(personList, age -> age > 24);

읎로썚 요구 사항의 확장에서 비롯되는 추가 메서드륌 감당할 필요가 없게 되었죠.
쀑복 윔드가 확 쀄었넀요 🀗 왞부에서 동작을 지정할 수 있게 되는 것읎 읎렇게나 강력하답니닀.

자 람닀륌 사용하니 개발자의 의도가 정확히 드러나멎서 윔드도 훚씬 간결핎지고 확장 요구사항에도 쀑복없읎 유연하게 대처할 수 있게 되었습니닀.
번거롭게 큎래슀와 메서드륌 생성할 필요도 없게 되었고 왞부에서 동작을 지정할 수 있게 되었습니닀.
람닀의 장점 읎제는 느껎지시나요? 😚

람닀의 정첎!

자 지ꞈ까진 람닀의 장점에 대핎서 알아볎았습니닀!
메서드륌 깔끔하게 축앜시킀며 가독성을 향상시킬수도 있고 왞부에서 동작 지정을 가능하게 핚윌로썚 음꞉ 컬렉션의 장점도 가질 수 있닀고 섀명드렞습니닀 👍

귞렇닀멎 람닀의 정첎는 묎엇음까요..?
메서드륌 축앜시킚 것읎띌고 볎멎 역시나 메서드음까요..?
메서드띌Ʞ엔 핚수형 ì–žì–Žê°€ 아닌 자바에서 파띌믞터로 전달도 가능하고 return대상도 될 수 있고 변수도 될 수 있는데 메서드띌고 볎Ʞ엔 얎렵겠죠!
역시 람닀는 메서드가 아니띌 객첎..?

저희 직접 한번 람닀식을 변수로 추출핎뎅시닀 🀗
우선 읞텔늬제읎륌 킀고 닀음의 람닀식을 작성

() -> System.out.println();

ê·ž 닀음에 ctrl + alt + v륌 통핎 정첎가 묎엇읞지 추출핎볎죠!

Runnable runnable = () -> System.out.println();

Runnable읎띌는 핚수형 읞테페읎슀가 람닀의 정첎였넀요!

핚수형 읞터페읎슀

핚수형 읞터페읎슀는 추상 메서드가 딱 1개만 있는 읞터페읎슀륌 말합니닀!
람닀의 정첎가 읎것읎었죠 🀔

읞터페읎슀륌 implement하는 큎래슀가 있얎알 동작을 할텐데 저희는 구현첎륌 만듀얎쀀 적읎 없습니닀!
귞럌에도 람닀는 잘 동작했었죠!

읎유는 바로 람닀식읎 묞법을 통핎서 읞터페읎슀의 읞슀턎슀륌 만듀얎죌고 있었던 것읎Ʞ 때묞입니닀!
결곌적윌로 람닀식은 핚수형 읞터페읎슀의 구현첎읎고 동작읎 혞출될때마닀 하나밖에 없는 메서드륌 싀행시킀도록 섀계가 되얎 있던 것읎넀요!

읎러한 복잡한 곌정을 람닀 묞법윌로 추상화 되얎 있었Ʞ에 저희는 람닀식윌로썚 메서드륌 읎용할 수 있게 되었닀고 볌 수 있겠습니닀 😊

람닀식은 핚수형 읞터페읎슀륌 구현한 읞슀턎슀!

저희는 람닀식읎 핚수형 읞터페읎슀의 구현첎임을 알게 되었습니닀.
귞런데 핚수형 읞터페읎슀는 추상 메서드가 한 개띌고 섀명드렞었죠!
맀번 핚수형 읞터페읎슀륌 정의핎서 람닀식읎랑 1:1 맀핑시쌜 사용핎알 할까요?

정답은 귞렇지 않닀는 것입니닀 저희는 믞늬 만듀얎진 핚수형 읞터페읎슀륌 읎용할 수 있얎요!
애쎈에 생각핎볎멎 위에서 람닀의 정첎륌 파악하Ʞ 위핎 테슀튞 핎뎀던 Runnable도 저희가 만든 적읎 없죠🀔

믞늬 정의된 읞터페읎슀로 추출되었닀고 읎제는 생각핎볌 수 있겠넀요

잘 만듀얎진 핚수형 읞터페읎슀륌 사용하자!

맀개변수가 있는지, 반환값읎 있는지 등등을 Ʞ쀀윌로 java.util.function팚킀지에 많은 핚수형 읞터페읎슀듀읎 읎믞 만듀얎젞 있답니닀 😊
따띌서 저희가 람닀식을 사용하고자 할때에는 FunctionalInterface륌 직접 만듀얎서 ì“°êž° 볎닀는 잘 곚띌서 ì“°ë©Ž 펞늬핚을 더욱 크게 누멮 수 있겠죠 😎

  • 핚수형 읞터페읎슀 예시 몇가지
핚수형 읞터페읎슀맀개 변수메서드반환값
RunnableXvoid run()X
SupplierXT get()O(T)
ConsumerO(T)void accept(T t)X
PredicateO(T)boolean test(T t)O(boolean)

위에서 직접 읞텔늬제읎에 테슀튞핎볎았던 () -> System.out.println()은 맀개변수도 없고 반환값도 없었Ʞ에 Runnable 핚수형 읞터페읎슀로 추출된 것도 읎제는 알 수 있겠넀요

람닀식 정늬

  • 람닀식의 도입윌로 자바는 핚수륌 음꞉ 객첎로썚 닀룰 수 있는 핚수형 얞얎의 특징도 챙Ʞ게 되었습니닀 🀗
  • 결곌적윌로 윔드륌 간결하게 만듀 수 있윌며 핚수륌 만듀Ʞ 위핎 큎래슀륌 생성하고 메서드륌 정의하는 등의 동작읎 필요 없얎졌Ʞ에 생산성 또한 높아졌넀요
  • 람닀식읎 Functional Interface의 구현첎띌는 것곌 여러 Functional Interface가 믞늬 정의 되얎 있닀는 것을 닀시 한번 Ʞ억하셔알겠습니닀.

Reference

https://velog.io/@reveloper-1311/%EC%9D%BC%EA%B8%89-%EA%B0%9D%EC%B2%B4First-Class-Object%EB%9E%80

https://www.youtube.com/watch?v=4ZtKiSvZNu4

profile
추상볎닀 상섞에 집착하는 개발자 늬비(늬비엔슈)입니닀 🀗

0개의 댓Ꞁ