forEach()
람다 식의 가능성을 발견 하기 위해 일부 for-each 루프를 람다 메서드 로 변경하려고합니다 . 다음이 가능한 것 같습니다.
ArrayList<Player> playersOfTeam = new ArrayList<Player>();
for (Player player : players) {
if (player.getTeam().equals(teamName)) {
playersOfTeam.add(player);
}
}
람다와 함께 forEach()
players.forEach(player->{if (player.getTeam().equals(teamName)) {playersOfTeam.add(player);}});
하지만 다음은 작동하지 않습니다.
for (Player player : players) {
if (player.getName().contains(name)) {
return player;
}
}
람다와 함께
players.forEach(player->{if (player.getName().contains(name)) {return player;}});
마지막 줄의 구문에 문제가 있거나 forEach()
메서드 에서 반환 할 수 없습니까?
답변
return
람다 식에서보다는 함유 방법에서이 반환된다. 대신 스트림 forEach
이 필요 filter
합니다.
players.stream().filter(player -> player.getName().contains(name))
.findFirst().orElse(null);
여기 filter
에서는 조건 자와 일치하는 항목으로 스트림을 제한 한 findFirst
다음 Optional
일치하는 첫 번째 항목과 함께 를 반환합니다 .
이는 for-loop 접근 방식보다 덜 효율적으로 보이지만 실제로 findFirst()
단락 될 수 있습니다. 전체 필터링 된 스트림을 생성 한 다음 하나의 요소를 추출하지 않고 필요한만큼의 요소 만 필터링합니다. 첫 번째 일치하는 것을 찾으십시오. (주문 된) 스트림에서 첫 번째 일치하는 플레이어를 가져 오는 데 반드시 신경 쓰지 않고 일치하는 항목 만 있으면 findAny()
대신 사용할 수도 있습니다 . 이렇게하면 병렬 처리가있을 때 효율성이 향상됩니다.findFirst()
답변
먼저 전체 그림에서 Java 8을 이해하려고 시도하는 것이 좋습니다. 가장 중요한 경우에는 스트림, 람다 및 메서드 참조가 될 것입니다.
당신이해야 결코 라인별로 자바 8 코드로 기존의 코드를 변환하지, 당신은 기능을 추출하고 사람들을 변환해야합니다.
귀하의 첫 번째 사례에서 제가 확인한 것은 다음과 같습니다.
- 일부 술어와 일치하는 경우 입력 구조의 요소를 출력 목록에 추가하려고합니다.
어떻게하는지 살펴 보겠습니다. 다음과 같이 할 수 있습니다.
List<Player> playersOfTeam = players.stream()
.filter(player -> player.getTeam().equals(teamName))
.collect(Collectors.toList());
여기서하는 일은 :
- 입력 구조를 스트림으로 바꾸십시오 (여기서는 유형이 있다고 가정
Collection<Player>
하고 이제Stream<Player>
. - 를 사용하여 원하지 않는 모든 요소를 필터링하고
Predicate<Player>
유지하려는 경우 모든 플레이어를 부울 true로 매핑합니다. - 를 통해 목록의 결과 요소를 수집합니다
Collector
. 여기에서 표준 라이브러리 수집기 중 하나 인Collectors.toList()
.
여기에는 다른 두 가지 사항도 포함됩니다.
- 인터페이스에 대한 코드이므로
List<E>
overArrayList<E>
. - 에서 유형 매개 변수에 다이아몬드 추론을 사용하십시오
new ArrayList<>()
. 결국 Java 8을 사용하고 있습니다.
이제 두 번째 요점으로 넘어갑니다.
더 큰 그림을 보지 않고 레거시 Java를 Java 8로 다시 변환하고 싶습니다. 이 부분은 이미 @IanRoberts 에 의해 답변 되었지만 players.stream().filter(...)...
그가 제안한 것을 극복 해야한다고 생각합니다 .
답변
부울 값을 반환하려면 다음과 같이 사용할 수 있습니다 (필터보다 훨씬 빠름).
players.stream().anyMatch(player -> player.getName().contains(name));
답변
이것은 나를 도왔습니다.
List<RepositoryFile> fileList = response.getRepositoryFileList();
RepositoryFile file1 = fileList.stream().filter(f -> f.getName().contains("my-file.txt")).findFirst().orElse(null);
Java 8 에서 가져온 Lambda로 목록에서 특정 요소 찾기
답변
예외를 던질 수도 있습니다.
노트 :
가독성을 위해 스트림의 각 단계를 새 줄에 나열해야합니다.
players.stream()
.filter(player -> player.getName().contains(name))
.findFirst()
.orElseThrow(MyCustomRuntimeException::new);
논리가 느슨하게 “예외 기반”인 경우 (예 : 코드에서 모든 예외를 포착하고 다음에 수행 할 작업을 결정하는 한 위치가있는 경우) 코드베이스를 배수로 흩 뜨리는 것을 피할 수있을 때만 예외 기반 개발을 사용하고 try-catch
이러한 예외를 던지는 것은 예상하고 적절하게 처리 할 수있는 매우 특별한 경우입니다.)