사용시 외부 반복 오버 Iterable
우리 사용 break
또는 return
피 각 루프에서와 같은 향상된 :
for (SomeObject obj : someObjects) {
if (some_condition_met) {
break; // or return obj
}
}
Java 8 람다 식에서 내부 반복 을 사용 break
하거나 어떻게 사용할 수 있습니까?return
someObjects.forEach(obj -> {
//what to do here?
})
답변
이것이 필요한 경우을 사용하지 말고 forEach
스트림에서 사용할 수있는 다른 방법 중 하나를 사용하십시오. 어느 것이 목표인지에 달려 있습니다.
예를 들어,이 루프의 목표가 술어와 일치하는 첫 번째 요소를 찾는 것입니다.
Optional<SomeObject> result =
someObjects.stream().filter(obj -> some_condition_met).findFirst();
(참고 : 스트림이 느리게 평가되기 때문에 전체 콜렉션을 반복하지 않습니다. 조건과 일치하는 첫 번째 오브젝트에서 중지됩니다).
컬렉션에 조건이 맞는 요소가 있는지 알고 싶다면 다음을 사용할 수 있습니다 anyMatch
.
boolean result = someObjects.stream().anyMatch(obj -> some_condition_met);
답변
이것은 이다 가능 Iterable.forEach()
(그러나 신뢰성과 Stream.forEach()
). 이 솔루션은 좋은 아니지만, 그것은 이다 가능합니다.
경고 : 비즈니스 로직을 제어하는 데 사용하지 말고 순전히을 실행하는 동안 발생하는 예외 상황을 처리하는 데 사용해야합니다 forEach()
. 리소스가 갑자기 액세스를 중지하는 등 처리 된 개체 중 하나가 계약을 위반하고 있습니다 (예 : 계약에 따르면 스트림의 모든 요소가 null
갑자기 갑자기 예기치 않은 요소 중 하나가되어야 함 null
).
에 대한 문서에 따르면 Iterable.forEach()
:
모든 요소가 처리되거나 조치에서 예외가 발생
Iterable
될 때까지 의 각 요소에 대해 지정된 조치를 수행합니다. 조치에 의해 발생한 예외는 호출자에게 중계됩니다.
따라서 내부 루프를 즉시 중단시키는 예외가 발생합니다.
코드는 다음과 같습니다. 나는 그것을 좋아한다고 말할 수는 없지만 작동합니다. 당신 BreakException
은 확장하는 자신의 클래스 를 만듭니다 RuntimeException
.
try {
someObjects.forEach(obj -> {
// some useful code here
if(some_exceptional_condition_met) {
throw new BreakException();
}
}
}
catch (BreakException e) {
// here you know that your condition has been met at least once
}
(가) 것을 알 수 try...catch
있습니다 하지 않고 주위 전체 주위의 람다 식,하지만 forEach()
방법. 더 잘 보이게하려면 다음 코드를보다 명확하게 보여주는 코드를 참조하십시오.
Consumer<? super SomeObject> action = obj -> {
// some useful code here
if(some_exceptional_condition_met) {
throw new BreakException();
}
});
try {
someObjects.forEach(action);
}
catch (BreakException e) {
// here you know that your condition has been met at least once
}
답변
람다에서의 리턴은 for-each에서의 계속과 동일하지만 휴식과 동등한 것은 없습니다. 계속하려면 반품을 수행하면됩니다.
someObjects.forEach(obj -> {
if (some_condition_met) {
return;
}
})
답변
아래에는 프로젝트에서 사용한 솔루션이 있습니다. 대신 다음 forEach
을 사용하십시오 allMatch
.
someObjects.allMatch(obj -> {
return !some_condition_met;
});
답변
어느 쪽이든 당신은 (대신 휴식을 가지고 있도록) 계속할지 여부를 나타내는 술어를 사용하는 방법을 사용해야 하거나 물론, 아주 추악한 방법 – 당신은 예외를 던질 필요가있다.
따라서 다음 forEachConditional
과 같은 방법을 작성할 수 있습니다 .
public static <T> void forEachConditional(Iterable<T> source,
Predicate<T> action) {
for (T item : source) {
if (!action.test(item)) {
break;
}
}
}
대신에 Predicate<T>
, 일반적인 방법 (a T
를 가져오고 리턴하는 것과 같은)을 사용하여 자신 만의 기능적 인터페이스를 정의하고 싶을 수 bool
있지만 기대를보다 명확하게 나타내는 이름 Predicate<T>
은 여기에 이상적이지 않습니다.
답변
java8 + rxjava를 사용할 수 있습니다 .
//import java.util.stream.IntStream;
//import rx.Observable;
IntStream intStream = IntStream.range(1,10000000);
Observable.from(() -> intStream.iterator())
.takeWhile(n -> n < 10)
.forEach(n-> System.out.println(n));
답변
병렬 작업에서 최대 성능을 얻으 려면 findFirst ()와 유사한 findAny ()를 사용하십시오 .
Optional<SomeObject> result =
someObjects.stream().filter(obj -> some_condition_met).findAny();
그러나 안정적인 결과를 원하면 findFirst ()를 대신 사용하십시오.
또한 일치하는 패턴 (anyMatch () / allMatch)은 부울 만 반환하며 일치하는 객체는 얻지 않습니다.