Java 함수 프로그래밍(6): Optional

개별 요소 선택
직감적으로 말하자면 하나의 원소를 선택하는 것은 여러 개의 원소를 선택하는 것보다 훨씬 간단할 것이다. 그러나 여기에도 문제가 존재한다.우리는 먼저 일반적인 방법의 문제가 무엇인지 본 다음에lambda 표현식으로 그것을 해결하는 방법을 보았다.
특정 알파벳으로 시작하는 요소를 찾아서 인쇄하는 방법을 새로 만듭니다.

public static void pickName(
final List<String> names, final String startingLetter) {
String foundName = null;
for(String name : names) {
if(name.startsWith(startingLetter)) {
foundName = name;
break;
}
}
이 방법은 그야말로 방금 지나간 쓰레기차처럼 악취가 난다.foundName 변수를 새로 만든 다음null로 초기화합니다. 이것이 바로 악취의 근원입니다.비어 있는지 확인해야 합니다. 그렇지 않으면 Null Pointer Exception이나 오류 응답을 던집니다.우리는 또한 외부 교체기를 사용하여 목록을 순환했다. 만약에 원하는 원소를 찾은 후에 이 순환에서 벗어나야 한다면 이것은 원래의 악취를 가중시켰다. 기본 유형의 고집, 명령식 스타일, 가변성, 모두 살아났다.일단 순환을 끝내면, 우리는 먼저 결과를 검사한 후에야 인쇄할 수 있다.이 정도의 임무에 이렇게 긴 코드를 썼다니.
우리 이 문제를 다시 한번 분석해 봅시다.우리는 단지 첫 번째 일치하는 원소를 선택할 수 있고 이러한 원소가 존재하지 않는 상황을 안전하게 처리할 수 있기를 희망할 뿐이다.이 pickName 방법을 lambda 표현식으로 다시 쓰겠습니다.

public static void pickName(
final List<String> names, final String startingLetter) {
final Optional<String> foundName =
names.stream()
.filter(name ->name.startsWith(startingLetter))
.findFirst();
System.out.println(String.format("A name starting with %s: %s",
startingLetter, foundName.orElse("No name found")));
}
JDK의 몇 가지 강력한 기능은 이 코드를 더욱 간결하게 한다.우선 우리는 filter 방법으로 조건을 만족시키는 모든 요소를 얻은 다음에 Stream 클래스의findFirst 방법으로 집합을 되돌리는 첫 번째 요소를 선택했다.이 방법은 Optional 대상을 되돌려줍니다. 이것이 바로 자바에서 공식적으로 인증한 null 변수의 제취제입니다.
Optional 클래스는 매우 유용합니다. 결과가 존재하는지 아닌지는 상관하지 마세요.그것은 우리로 하여금 빈 바늘의 이상한 고민을 면하게 하고, 결과가 없다는 것도 가능한 결과라는 것을 더욱 명확하게 가리킨다.isPresent () 방법을 통해 결과가 존재하는지 알 수 있습니다. 결과 값을 얻으려면 get () 방법을 사용할 수 있습니다.우리는 또한 (이 방법명은 당신을 놀라게 할 수 있다) orElse 방법으로 그것에 기본값을 설정할 수 있다. 마치 앞 코드에 있는 것처럼.
이 PickName 방법을 검증하기 위해 이전에 사용했던 friends 집합을 사용합니다.

pickName(friends, "N");
pickName(friends, "Z");
이 코드는 첫 번째 일치하는 요소를 선택하고 찾지 못하면 우호적인 알림 메시지를 출력합니다.

A name starting with N: Nate
A name starting with Z: No name found
findFirst() 방법과 Optinal 클래스의 결합 사용은 우리의 코드량을 줄이고 보기에 괜찮다.하지만 Optional 클래스의 기능은 이뿐만이 아닙니다.예를 들어 대상이 존재하지 않을 때 기본값을 제공하는 것 외에 결과가 존재하면 코드나 lambda 표현식을 실행할 수 있다.

foundName.ifPresent(name -> System.out.println("Hello " + name));
명령식으로 첫 번째 이름이 일치하는 코드를 선택하는 것보다 흐르는 우아한 함수식 스타일이 더 좋다.그런데 이 호출 흐름의 버전에는 너무 많은 일이 있지 않습니까?물론 아니다. 이런 방법은 매우 지능적이다. 그들은 수요에 따라 일을 할 수 있다. (뒤에 있는 113페이지의 Stream의 타성 구치에서 우리는 이 점을 깊이 있게 연구할 것이다.)
단일 요소를 선택한 예는 JDK 라이브러리의 더 많은 강력한 기능을 보여 줍니다. 다음은 lambda 표현식이 어떻게 하나의 집합에 따라 원하는 값을 구하는지 보겠습니다.

좋은 웹페이지 즐겨찾기