Comparing Long Values in Java – 在Java中比较长值

最后修改: 2020年 3月 29日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this short tutorial, we’ll discuss different ways to compare two Long instances. We emphasize the problems that arise when using the reference comparison operator (==).

在这个简短的教程中,我们将讨论比较两个Long实例的不同方法。我们强调使用引用比较运算符(==)时出现的问题。

2. Problem Using Reference Comparison

2.使用参照物比较的问题

Long is a wrapper class for the primitive type long. Since they are objects and not primitive values, we need to compare the content of Long instances using .equals() instead of the reference comparison operator (==).

Long是原始类型long包装器类。由于它们是对象而不是原始值,我们需要使用.equals()来比较Long实例的内容,而不是使用引用比较操作符(==)。

In some cases, we may get the idea that == is okay, but looks are deceiving. Consider that we can use == with low numbers:

在某些情况下,我们可能会认为==是可以的,但外观是骗人的。考虑到我们可以用==来处理低数字。

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

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

but not with larger numbers. We would end up having issues if values are out of the range -128 to 127, having a completely different and unexpected result:

但对更大的数字则不然。我们最终会出现问题如果数值超出了-128到127的范围,就会出现完全不同的意外结果。

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

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

This is because Java maintains a constant pool for instances of Long between -128 and 127.

这是因为Java为-128和127之间的Long实例维护了一个恒定的池。

This optimization, though, does not give us a license to use ==. In the general case, two boxed instances having the same primitive value don’t yield the same object reference.

但是,这种优化并没有给我们使用==的许可。 在一般情况下,两个boxed instances具有相同的基元值,不会产生相同的对象引用。

3. Using .equals()

3.使用.equals()

One of the solutions is to use the .equals(). This will evaluate the content (and not the reference) of both objects:

其中一个解决方案是使用.equals()/a>。这将评估两个对象的内容(而不是引用)。

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

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

4. Objects.equals()

4.Objects.equals()

The problem with using equals() is that we need to be cautious not to call it on the null reference.

使用equals()的问题是,我们需要谨慎,不要在null引用上调用它。

Luckily, there’s a null-safe utility method we can use – Objects.equals().

幸运的是,有一个安全的实用方法,我们可以使用 – Objects.equals()

Let’s see how it works in practice:

让我们看看它在实践中如何运作。

Long l1 = null;
Long l2 = 128L;

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

As we can see, we don’t need to bother if any of the Longs we want to compare is null.

正如我们所看到的,如果我们想要比较的任何一个Longs是null.,我们不需要理会。

Under the hood, Objects.equals() first uses the == operator for the comparison, and if that fails it uses a standard equals().

在引擎盖下,Objects.equals()首先使用==运算符进行比较,如果失败,则使用标准的equals()

5. Unboxing Long Values

5.开箱长值

5.1. Using the .longValue() Method

5.1.使用.longValue()方法

Next, let’s use the “==” comparison operator, but in a safe way. The class Number has a method .longValue() which unwraps the primitive long value:

接下来,让我们使用”==”比较运算符,但要用一种安全的方式。类Number有一个方法.longValue(),它可以解包原始的long值。

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

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

5.2. Casting to Primitive Values

5.2.铸造到原始值

A different way to unbox a Long is by casting the objects to primitive types. Therefore, we’ll extract the primitive value and then we can proceed to use the comparison operator:

解除Long的另一种方法是通过将对象转换成原始类型。因此,我们将提取原始值,然后我们可以继续使用比较运算符。

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

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

Note that, for the .longValue() method or using casting, we should check if the object is null. We could have a NullPointerException if the object is null.

注意,对于.longValue()方法或使用铸造,我们应该检查对象是否为null如果对象为null,我们可能会出现NullPointerException

6. Conclusion

6.结语

In this short tutorial, we have explored different options on how to compare Long objects. We have analyzed the differences when comparing references to objects or content.

在这个简短的教程中,我们探讨了关于如何比较Long对象的不同选项。我们分析了在比较对对象或内容的引用时的差异。

As always, the full source code of the article is available over on GitHub.

一如既往,文章的完整源代码可在GitHub上获得