단일 요소 선택
직관적으로 단일 요소를 선택하는 것은 여러 요소를 선택하는 것보다 확실히 쉽지만 여기에는 몇 가지 문제가 있습니다. 먼저 일반적인 접근 방식의 문제점이 무엇인지 살펴본 다음, 이를 해결하기 위해 람다 표현식을 사용하는 방법을 살펴보겠습니다.
먼저 특정 문자로 시작하는 요소를 찾는 새 메서드를 만든 다음 인쇄해 보겠습니다.
다음과 같이 코드 코드를 복사합니다.
공개 정적 무효 pickName(
final List<String> 이름, final String StartingLetter) {
문자열 발견이름 = null;
for(문자열 이름 : 이름) {
if(name.startsWith(startingLetter)) {
발견이름 = 이름;
부서지다;
}
}
이 방법은 방금 지나간 쓰레기차처럼 냄새가 납니다. 먼저 새foundName 변수를 만든 다음 이를 null로 초기화했습니다. 이것이 악취의 원인입니다. null인지 확인해야 합니다. 그렇지 않으면 NullPointerException 또는 오류 응답이 발생합니다. 또한 목록을 반복하기 위해 외부 반복자를 사용합니다. 원하는 요소를 찾으면 루프에서 벗어나야 합니다. 이는 기본 유형 편집증, 명령형 스타일, 가변성 등 모두 살아납니다. 루프를 종료하면 인쇄하기 전에 결과를 확인해야 합니다. 이러한 작은 작업에는 실제로 긴 코드가 필요합니다.
이 문제를 다시 분석해 보겠습니다. 우리는 일치하는 첫 번째 요소를 선택하고 그러한 요소가 존재하지 않는 경우를 안전하게 처리할 수 있기를 원합니다. 람다 표현식을 사용하여 이 pickName 메서드를 다시 작성해 보겠습니다.
다음과 같이 코드 코드를 복사합니다.
공개 정적 무효 pickName(
final List<String> 이름, final String StartingLetter) {
final Optional<String>foundName =
이름.스트림()
.filter(이름 ->name.startsWith(startingLetter))
.findFirst();
System.out.println(String.format("%s로 시작하는 이름: %s",
StartingLetter,foundName.orElse("이름을 찾을 수 없습니다.")));
}
JDK의 일부 강력한 기능은 이 코드를 매우 간결하게 만듭니다. 먼저 필터 메소드를 사용하여 조건을 충족하는 모든 요소를 얻은 다음 Stream 클래스의 findFirst 메소드를 사용하여 반환된 컬렉션의 첫 번째 요소를 선택합니다. 이 메소드는 Java의 널 변수에 대해 공식적으로 인증된 탈취제인 Optional 객체를 반환합니다.
Optional 클래스는 매우 유용하므로 결과가 존재하는지 여부에 대해 걱정할 필요가 없습니다. 이는 널 포인터 예외 문제로부터 우리를 구하고 결과가 있을 수 없다는 점을 더 명확하게 해줍니다. isPresent() 메소드를 통해 결과가 존재하는지 알 수 있습니다. 결과 값을 얻으려면 get() 메소드를 사용할 수 있습니다. 이전 코드와 마찬가지로 orElse 메소드를 사용하여 기본값을 설정할 수도 있습니다(이 메소드의 이름을 보면 충격을 받을 것입니다).
우리는 pickName 메소드를 검증하기 위해 이전에 사용했던 친구 컬렉션을 사용합니다.
다음과 같이 코드 코드를 복사합니다.
pickName(친구, "N");
pickName(친구, "Z");
이 코드는 일치하는 첫 번째 요소를 선택하고 해당 요소를 찾을 수 없으면 친숙한 메시지를 인쇄합니다.
다음과 같이 코드 코드를 복사합니다.
N으로 시작하는 이름 : 네이트
Z로 시작하는 이름: 이름을 찾을 수 없습니다.
findFirst() 메소드와 Optinal 클래스의 조합은 코드 양을 줄여 보기 좋게 보입니다. 그러나 Optional 클래스의 기능은 그 이상입니다. 예를 들어 객체가 존재하지 않을 때 기본값을 제공하는 것 외에도 이를 사용하여 다음과 같이 코드 조각이나 람다 표현식(결과가 있는 경우)을 실행할 수도 있습니다.
다음과 같이 코드 코드를 복사합니다.
foundName.ifPresent(이름 -> System.out.println("안녕하세요 " + 이름));
첫 번째로 일치하는 이름을 선택하는 명령형 코드와 비교하면 흐름의 우아한 기능적 스타일이 더 좋아 보입니다. 하지만 이 버전의 통화 흐름에는 할 일이 너무 많습니까? 물론 그렇지 않습니다. 이러한 방법은 매우 똑똑하고 필요에 따라 작동합니다(113페이지의 스트림의 지연 평가에서 이에 대해 자세히 살펴볼 것입니다).
단일 요소를 선택하는 예는 JDK 라이브러리의 더욱 강력한 기능을 보여줍니다. 람다 표현식이 컬렉션을 기반으로 원하는 값을 찾는 방법을 살펴보겠습니다.