2016-07-25 2 views
3

그래서 저는 Optionals와 함께 일하고 이상한 행동을 보았습니다. 나는 이것이 정말로 intendet "feature"인지 아니면 ... something ...인지 알기를 원한다. ...orElse- 분기 옵션에서 예외가 발생합니다.

여기에 주어진 예가있다. 나는 orElse가있는 orElse의 Option을 가진 메소드를 가지고있다. 기타 선택 사항. 다른 옵션이없는 경우, 나는 IllegalArgumentException을 올릴 수 있습니다 :

firstOptionalVar.orElse(secondOptionalVar.orElseThrow(IllegalArgumentException::new)); 

는 이제 secondOptionalVar는 선택 사항 비어는 IllegalArgumentException을 올릴 경우, firstOptionalVar이 존재하는 경우에도 마찬가지입니다. 이것은 나에게 맞는 것 같지 않다. firstOptionalVar이 존재하지 않으면 IllegalArgumentException을 발생시킬 것으로 예상됩니다.

이 같은 java7-방법과이 동작을 arround 얻을 수있는 큰 문제는 아니다 : 다른 사람이 전에이 문제를 경험 한

firstOptionalVar.isPresent() ? firstOptionalVar.get() : secondOptionalVar.orElseThrow(IllegalArgumentException::new); 

? 이것은 정말로 선택자가 행동해야하는 방식입니까?

+0

'flatMap'은 불행히도 그 반대입니다. – biziclop

+2

예외에 대한 anwer는 연결된 질문 또는 사용자가 얻은 대답에서 찾을 수 있습니다. 수행 할 "or"작업은 Java 9에서 사용할 수 있습니다. http://stackoverflow.com/questions/24599996/get-value-from-one-optional-or-another – Tunaki

+0

답변 해 주셔서 감사합니다. @resueman의 해결책은 나를 위해 작동하지만 java9가이 경우를 처리하는 방법을 알고있는 것이 좋습니다. – Numbernick

답변

6

이것은 의도 한 동작입니다. orElseorElseThrow. Optional의 일반적인 유형이 어떤 유형 T (의 인수를 예상하는 T를 반환, 그래서 orElse에 매개 변수를 전달하기 위해, 먼저 평가해야합니다. 당신이 원하는 무엇

orElseGet, 인 .. Supplier<T> 소요 그 firstOptionalVar이 이미 확인 된 후까지 orElseThrow의 실행을 지연합니다

을 그래서 코드는 다음과 같아야합니다

firstOptionalVar.orElseGet(() -> secondOptionalVar.orElseThrow(IllegalArgumentException::new)); 

그러면 orElseThrow 섹션이 람다로 바뀌며 필요한 경우에만 평가됩니다 (예 : firstOptionalVar에 얻을 값이 없을 때).

+2

좋은 점. 이것이 내가 알아 내려고 노력한 해결책입니다. :) – biziclop

+1

고맙습니다. 그게 바로 제가 찾던 것입니다. – Numbernick

3

모든면에서 Java 메소드 만 호출하므로 Java 표준 평가 순서가 적용됩니다.

구체적 : secondOptionalVar.orElseThrow(IllegalArgumentException::new)firstOptionalVar.orElse()의 인자를 제공하기 때문에, firstOptionalVar.orElse() 전에 통화를 평가한다.

Optional의 표준 방법으로이 문제를 해결할 수있는 쉬운 방법이 보이지 않습니다. 두 옵션 중에서 스트림을 빌드하고 첫 번째 요소를 가져 오거나 예외를 throw 할 수 있지만 비트가 복잡해 보입니다.

관련 문제