タグ付けされた質問 「java8」

Java 8は、Javaプラットフォームの最新バージョンを指します。

10
従来のヌルポインターチェックの代わりにJava 8以降でOptionalを使用する理由
最近、Java 8に移行しました。今、アプリケーションがOptionalオブジェクトであふれていることがわかります。 Java 8(スタイル1)より前 Employee employee = employeeServive.getEmployee(); if(employee!=null){ System.out.println(employee.getId()); } Java 8(スタイル2)の後 Optional<Employee> employeeOptional = Optional.ofNullable(employeeService.getEmployee()); if(employeeOptional.isPresent()){ Employee employee = employeeOptional.get(); System.out.println(employee.getId()); } Optional<Employee> employeeOptional = employeeService.getEmployee();サービス自体がオプションを返すときの付加価値はありません: Java 6のバックグラウンドから来た私は、スタイル1がより明確で、コードの行が少ないと考えています。ここに欠けている本当の利点はありますか? すべての回答からの理解とブログでのさらなる調査から統合
110 java  java8 

5
抽象クラスが既にあるのに、なぜJava 8のインターフェイスにデフォルトおよび静的メソッドが追加されたのですか?
Java 8では、インターフェイスに実装メソッド、静的メソッド、いわゆる「デフォルト」メソッド(実装クラスがオーバーライドする必要はありません)を含めることができます。 私の(おそらく素朴な)見解では、このようなインターフェースに違反する必要はありませんでした。インターフェイスは常にあなたが満たさなければならない契約であり、これは非常にシンプルで純粋な概念です。今では、いくつかのものが混在しています。私の考えでは: 静的メソッドはインターフェイスに属しません。これらはユーティリティクラスに属します。 「デフォルト」メソッドはインターフェースでまったく許可されるべきではありません。この目的には常に抽象クラスを使用できます。 要するに: Java 8より前: 抽象クラスと通常クラスを使用して、静的メソッドとデフォルトメソッドを提供できます。インターフェイスの役割は明確です。 クラスを実装することにより、インターフェイス内のすべてのメソッドをオーバーライドする必要があります。 すべての実装を変更せずにインターフェイスに新しいメソッドを追加することはできませんが、これは実際には良いことです。 Java 8以降: インターフェースと抽象クラス(多重継承を除く)には実質的に違いはありません。実際、インターフェイスを使用して通常のクラスをエミュレートできます。 実装をプログラミングするとき、プログラマはデフォルトのメソッドをオーバーライドするのを忘れることがあります。 クラスが同じシグネチャを持つデフォルトメソッドを持つ2つ以上のインターフェイスを実装しようとすると、コンパイルエラーが発生します。 インターフェイスにデフォルトのメソッドを追加することにより、実装するすべてのクラスがこの動作を自動的に継承します。これらのクラスの一部は、その新しい機能を念頭に置いて設計されていない可能性があり、これにより問題が発生する可能性があります。たとえば、誰かが新しいデフォルトのメソッドdefault void foo()をinterface Ixに追加すると、同じシグネチャを持つプライベートメソッドをCx実装Ixしているクラスfooはコンパイルされません。 このような大きな変更の主な理由は何ですか?また、追加された新しいメリット(ある場合)は何ですか?

3
引数を取らず、何も返さない関数の名前は何ですか?[閉まっている]
Java 8のjava.util.functionパッケージには、次のものがあります。 機能:1つの引数を取り、1つの結果を生成します。 消費者:1つの引数を取り、何も生成しません。 サプライヤ:引数をとらず、1つの結果を生成します。 ...:プリミティブ、2つの引数などを処理する他のケース... しかし、「引数を取らず、何も生成しない」場合を処理する必要があります。 これには何もありませんjava.util.functionnal。 したがって、質問は次のとおりです。 「引数を取らず、何も返さない関数」の名前は何ですか? Java 8では、その定義は次のようになります。 @FunctionalInterface public interface InsertANameHere { void execute(); } エグゼキューターは既に存在し、別の目的があります:「サブミットされたRunnableタスクを実行するオブジェクト」。署名は一致せず(execute(Runnable):void)、機能的なインターフェースすらありません。 Runnableは存在しますが、スレッドコンテキストに強くリンクされています。 パッケージがあるjava.lang、ありませんjava.util.function。 javadocの状態:「Runnableインターフェイスは、インスタンスがスレッドによって実行されることを意図しているクラスによって実装する必要があります」。 「Runnable」という名前は、スレッド内で実行中のコードを示唆しています。

3
Java 8 java.timeクラスにgetMillis()メソッドがないのはなぜですか?
Java 8には、パッケージjava.timeに日付と時刻のまったく新しいライブラリがあります。これは、以前にJodaTimeを使用したり、独自の日付処理ヘルパーメソッドを作成したりする必要があるユーザーにとって非常に歓迎されるものです。このパッケージの多くのクラスはタイムスタンプを表し、タイムスタンプgetHour()から時間getMinute()を取得する、タイムスタンプから分を取得する、タイムスタンプからナノを取得するなどのヘルパーメソッドを持っていgetNano()ます... getMillis()タイムスタンプのミリ秒を取得するために呼び出されるメソッドがないことに気付きました。代わりに、methodを呼び出す必要がありますget(ChronoField.MILLI_OF_SECOND)。私には、図書館の矛盾のように思えます。そのようなメソッドが欠落している理由を誰かが知っていますか、またはJava 8がまだ開発中であるため、後で追加される可能性がありますか? https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html ここで定義されているクラスは、インスタント、期間、日付、時刻、タイムゾーン、期間など、主要な日時の概念を表しています。これらはISOカレンダーシステムに基づいています。これは、予言的なグレゴリオ暦のルールに基づいた事実上の世界カレンダーです。すべてのクラスは不変であり、スレッドセーフです。 各日時インスタンスは、APIによって便利に利用できるようになっているフィールドで構成されています。フィールドへの低レベルのアクセスについては、java.time.temporalパッケージを参照してください。各クラスには、あらゆる種類の日付と時刻の印刷と解析のサポートが含まれています。java.time.formatカスタマイズオプションについては、パッケージを参照してください... この種類のクラスの例:https : //docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html 2007-12-03T10:15:30など、ISO-8601カレンダーシステムのタイムゾーンのない日時。 LocalDateTimeは、日時を表す不変の日時オブジェクトであり、多くの場合、年月日日時分秒として表示されます。年間通算日、曜日、通年など、他の日付および時刻フィールドにもアクセスできます。時間はナノ秒の精度で表されます。たとえば、「2007年10月2日13:45.30.123456789」という値は、LocalDateTime...
64 java  java8 

3
Java 8でラムダ構文の代わりにメソッド参照構文を使用すると、パフォーマンス上の利点はありますか?
メソッド参照はラムダラッパーのオーバーヘッドをスキップしますか?将来的にはそうなるのでしょうか? メソッド参照に関するJavaチュートリアルによると: 時々...ラムダ式は既存のメソッドを呼び出すだけです。これらの場合、既存のメソッドを名前で参照する方が明確な場合がよくあります。メソッド参照により、これを行うことができます。これらは、既に名前を持っているメソッドのコンパクトで読みやすいラムダ式です。 いくつかの理由から、メソッド参照構文よりもラムダ構文の方が好きです。 ラムダはより明確です Oracleの主張にもかかわらず、メソッド参照構文があいまいであるため、ラムダ構文はオブジェクトメソッド参照の速記より読みやすいと思います。 Bar::foo xのクラスで静的な1引数のメソッドを呼び出してxを渡しますか? x -> Bar.foo(x) または、xで引数のないインスタンスメソッドを呼び出していますか? x -> x.foo() メソッド参照構文は、どちらの代わりにもなります。コードが実際に行っていることを隠します。 ラムダはより安全です クラスメソッドとしてBar :: fooを参照し、Barが後で同じ名前のインスタンスメソッドを追加した場合(またはその逆)、コードはコンパイルされなくなります。 ラムダを一貫して使用できます 任意の関数をラムダでラップできます。そのため、どこでも同じ構文を一貫して使用できます。メソッド参照構文は、プリミティブ配列を取得または返すメソッド、チェックされた例外をスローするメソッド、またはインスタンスと静的メソッドとして使用されるメソッド名が同じメソッドでは機能しません(メソッド参照構文が呼び出されるメソッドについて曖昧だからです) 。同じ数の引数を持つメソッドをオーバーロードした場合は機能しませんが、とにかくそれを行うべきではないため(Josh Blochの項目41を参照)、メソッド参照に対してそれを保持することはできません。 結論 パフォーマンスの低下がない場合は、IDEで警告をオフにし、メソッド参照をコードに散在させることなくラムダ構文を一貫して使用したいと思います。 PS ここでもそこでもありませんが、私の夢では、オブジェクトメソッドの参照は次のように見え、ラムダラッパーなしでメソッドに対してinvoke-dynamicを直接適用します。 _.foo()

6
Javaチェック例外の回避策
ラムダとデフォルトのメソッドインターフェースに関する新しいJava 8の機能に感謝します。それでも、私はまだチェックされた例外に飽きています。たとえば、オブジェクトのすべての表示フィールドを一覧表示するだけの場合は、単に次のように記述します。 Arrays.asList(p.getClass().getFields()).forEach( f -> System.out.println(f.get(p)) ); ただし、getメソッドはConsumerインターフェイスコントラクトに同意しないチェック例外をスローする可能性があるため、その例外をキャッチして次のコードを記述する必要があります。 Arrays.asList(p.getClass().getFields()).forEach( f -> { try { System.out.println(f.get(p)); } catch (IllegalArgumentException | IllegalAccessException ex) { throw new RuntimeException(ex); } } ); ただし、ほとんどの場合、例外をaとしてスローし、RuntimeExceptionコンパイルエラーなしで例外をプログラムに処理させるかどうかを許可します。 それで、私はチェックされた例外の迷惑のための私の物議を醸す回避策についてあなたの意見を持ちたいです。そのために、次のように補助インターフェイスConsumerCheckException<T>とユーティリティ関数rethrow(Dovalのコメントの推測に応じて更新)を作成しました。 @FunctionalInterface public interface ConsumerCheckException<T>{ void accept(T elem) throws Exception; } public class Wrappers { public static <T> Consumer<T> rethrow(ConsumerCheckException<T> c) …

3
forループの代わりに「機能的操作」を使用する必要があるのはなぜですか?
for (Canvas canvas : list) { } NetBeansは、「機能的操作」を使用することを提案しています。 list.stream().forEach((canvas) -> { }); しかし、なぜこれが好ましいのでしょうか?どちらかといえば、読みやすく、理解しにくいです。を呼び出してからstream()、forEach()パラメーター付きのラムダ式を使用していますcanvas。for最初のスニペットのループよりも優れていることはわかりません。 明らかに、私は美学だけについて話している。おそらく、ここには技術的な利点がありますが、私には欠けています。それは何ですか?代わりに2番目の方法を使用する必要があるのはなぜですか?

3
peek()を使用してストリーム要素を変更するのはアンチパターンですか?
モノのストリームがあり、それらを途中で「強化」したい場合peek()、これを行うために使用できます。たとえば: streamOfThings.peek(this::thingMutator).forEach(this::someConsumer); コードのこの時点でthingMutatorモノを変更することは正しい動作であると仮定します。たとえば、メソッドは「lastProcessed」フィールドを現在の時間に設定できます。 ただし、peek()ほとんどのコンテキストでは、「見て、触れないでください」という意味です。 ストリーム要素の突然変異にアンチパターンを使用peek()していますか? 編集: より一般的な代替アプローチは、消費者を変換することです。 private void thingMutator(Thing thing) { thing.setLastProcessed(System.currentTimeMillis()); } パラメータを返す関数に: private Thing thingMutator(Thing thing) { thing.setLastProcessed(currentTimeMillis()); return thing; } map()代わりに使用します: stream.map(this::thingMutator)... しかし、それは機能的なコード(return)を導入しpeek()、同じオブジェクトを返すことを知っているので、それがより明確であるとは確信していませんがmap()、同じクラスのオブジェクトであることは一目でさえわかりません。 さらに、peek()あなたは突然変異するラムダを持つことができmap()ますが、列車の残骸を構築する必要があります。比較する: stream.peek(t -> t.setLastProcessed(currentTimeMillis())).forEach(...) stream.map(t -> {t.setLastProcessed(currentTimeMillis()); return t;}).forEach(...) 私は思うpeek()ので、何の「神秘的」副作用はありません、バージョンが明確で、かつラムダは明らかに変異されます。同様に、メソッド参照が使用され、メソッドの名前が明らかに突然変異を暗示している場合、それも明確で明白です。 個人的には、peek()突然変異に使うことをためらわない-非常に便利だと思う。

1
Java 8の型推論
Java 8 での新しいラムダ表記(たとえば、この記事を参照)の導入には、ある種の型推論が必要になりますか? もしそうなら、新しい型システムはJava言語全体にどのような影響を与えますか?

9
変数をnullチェックするよりも優先的にオプションを使用するのはなぜですか?
2つのコード例を取り上げます。 if(optional.isPresent()) { //do your thing } if(variable != null) { //do your thing } 私の知る限り、最も明らかな違いは、オプションでは追加のオブジェクトを作成する必要があるということです。 ただし、多くの人がオプションを急速に採用し始めています。オプションを使用する場合とnullチェックを使用する場合の利点は何ですか?
25 java  java8 

3
isPresent()を呼び出さずにOptional.get()が悪いのに、iterator.next()が悪いのはなぜですか?
新しいJava8ストリームAPIを使用してコレクション内の特定の要素を検索する場合、次のようなコードを記述します。 String theFirstString = myCollection.stream() .findFirst() .get(); ここで、IntelliJは、isPresent()を最初にチェックせずにget()が呼び出されることを警告しています。 ただし、このコード: String theFirstString = myCollection.iterator().next(); ...警告は表示されません。 ストリーミングアプローチを何らかの方法でより「危険」にし、最初にisPresent()を呼び出さずにget()を呼び出さないことが重要であるという2つの手法の間に大きな違いがありますか?いろいろと調べてみると、Optional <>でプログラマーが不注意である方法についての記事を見つけ、いつでもget()を呼び出すことができると仮定しています。 つまり、コードがバグのある場所にできるだけ近い場所で例外をスローするのが好きです。この場合は、要素が見つからないときにget()を呼び出しています。次のような役に立たないエッセイを書く必要はありません。 Optional<String> firstStream = myCollection.stream() .findFirst(); if (!firstStream.isPresent()) { throw new IllegalStateException("There is no first string even though I totally expected there to be! <sarcasm>This exception is much more useful than NoSuchElementException</sarcasm>"); } String …
23 java8 

1
Java 8コードの条件付きカバレッジを測定するのは理にかなっていますか?
Java 8が登場して以来、現在のJava用ツールによる条件付きコードカバレッジの測定は時代遅れではないのかと思っています。Javaの8のではOptionalとStream私たちはしばしば、それが簡単にすべての可能な実行パスをテストすることなく、非常に高い条件カバレッジを取得することができますコード分岐/ループを回避することができます。古いJavaコードとJava 8コードを比較してみましょう。 Java 8より前: public String getName(User user) { if (user != null) { if (user.getName() != null) { return user.getName(); } } return "unknown"; } 上記のメソッドには3つの実行パスがあります。条件付きカバレッジを100%取得するには、3つの単体テストを作成する必要があります。 Java 8: public String getName(User user) { return Optional.ofNullable(user) .map(User::getName) .orElse("unknown"); } この場合、ブランチは非表示になり、100%のカバレッジを得るために必要なテストは1つだけで、テストするケースは関係ありません。カバーすべき3つの論理ブランチはまだありますが、信じています。最近の条件付きカバレッジ統計は完全に信頼できないものになっていると思います。 Java 8コードの条件付きカバレッジを測定するのは理にかなっていますか?十分にテストされていないコードを発見する他のツールはありますか?

3
コレクションを通常返す場所にストリームを返すのは正気ですか?
レガシーコードに関連付けられていないAPIを開発しているとき、結果を収集することで純粋にStreamsパイプラインで終了するメソッドを作成していることがよくあります。このように: ImmutableSet<T> deriveSomethingMeaningfulFromPrivateState() { return myPrivateThingies.stream() .map(this::ownerOfThing) .map(Owner::socialStatus) .filter(SocialStatus::isHeAFineMatey) .collect(MyCustomCollectors.toImmutableSet()); } さて、このクラスのほとんどのクライアントは通常、要素を検索してそれを反復処理するためにコレクション(この場合はImmutableSet)を必要としますが、一部のクライアントはその上にいくつかの操作をパイプできるようにストリームを持つことで利益を得ることができますコレクションから新しいストリームを取得する必要のないストリーム。したがって、ストリームを返すと、コレクションを持っている場合のオプションのスーパーセットがクライアントに提供されます(結局、常にcollect()ストリーム自体を使用できます: Stream<T> deriveSomethingMeaningfulFromPrivateState() { return myPrivateThingies.stream() .map(this::ownerOfthing) .map(Owner::socialStatus) .filter(SocialStatus::isHeAFineMatey); // No collect } このアプローチは、潜在的な欠陥が見当たらないため、試してみたいと思います。しかし、どのライブラリでもこのアプローチを見たことはありません(おそらく、Java 8の登場後にリリースされたライブラリが多くなかったためです)。既存のライブラリクラスは、通常、プライベート状態から何かを派生するときにコレクションを返します。 Java 8より前の自分がコレクションを返す場所にストリームを返すことにした場合に発生する可能性のある悪いことがありますか?または、私はここで私的状態から派生したすべてのものでアンチパターンの何かをしていますか?

1
Scala関数をJava 8メソッドに渡す
次のScalaコードは機能し、関数を必要とするJavaメソッドに渡すことができます。これを行うよりクリーンな方法はありますか?これが私の最初のパスです。 val plusOne = new java.util.function.Function[Int,Int] { override def apply(t:Int):Int = t + 1 override def andThen[V](after:function.Function[_ >: Int, _ <: V]): function.Function[Int, V] = ??? override def compose[V](before:function.Function[_ >: V, _ <: Int]): function.Function[V, Int] = ??? } 2番目のパスは次のとおりです。Java-8Functionインターフェイスの汎用ラッパーを使用して、Scalaの構文を簡素化します。 // Note: Function1 is Scala's functional interface, // Function (without …

1
Collection.stream()。filter()。forEach()は、各ループの標準と比較して非効率ですか?
IntelliJ IDEAは、次のfor-eachループをJava 8の "forEach"呼び出しに置き換えるために、今私に勧めました: for (Object o : objects) { if (o instanceof SomeObject) { doSomething(); } } 推奨される呼び出しは次のようになります。 objects.stream().filter(o -> o instanceof SomeObject).forEach(o -> doSomething()); Streamの基本的な機能がどのように機能するかを誤解していない限り、streamの使用は標準のfor-eachループのO(n)操作ではなくO(2n)操作であるように思われます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.