ホームページ  >  記事  >  Java  >  オプションのクラス、Java 8 の新機能

オプションのクラス、Java 8 の新機能

黄舟
黄舟オリジナル
2017-02-23 10:30:321880ブラウズ

要約: Optional は null キーワードの代替ではありませんが、null 判定のより洗練された実装を提供します

NullPointException は、Java が最初から設計されていないにもかかわらず、すべての Java プログラマーが遭遇する例外であると言えます。私たちはプログラマをポインタの苦痛から解放しようとしましたが、ポインタは実際に存在し、Java 設計者は Java 言語でポインタをよりシンプルで使いやすくすることしかできませんが、ポインタを完全に排除することはできません。そのため、キーワード

null

があるのです。私たちが毎日目にしているもの。

Null ポインター例外は実行時例外です。明確な処理戦略がない場合、ベスト プラクティスはプログラムを早期にハングアップさせることです。ただし、多くのシナリオでは、開発者はそうしません。特定の処理戦略はありませんが、null ポインター例外の存在をまったく認識しません。例外が発生した場合の処理​​戦略も、例外が存在する箇所に if ステートメントの判定を追加するだけで十分です。ただし、このような応答戦略では、プログラム内でより多くの null 判定が発生することになります。コード内の null キーワードの出現を最小限に抑える必要があり、java8 によって提供される

Optional

クラスは、NullPointException を減らすだけでなく、コードの美しさを向上させます。ただし、最初に、これは

null
キーワードの代替ではなく、NullPointException を回避するための null 判定のより洗練された実装を提供するものであることを明確にする必要があります。

1. 直感的なエクスペリエンス

サードパーティのツールクラスを使用しない場合、

if(null ==) メソッドを呼び出す必要があるとします。 str) { // Null ポインタを決定する

return 0;
}
return str.length();
Optional クラスを使用する場合、実装は次のようになります:

return Optional.ofNullable(str).map(String: :length).orElse(0);
Optional コードは比較的簡潔ですが、コード量が多いとnull判定を忘れてしまいがちですが、Optionalクラスを使うことでそのような問題を回避できます。



2. 基本的な使用方法

1. オブジェクトの作成

Optionalf7e83be87db5cd2d9a8a0b8117b38cd4 optStr = Optional.empty();

上記のコード例は、

str.length()
メソッドを呼び出します。空の
empty()

オブジェクトタイプ。

オブジェクトの作成: 空にすることはできません

オプションは、空でないオブジェクトを作成するためのメソッド

Optional<String>

を提供します。このメソッドでは、渡されるパラメーターを空にすることができません。それ以外の場合は、
of()
がスローされます。次のように:

Optional< ;String> optStr = Optional.of(str); // str が null の場合、NullPointException がスローされます

オブジェクトを作成します: 空であることが許可されます


渡されたパラメータは null 値の可能性があるため、Optional の

NullPointException

メソッドを使用してオブジェクトを作成できます。入力パラメータが null の場合は、空のオブジェクトが作成されます。例は次のとおりです: Optionalf7e83be87db5cd2d9a8a0b8117b38cd4 optStr = Optional.ofNullable(str); // str が null の場合、ストリーミング処理

2. ストリーミング処理も java8 によって提供されます。コレクションをより簡潔かつ効率的に操作できるようにする強力な新機能 Java 8 の新機能に関する次の記事では、チャーン処理について包括的に説明します。ここではオプションで、マッピングとフィルタリングという 2 つの基本的なチャーン処理も提供します。

デモンストレーションのために、次のような

ofNullable()

クラスを設計しました:

User

携帯電話と電子メールは個人には必要ないため、オプションの定義を使用します。



マッピング: マップと flatMap


マッピングは、入力を別の形式の出力に変換する操作です。たとえば、前の例では、文字列を入力し、その文字列の長さを出力します。シュート、これを達成するために

/**
 * @author: zhenchao.Wang 2016-9-24 15:36:56
 */
public class User {
    /** 用户编号 */
    private long id;
    private String name;
    private int age;
    private Optional phone;
    private Optional<String> email;
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
    // 省略setter和getter
}

メソッドを使用します。人の名前を取得したいとすると、次のように実装できます:

String name = Optional.ofNullable(user).map(User::getName).orElse("no name");このように、入力パラメータ user が空でない場合、その名前が返され、それ以外の場合は

map()

が返されます。 上記のメソッドを通じて電話やメールを取得したい場合、map の後に返されるものは次のとおりであるため、上記のメソッドは機能しません。オプションで、これをオプションのネストと呼びます。必要な結果を取得するには、一度マップする必要があります:

longphone = optUser.map(User::getPhone).map(Optional::get).orElse(-1L);

In実際、現時点では、 flatMap を使用して 1 ステップで必要な結果を取得する方が良い方法です:


long Phone = optUser. flatMap(User::getPhone).orElse(-1L);
flapMap は各ストリームをフラット化できますストリームになるメソッドによって返されます。これについては、ストリーミング処理に特化した次の記事で詳しく説明します。

フィルター: filterer

filter は、名前が示すように、18 歳以上の成人をフィルターする目的を達成するためにフィルター操作をパラメーターとしてこのメ​​ソッドに渡すことができます。 3. デフォルトの動作


デフォルトの動作は、上記の例で使用したような条件を満たさない場合に実行される操作です

orElse()

就是一个默认操作,用于在Optional对象为空时执行特定操作,当然也有一些默认操作是当满足条件的对象存在时执行的操作。

get()

get用于获取变量的值,但是当变量不存在时则会抛出

NoSuchElementException

,所以如果不确定变量是否存在,则不建议使用

orElse(T other)

当Optional的变量不满足给定条件时,则执行orElse,比如前面当str为null时,返回0。

orElseGet(Supplier<? extends X> expectionSupplier)

如果条件不成立时,需要执行相对复杂的逻辑,而不是简单的返回操作,则可以使用orElseGet实现:

long phone = optUser.map(User::getPhone).map(Optional::get).orElseGet(() -> {
    // do something here
    return -1L;
});
orElseThrow(Supplier<? extends X> expectionSupplier)

与get()方法类似,都是在不满足条件时返回异常,不过这里我们可以指定返回的异常类型。

ifPresent(Consumer117c5a0bdb71ea9a9d0c2b99b03abe3e)

当满足条件时执行传入的参数化操作。

三. 注意事项

Optional是一个final类,未实现任何接口,所以当我们在利用该类包装定义类的属性的时候,如果我们定义的类有序列化的需求,那么因为Optional没有实现Serializable接口,这个时候执行序列化操作就会有问题:

public class User implements Serializable{
    /** 用户编号 */
    private long id;
    private String name;
    private int age;
    private Optional phone;  // 不能序列化
    private Optional<String> email;  // 不能序列化

不过我们可以采用如下替换策略:

private long phone;
public Optional<Long> getPhone() {
    return Optional.ofNullable(this.phone);
}

看来Optional在设计的时候就没有考虑将它作为类的字段使用~

 以上就是Java8 新特性之 Optional 类 的内容,更多相关内容请关注PHP中文网(www.php.cn)!

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。