web-dev-qa-db-ja.com

Java 8ストリームで例外を処理する方法は?

リストをトラバースしてリストを作成する方法があります。そうしている間、私はメソッド(createResult)を呼び出して、結果を返し、ResultClassExceptionとしてラップしているCustomExceptionもスローします。しかし、未処理の例外というエラーが表示され続けます。

私のコード:

 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
user3407267

あなたはおそらくあなたの方法であまりにも多くの責任を負っています。マップのみを行うメソッドと、それらを収集するメソッドに分割することを検討する必要があります。

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);
  }
}
6

RuntimeExceptionを使用すると、コーディングの練習が不十分になるため、お勧めしません。 getResultList(...)の呼び出しメソッドでResultClassExceptionを処理してみてください。

1
msuper

Streams内からチェックされた例外を処理することはできません

回避策の1つは、RuntimeExceptionからcreateResultをスローするか、チェックされた例外をキャッチして処理するcreateResultをラップするメソッドを作成することです。

0
santosh-patil

Java 8のラムダ式を使用すると、内部クラスを表すことになります。したがって、例外は匿名の内部クラス内にスローされます。thrownewResultClassException( "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:ストリームで例外スローメソッドを操作するにはどうすればよいですか?

0
strash