有没有数字“价值相等”?

时间:2013-10-16 17:52:05

标签: java numbers equals primitive

默认情况下,Java对基元执行Binary Numeric Promotion,但不对对象执行相同的操作。这是一个快速测试来证明:

public static void main(String... args) {
  if(100 == 100L) System.out.println("first trial happened");
  if(Integer.valueOf(100).equals(Long.valueOf(100))) {
    System.out.println("second trial was true");
  } else {
    System.out.println("second trial was false");
  }
  if(100D == 100L) System.out.println("third trial, fun with doubles");
}

输出:

first trial happened
second trial was false
third trial, fun with doubles

这显然是 正确行为 - Integer a Long。但是,Number子类是否存在“值等于”,它会以100 == 100L返回true的方式返回true?还是100d == 100L?换句话说,是否有一个方法(不是Object.equals)将对象的二进制数字促销行为等效?

3 个答案:

答案 0 :(得分:3)

if(100 == 100L) System.out.println("first trial happened");

你得到一些Binary Numeric Promotion

  

否则,如果任一操作数的类型为long,则转换另一个操作数   很久。

因此100L == 100L

这个

if(Integer.valueOf(100).equals(Long.valueOf(100))) {
    System.out.println("second trial was true");
} else {
    System.out.println("second trial was false");
}

“失败”,因为Integer#equals()方法检查传递的对象是否为instanceof Integer。如果不是,则立即返回false

if(100d == 100l) System.out.println("third trial, fun with doubles");

与第一个相同,但double代替long

盒装类型的所有equals()方法都会检查instanceof各自的类型,因此无法使它们正常工作。

你可能不喜欢这个解决方案,但它会有类似的东西

if (Integer.valueOf(100).intValue() == Long.valueOf(100).longValue()) {
    System.out.println("second trial was true");
} else {
    System.out.println("second trial was false");
}

答案 1 :(得分:2)

Guava提供了一些很好的实用工具来处理基元,包括每种类型的compare()方法:

int compare(prim a, prim b)

事实上,从Java 7开始,JDK已经添加了相同的功能。这些方法不提供任意Number比较,但是它们可以为您提供定义任何类型安全比较的粒度。 d,通过选择要使用的类(LongsDoubles等)。

@Test
public void valueEquals() {
  // Your examples:
  assertTrue(100 == 100l);
  assertTrue(100d == 100l);
  assertNotEquals(100, 100l); // assertEquals autoboxes primitives
  assertNotEquals(new Integer(100), new Long(100));

  // Guava
  assertTrue(Longs.compare(100, 100l) == 0);
  assertTrue(Longs.compare(new Integer(100), new Long(100)) == 0);
  assertTrue(Doubles.compare(100d, 100l) == 0);
  // Illegal, expected compare(int, int)
  //Ints.compare(10, 10l);

  // JDK
  assertTrue(Long.compare(100, 100l) == 0);
  assertTrue(Long.compare(new Integer(100), new Long(100)) == 0);
  assertTrue(Double.compare(100d, 100l) == 0);
  // Illegal, expected compare(int, int)
  //Integer.compare(10, 10l);
  // Illegal, expected compareTo(Long) which cannot be autoboxed from int
  //new Long(100).compareTo(100);
}

答案 2 :(得分:1)

如果只关心数字值,则应使用compareTo方法而不是equals