1. 概要

この短いチュートリアルでは、2つのLongインスタンスを比較するさまざまな方法について説明します。 参照比較演算子( == )を使用するときに発生する問題を強調します。

2. 参照比較の使用に関する問題

Long は、プリミティブ型longラッパークラスです。 これらはオブジェクトであり、プリミティブ値ではないため、参照比較演算子(==)の代わりに.equals()を使用してLongインスタンスのコンテンツを比較する必要があります。

場合によっては、==は大丈夫だと思われるかもしれませんが、見た目はだまされています。 低い数値で==を使用できると考えてください。

Long l1 = 127L;
Long l2 = 127L;

assertThat(l1 == l2).isTrue();

ただし、数値が大きい場合はそうではありません。 値が-128〜127の範囲外の場合、で問題が発生し、でまったく異なる予期しない結果が発生します。

Long l1 = 128L;
Long l2 = 128L;

assertThat(l1 == l2).isFalse();

それの訳は Javaは、Longのインスタンスに対して-128から127の間の一定のプールを維持します。

ただし、この最適化では、==を使用するためのライセンスは提供されません。 一般的なケースでは、同じプリミティブ値を持つ2つのボックス化されたインスタンスは、同じオブジェクト参照を生成しません。

3. .equals()を使用する

解決策の1つは、 .equals()を使用することです。 これにより、両方のオブジェクトのコンテンツ(参照ではない)が評価されます。

Long l1 = 128L;
Long l2 = 128L;

assertThat(l1.equals(l2)).isTrue();

4. Objects.equals()

equals()を使用する場合の問題は、null参照で呼び出さないように注意する必要があることです。

幸いなことに、使用できる nullセーフユーティリティメソッド– Objects.equals()。があります。

それが実際にどのように機能するか見てみましょう:

Long l1 = null;
Long l2 = 128L;

assertThatCode(() -> Objects.equals(l1, l2)).doesNotThrowAnyException();

ご覧のとおり、比較するLongのいずれかがnullであるかどうかを気にする必要はありません。

内部的には、 Objects.equals()は最初に==演算子を使用して比較し、それが失敗した場合は標準の equals()。を使用します。

5. 長い値の開梱

5.1. .longValue()メソッドの使用

次に、「==」比較演算子を使用しますが、安全な方法です。 クラスNumberには、プリミティブ long値をアンラップするメソッド.longValue()があります。

Long l1 = 128L;
Long l2 = 128L;

assertThat(l1.longValue() == l2.longValue()).isTrue();

5.2. プリミティブ値へのキャスト

Long のボックスを解除する別の方法は、オブジェクトをプリミティブタイプにキャストすることです。 したがって、プリミティブ値を抽出してから、比較演算子の使用に進むことができます。

Long l1 = 128L;
Long l2 = 128L;

assertThat((long) l1 == (long) l2).isTrue();

.longValue()メソッドの場合、またはキャストを使用する場合は、オブジェクトがnullかどうかを確認する必要があります。オブジェクトが null の場合、NullPointerExceptionが発生する可能性があります。 ]。

6. 結論

この短いチュートリアルでは、長いオブジェクトを比較する方法に関するさまざまなオプションを検討しました。オブジェクトまたはコンテンツへの参照を比較するときの違いを分析しました。

いつものように、記事の完全なソースコードは、GitHubから入手できます。