比较 Java 中的字符、整数和类似类型:使用等于还是 ==?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/735832/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Comparing Character, Integer and similar types in Java: Use equals or ==?
提问by Uri
I wanted to make sure about something in Java: If I have a Character or an Integer or a Long and those sort of things, should I use equals or is == sufficient?
我想确定 Java 中的某些内容:如果我有一个字符、整数或长整数之类的东西,我应该使用 equals 还是 == 就足够了?
I know that with strings there are no guarantees that there is only one instance of each unique string, but I'm not sure about other boxed types.
我知道对于字符串,不能保证每个唯一字符串只有一个实例,但我不确定其他盒装类型。
My intuition is to use equals, but I want to make sure I'm not wasting performance.
我的直觉是使用 equals,但我想确保我没有浪费性能。
采纳答案by Jon Skeet
EDIT: The spec makes someguarantees for boxing conversions. From section 5.1.7:
编辑:规范对装箱转换做出了一些保证。从第 5.1.7 节:
If the value p being boxed is true, false, a byte, a char in the range \u0000 to \u007f, or an int or short number between -128 and 127, then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.
如果被装箱的值 p 是真、假、一个字节、一个 \u0000 到 \u007f 范围内的字符,或者一个 int 或 -128 到 127 之间的短数,那么让 r1 和 r2 是任何两个装箱转换的结果p. 的 r1 == r2 总是如此。
The implementation canuse a larger pool, mind you.
请注意,实现可以使用更大的池。
I would reallyavoid writing code which relies on that though. Not because it might fail, but because it's not obvious - few people will know the spec that well. (I previously thought it was implementation-dependent.)
我真的会避免编写依赖于它的代码。不是因为它可能会失败,而是因为它并不明显——很少有人会那么了解规范。(我以前认为它是依赖于实现的。)
You should use equals
or compare the underlying values, i.e.
您应该使用equals
或比较基础值,即
if (foo.equals(bar))
or
或者
if (foo.intValue() == bar.intValue())
Note that even if the autoboxing were guaranteed to use fixed values, other callers can always create separate instances anyway.
请注意,即使自动装箱保证使用固定值,其他调用者也始终可以创建单独的实例。
回答by Brandon Yarbrough
//Quick test
public class Test {
public static void main(String[] args) {
System.out.println("Are they equal? "+ (new Long(5) == new Long(5)));
}
}
Output:
输出:
"Are they equal? 0"
“它们相等吗?0”
Answer:
回答:
No, they're not equal. You must use .equals or compare their primitive values.
不,他们不是平等的。您必须使用 .equals 或比较它们的原始值。
回答by Joachim Sauer
If you want to compare anything about the value of any object, use .equals()
.
如果要比较任何对象的值,请使用.equals()
.
Even (and especially) if those Objects are the primitive wrapper types Byte, Character, Short, Integer, Long, Float, Double and Boolean.
即使(尤其是)这些对象是原始包装类型 Byte、Character、Short、Integer、Long、Float、Double 和 Boolean。
"==
" only ever compares the object identity and you that's very, very rarely what you want. And de-facto never what you want with the primitive wrappers.
” ==
“只比较对象身份和你那是非常非常少的你想要的。事实上,原始包装器永远不会是你想要的。
Only use ==
in one of those two scenarios:
仅==
在这两种情况之一中使用:
- all values involved in the comparison are primitive types (and preferably not floating point numbers)
- you really want to know if two references refer to the same object (this includes comparison of
enum
s, because there the value is bound to the object identity)
- 比较中涉及的所有值都是原始类型(最好不是浮点数)
- 你真的想知道两个引用是否指向同一个对象(这包括
enum
s 的比较,因为那里的值绑定到对象标识)
回答by Varkhan
The general answer is no, you are not guaranteed that for the same numeric value, the Long objects you get are the same (even if you restrict yourself to using Long.valueOf()).
一般的答案是否定的,您不能保证对于相同的数值,您获得的 Long 对象是相同的(即使您限制自己使用 Long.valueOf())。
However, it is possible that you would get a performance improvement by first trying to test the equality of references (using ==) and then, if failed, trying equals(). It all hinges on the comparative costs of the additional == test and the method call... Your mileage may vary, but it is worth trying a simple loop test to see which is better.
但是,您可能会通过首先尝试测试引用的相等性(使用 ==),然后在失败时尝试 equals() 来提高性能。这一切都取决于附加 == 测试和方法调用的比较成本......您的里程可能会有所不同,但值得尝试一个简单的循环测试,看看哪个更好。
回答by TofuBeer
If the value p being boxed is true, false, a byte, a char in the range \u0000 to \u007f, or an int or short number between -128 and 127, then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.
如果被装箱的值 p 是真、假、一个字节、一个 \u0000 到 \u007f 范围内的字符,或者一个 int 或 -128 到 127 之间的短数,那么让 r1 和 r2 是任何两个装箱转换的结果p. 的 r1 == r2 总是如此。
and:
和:
Discussion
Ideally, boxing a given primitive value p, would always yield an identical reference. In practice, this may not be feasible using existing implementation techniques. The rules above are a pragmatic compromise. The final clause above requires that certain common values always be boxed into indistinguishable objects. The implementation may cache these, lazily or eagerly.
For other values, this formulation disallows any assumptions about the identity of the boxed values on the programmer's part. This would allow (but not require) sharing of some or all of these references.
This ensures that in most common cases, the behavior will be the desired one, without imposing an undue performance penalty, especially on small devices. Less memory-limited implementations might, for example, cache all characters and shorts, as well as integers and longs in the range of -32K - +32K.
讨论
理想情况下,装箱给定的原始值 p 总是会产生相同的引用。实际上,使用现有的实现技术这可能是不可行的。上述规则是务实的妥协。上面的最后一条要求始终将某些常见值装入无法区分的对象中。实现可能会延迟或急切地缓存这些。
对于其他值,此公式不允许程序员对装箱值的身份进行任何假设。这将允许(但不要求)共享部分或所有这些引用。
这可确保在大多数常见情况下,行为将是所需的行为,而不会造成不应有的性能损失,尤其是在小型设备上。例如,内存限制较少的实现可能会缓存 -32K - +32K 范围内的所有字符和短整数,以及整数和长整数。
So, in some cases == will work, in many others it will not. Always use .equals to be safe since you cannot grantee (generally) how the instances were obtained.
因此,在某些情况下 == 会起作用,而在许多其他情况下则不会。始终使用 .equals 以确保安全,因为您无法授予(通常)如何获取实例。
If speed is a factor (most .equals start with an == comparison, or at least they should) AND you can gurantee how they were allocated AND they fit in the above ranges then == is safe.
如果速度是一个因素(大多数 .equals 以 == 比较开始,或者至少它们应该)并且您可以保证它们是如何分配的并且它们适合上述范围,那么 == 是安全的。
Some VMs may increase that size, but it is safer to assume the smallest size as specified by the langauge spec than to rely on a particular VM behaviour, unless you really really really need to.
某些 VM 可能会增加该大小,但假设语言规范指定的最小大小比依赖特定的 VM 行为更安全,除非您真的真的需要这样做。
回答by Steve Kuo
==
compares the object reference while equals(Object obj)
compares for object equality. If there can ever be more than one instance of an equals object in existencethen you mustuse equals
for equality comparison.
==
比较对象引用,同时equals(Object obj)
比较对象是否相等。如果存在多个 equals 对象的实例,那么您必须使用equals
相等比较。
Examples:
例子:
Integer i1 = new Integer(12345);
Integer i2 = new Integer(12345);
these are different object instances but are equal according to Integer's equality, so you must use equals(Object obj)
这些是不同的对象实例,但根据 Integer 的相等性是相等的,因此您必须使用 equals(Object obj)
public enum Gender {
MALE, FEMALE;
}
in this case there will only be one instance of FEMALE
in existence so ==
is safe to use.
在这种情况下,将只存在一个实例,FEMALE
因此==
可以安全使用。
回答by Peter Lawrey
It is worth noting that auto-boxed values will uses pooled object if they are available. This is why (Integer) 0 == (Integer) 0 but (Integer) 128 != (Integer) 128 for Java 6u13
值得注意的是,如果自动装箱值可用,它们将使用池化对象。这就是为什么 (Integer) 0 == (Integer) 0 but (Integer) 128 != (Integer) 128 for Java 6u13
回答by Skip Head
Implementations of the equals(Object o) method almost always start with
equals(Object o) 方法的实现几乎总是以
if(this == o) return true;
so using equals
even if ==
is true is really not much of a performance hit.
所以使用equals
即使==
是真的对性能影响不大。
I recommend always* using the equals
method on objects.
我建议始终*equals
在对象上使用该方法。
* of course there are a very few times when you should not take this advice.
* 当然,在极少数情况下您不应该接受此建议。
回答by djangofan
I like to see the result visually:
我喜欢直观地看到结果:
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
}