比较 Java 中的字符、整数和类似类型:使用等于还是==?
题
我想确定一下 Java 中的一些事情:如果我有一个字符、一个整数或一个长整型以及诸如此类的东西,我应该使用 equals 还是 == 就足够了?
我知道对于字符串,不能保证每个唯一字符串只有一个实例,但我不确定其他装箱类型。
我的直觉是使用 equals,但我想确保我没有浪费性能。
解决方案
编辑:该规范使得用于装箱转换一些保证。从节5.1.7 :
如果被装箱值p为真, 假,一个字节,在范围内的炭 \ u0000的到\ u007f,或int或短 -128到127之间的数字,然后让 r1和r2是任何两个结果 P的装箱转换。它始终是 的情况是R1 == R2。
在实施的可以的使用较大的池,请注意。
我的真正的避免依赖,虽然写的代码。不是因为它可能会失败,但因为它不是显而易见的 - 很少有人会知道的规范那么好。 (我以前认为这是实现相关的。)
您应该使用equals
或比较基础值,即
if (foo.equals(bar))
或
if (foo.intValue() == bar.intValue())
请注意,即使自动装箱得到保障,使用固定的值,其他呼叫者可以总是反正创建单独的实例。
其他提示
如果您想比较任何对象的值,请使用 .equals()
.
即使(尤其是)这些对象是原始包装类型 Byte、Character、Short、Integer、Long、Float、Double 和 Boolean。
"==
“只比较对象身份和你,这很少是你想要的。事实上,原始包装器从来都不是你想要的。
仅使用 ==
在这两种情况之一:
- 比较中涉及的所有值都是原始类型(最好不是浮点数)
- 你真的想知道两个引用是否引用同一个对象(这包括比较
enum
s,因为该值绑定到对象标识)
//Quick test
public class Test {
public static void main(String[] args) {
System.out.println("Are they equal? "+ (new Long(5) == new Long(5)));
}
}
输出:
“他们等于?0”
答案:
没有,他们是不相等的。您必须使用.equals或比较它们的原始值。
如果被装箱值p为真, 假,一个字节,在范围内的炭 \ u0000的到\ u007f,或int或短 -128到127之间的数字,然后让 r1和r2是任何两个结果 P的装箱转换。它始终是 的情况是R1 == R2。
和
讨论
理想情况下,拳击给定的原始 p值,将始终产生一个 相同的附图。在实践中,这 可能是不可行的使用现有 实现技术。规则 以上是一个务实的妥协。该 上述最终条款要求 某些共同的价值观总是被装箱 为区分对象。该 实现可能缓存这些,懒洋洋地 或热切。
有关的其它值,该制剂 禁止对任何假设 在盒装值的身份 程序员的一部分。这将允许 一些(但不要求)共享或 所有这些参考文献中。
这确保了最常见的 情况下,该行为将是 期望的一个,而不强加不适当 性能损失,特别是在 小型设备。更少的内存限制 实现可能,例如, 高速缓存中的所有字符和短裤,如 以及在整型和长 的-32K范围。 - + 32K
因此,在某些情况下会==工作,在许多其他国家也不会。始终使用.equals是安全的,因为你不能受款人(一般)如何获得的实例。
如果速度是一个因素(最.equals开始与==比较,或者至少它们应该)并可以出示担保它们是如何分配的,它们适合在上述范围内则==是安全的。
某些虚拟机可能会增加的大小,但它是安全的假设由的langauge规范的规定,而不是依赖于特定的虚拟机的行为,除非你真的真的真的需要的最小尺寸。
等号(对象o)方法的实现几乎总是与
开始if(this == o) return true;
因此,使用即使equals
是真的真的没有太大的性能损失==
。
我建议总是*使用equals
方法上的对象。
*当然也有极少数的时候,你不应该采取这样的建议。的
在一般的答案是否,你不能保证,对于相同的数值,你得到的龙对象是相同的(即使你限制自己使用Long.valueOf())。
然而,很可能你会首先尝试测试)引用(使用==),然后,如果失败,尝试平等的平等(获得的性能提升。这一切都取决于附加==测试和方法调用...您的里程可能会有所不同的比较成本,但它是值得尝试的一个简单的循环测试,看看哪个更好。
值得注意的是自动装箱值将合并使用对象(如果可用)。这就是为什么(整数)0 ==(整数)0但(整数)128!=(整数)128针对Java 6u13
我喜欢直观地看到的结果:
public static void main(String[] args)
{
Integer a = 126; //no boxed up conversion, new object ref
Integer b = 126; //no boxed up conversion, re-use memory address
System.out.println("Are they equal? " + (a == b)); // true
Integer a1 = 140; //boxed up conversion, new object
Integer b1 = 140; //boxed up conversion, new object
System.out.println("Are they equal? " + (a1 == b1)); // false
System.out.println("Are they equal? " + (new Long(5) == new Long(5))); // false
}
==
而equals(Object obj)
比较了对象相等比较对象引用。 如果能永远的多个实例等于存在对象的那么您必须使用equals
是否相等的比较。
示例:
Integer i1 = new Integer(12345);
Integer i2 = new Integer(12345);
这些是不同的对象实例,但是根据整数平等相等,因此必须使用equals(Object obj)
public enum Gender {
MALE, FEMALE;
}
在这种情况下,将只有FEMALE
的一个实例中存在这样==
是安全使用。