2017-04-13 1 views
3

나는 목록을 탐색하고 목록을 만드는 방법이 있습니다. 그렇게하는 동안 Result (ResultRassult)를 호출하여 ResultClassException으로 래핑하는 CustomException을 throw합니다. 하지만 처리되지 않은 예외를 말하는 오류가 계속 발생합니다.Java 8 Stream에서 Exception을 처리하는 방법은 무엇입니까?

내 코드 :

private List<Result> getResultList(List<String> results) throws ResultClassException { 
    List<Result> resultList = new ArrayList<>(); 
     results.forEach(
       (resultName) -> { 
        if (!resultRepository.contains(resultName)) { 
         try { 
          final Result result = createResult(resultName); 
          resultList.add(result); 
         } catch (CustomException e) { 
          throw new ResultClassException("Error",e); 
         } 

        } else { 
         resultList.add(resultRepository.get(resultName)); 
         log.info("Result {} already exists.", resultName); 
        } 
       } 
     ); 
     return Collections.unmodifiableList(resultList); 
    } 

은 누군가가 내가 잘못 뭐하는 거지 말할 수 있습니까?

+3

'ResultClassException'이 (가) RuntimeException 또는 ResultRepository.get (resultName)의 하위 클래스가 아니며 체크 예외를 throw합니다. 이 람다는'Consumer' 함수 인터페이스에 해당하지 않기 때문에'forEach'의 람다에서 검사 된 예외를 던질 수 없습니다. –

+2

코드에 스트림이 표시되지 않고 단지 forEach 만 표시됩니다. 왜 보통의 for 루프를 사용하지 않겠습니까? – shmosel

답변

4

당신은 아마 당신의 방법에 너무 많은 책임을 가지고있다. 당신은 그것만을 매핑하는 방법과 그것을 모으는 다른 방법으로 나누는 것에 대해 생각해야합니다.

private List<Result> getResultList(List<String> names) throws ResultClassException { 
    try { 
    return names.stream() 
     .map(this::getOrCreateResult) 
     .collect(collectingAndThen(toList(), Collections::unmodifiableList)); 
    } catch (RuntimeException e) { 
    if (e.getCause() instanceof CustomException) { 
     throw new ResultClassException("Error", e.getCause()); 
    } 
    throw e; 
    // Or use Guava's propagate 
    } 
} 

private Result getOrCreateResult(String name) { 
    if (!resultRepository.contains(name)) { 
    try { 
     return createResult(name); 
    } catch (CustomException e) { 
     throw new RuntimeException(e); 
    } 
    } else { 
    log.info("Result {} already exists.", name); 
    return resultRepository.get(name); 
    } 
} 
0

RuntimeException을 사용하면 코딩 실력이 떨어지게되어서는 안된다. getResultList (...) 호출 메소드에서 ResultClassException을 처리하도록하십시오.

0

Java 8의 람다 식을 사용하면 내부 클래스를 표현할 수 있습니다. 따라서 익명의 내부 클래스에서 예외가 발생합니다. 새 ResultClassException ("Error", e)을 추가 할 곳을 추가하려고합니다.

     Thread.getAllStackTraces() 
          .keySet() 
          .stream() 
          .map(Thread::getStackTrace) 
          .map(Arrays::asList) 
          .forEach(list -> System.out.println(list.stream() 
                    .map(i -> i.toString()) 
                    .collect(Collectors.joining("\n\t")))); 

그리고이를 호출하는 스레드를 참조하십시오. 예외가 람다에서 예상했던 범위를 벗어나는 것을 볼 수 있습니다. 스트림이 많은 스레드를 생성하고 예외가 원하는 스레드의 일부가 아니라는 것을 알 수 있습니다. 당신은 그런 당신의 방법을 포장 할 수 있습니다 Java 8: How do I work with exception throwing methods in streams?

관련 문제