findFirst().get()
を使用せずに.orElse()
で警告を取り除く方法があることを知りたいNoSuchElementException
。たとえば、次のコードを見てみましょう。
_ List<String> myList = new ArrayList<>();
myList.add("Test");
myList.add("Example");
myList.add("Sth");
String fisrstString = myList.stream().findFirst().get(); // here I surely get "Test"
_
私は他のIDE-sがこれをどのように扱うのかわかりませんが、私のIDE(IntelliJ)はそれを警告('Optional.get()' without 'isPresent()'
)として扱います。いつNoSuchElementException
が得られるのか、いつ得られないのか、またはその理由がわからない。この警告を解決する方法があることは知っている(isPresent()
check、.orElse(something)
)しかし、役に立たないコードでは、単純にそれらのソリューションは必要ないので使用したくないのですが、何ができるのか、IDEによってどのように扱われるのか説明がありますか?
編集: NPEでごめんなさい、そのNoSuchElementException
私はそのエラーがありましたが、質問はまだ利用できると思います。
私にとっては、関数型プログラミングを使用して、オプションで引き続き作業することが最善の方法です。したがって、たとえば、この文字列を何らかのサービスに渡す必要がある場合は、次のことができます。
String fisrstString = myList.stream().findFirst().get();
service.doSomething(fisrstString);
しかし、これはあまり良くありません。代わりに、関数型プログラミングの長所を使用して、以下を実行できます。
myList.stream().findFirst().ifPresent(service::doSomething);
最初にNPE
を取得するのではなく、NoSuchElementException
を取得します。第二に、それはyoだれが確かかもしれません;しかし、他の人々がやって来て、それをwill例外をスローしないことに気付かないかもしれません。
サンドボックスプロジェクトの場合-はい、気にしないで警告を無視できます。量産コードの場合は、無効にすることはできません(できたとしても)。
そして最後のポイントは、あなたがそう確信しているなら、なぜ例外を投げないのかということです。
orElseThrow(IAmSureThisWillNotHappenException::new)
(実際に存在する場合)値を取得しようとする代わりに、findFirst()
によって返されるOptional
を使用する必要があります。
myList.stream()
.findFirst()
.ifPresent(/* consume the string here, if present */);
Optional.ifPresent
メソッドは、[ Consumer
を受け取ります。これは、Optional
にNULL以外の値が含まれる場合にのみ使用されます。
問題は、我々がJava開発者は命令型パラダイムにとても慣れているということです...特に、オブジェクトを取得し、pushingit itメソッドへ:
String myString = "hello"; // getting an object here
System.out.println(myString); // pushing the object to System.out here
// (via the println method)
Stream.findFirst()
によって返されるOptional
を使用すると、上記と同じことをしていました。
String myString = myList.stream()
.findFirst()
.get(); // getting a string here
System.out.println(myString); // pushing the string here
一方、機能パラダイム(Optional
を含む)は通常、他の方法で機能します。
myList.stream()
.findFirst()
.ifPresent(myString -> System.out.println(myString));
ここでは、文字列を取得せずに、それを何らかのメソッドにプッシュします。代わりに、Optional
のifPresent
操作に引数を指定し、Optional
の実装に値を引数にプッシュさせます。つまり、Optional
の引数を使用して、ifPresent
でラップされた値をpullします。 ifPresent
は、値が存在する場合にのみ、このConsumer
引数を使用します。
このプルパターンは関数型プログラミングでよく見られ、慣れると非常に便利です。開発者が別の方法で思考(およびプログラミング)を開始する必要があります。
問題なく空のリストをストリーミングできますが、空のリストの最初の要素を取得しようとするとNoSuchElementExceptionが返されます
stream APIはその問題を認識しているため、複数の方法で処理できます。
Option1:orElse
最初の要素が見つからない場合は「デフォルト」値を返すことができます
String firstString = myList.stream().findFirst().orElse("Ups!");
Option2:orElseGet
を使用できますSupplier<String>
最初の要素が見つからない場合に文字列を返します
firstString = myList.stream().findFirst().orElseGet(mySupplier);
Option:orElseThrow
最初の要素が見つからない場合は例外をスローできます
firstString = myList.stream().findFirst().orElseThrow(WhatTerribleFailException::new);
System.out.println(fisrstString);
[〜#〜] if [〜#〜]Optional
が空にならないことがわかっている場合は、_@SuppressWarnings
_を使用できます以下のような注釈:
_@SuppressWarnings("ConstantConditions") String foo = Optional.of("bar").get();
_
時々_Optional.get
_はNullPointerException
を発生させます。例:
_Optional<String> it = Optional.empty();
String foo = it.get();
// ^--- throws NullPointerException when this method is invoked
_
[〜#〜] so [〜#〜]この式を使用すると、Intellijはwarninging検査。
[〜#〜] if [〜#〜]すべての契約検査を無効にするには、次のアクションを実行できます。Settings->Inspections->Constant condition&exceptions オプション->設定を保存するために、下にあるApplyボタンをクリックすることを忘れないでください。
[〜#〜] if [〜#〜]Optional.get()
警告以外のすべての契約検査を無効にしたくない次のアクションを実行します:Settings->Inspections->一定の条件と例外オプション->右下にOptional.get()
警告を設定するフレームがあります->忘れないでください設定を保存するには、下部のApplyボタンをクリックします。