比较 Java 中的字符、整数和类似类型:使用 equals 还是 ==?
我想确定一下 Java 中的一些事情: 如果我有一个字符、一个整数或一个长整型以及诸如此类的东西,我应该使用 equals 还是 == 就足够了?
我知道对于字符串,不能保证每个唯一字符串只有一个实例,但我不确定其他装箱类型。
我的直觉是使用 equals,但我想确保我没有浪费性能。
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?
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
编辑:该规范对装箱转换做出了一些保证。 来自第 5.1.7 节:
请注意,该实现可以使用更大的池。
不过,我真的会避免编写依赖于它的代码。 不是因为它可能会失败,而是因为它并不明显——很少有人会那么了解该规范。 (我之前认为它与实现相关。)
您应该使用
equals
或比较基础值,即或
请注意,即使自动装箱保证使用固定值,其他调用者始终可以创建单独的实例反正。
EDIT: The spec makes some guarantees for boxing conversions. From section 5.1.7:
The implementation can use a larger pool, mind you.
I would really avoid 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.or
Note that even if the autoboxing were guaranteed to use fixed values, other callers can always create separate instances anyway.
如果要比较任意两个对象的相等性,请使用
.equals()
。即使(尤其是)这些对象是原始包装类型
Byte
、Character
、Short
、Integer
、<代码>长整型、浮点
、双精度
和布尔
。对于对象,“
==
”仅比较对象标识,而这很少是您想要的。 事实上,使用原始包装器你永远无法得到你想要的东西。仅在这两种情况之一中使用
==
:enum
的比较,因为那里的值绑定到对象标识)If you want to compare any two objects for equality use
.equals()
.Even (and especially) if those objects are the primitive wrapper types
Byte
,Character
,Short
,Integer
,Long
,Float
,Double
andBoolean
.For objects "
==
" only ever compares the object identity and that's very, very rarely what you want. And you de-facto never what you want with the primitive wrappers.Only use
==
in one of those two scenarios:enum
s, because there the value is bound to the object identity)Java 语言规范 5.1.7:
和:
因此,在某些情况下 == 会起作用,但在许多其他情况下则不会。 为了安全起见,请始终使用 .equals,因为您无法(通常)授予实例的获取方式。
如果速度是一个因素(大多数 .equals 以 == 比较开始,或者至少它们应该)并且您可以保证它们是如何分配的并且它们符合上述范围,那么 == 是安全的。
某些虚拟机可能会增加该大小,但假设语言规范指定的最小大小比依赖特定虚拟机行为更安全,除非您确实确实需要这样做。
Java Language Spec 5.1.7:
and:
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.
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.
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.
输出:
“它们相等吗?0”
答案:
不,它们不相等。 您必须使用 .equals 或比较它们的原始值。
Output:
"Are they equal? 0"
Answer:
No, they're not equal. You must use .equals or compare their primitive values.
equals(Object o) 方法的实现几乎总是以
这样的方式开始,因此即使
==
为 true,使用 equals 也不会对性能造成太大影响。我建议始终*对对象使用
equals
方法。* 当然,在极少数情况下您不应该接受此建议。
Implementations of the equals(Object o) method almost always start with
so using
equals
even if==
is true is really not much of a performance hit.I recommend always* using the
equals
method on objects.* of course there are a very few times when you should not take this advice.
一般的答案是否,您不能保证对于相同的数值,您获得的 Long 对象是相同的(即使您限制自己使用 Long.valueOf() )。
但是,通过首先尝试测试引用的相等性(使用 ==),然后如果失败,尝试 equals(),您可能会获得性能改进。 这一切都取决于额外的 == 测试和方法调用的比较成本...您的里程可能会有所不同,但值得尝试一个简单的循环测试来看看哪个更好。
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()).
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.
值得注意的是,自动装箱的值将使用池对象(如果可用)。 这就是为什么 Java 6u13 中 (Integer) 0 == (Integer) 0 但 (Integer) 128 != (Integer) 128
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
我喜欢直观地看到结果:
I like to see the result visually:
==
比较对象引用,而equals(Object obj)
比较对象相等性。 如果存在多个 equals 对象实例,那么您必须使用equals
进行相等比较。示例:
这些是不同的对象实例,但根据 Integer 相等性是相等的,因此您必须使用
equals(Object obj)
在这种情况下,其中只有一个
FEMALE
实例存在,因此==
可以安全使用。==
compares the object reference whileequals(Object obj)
compares for object equality. If there can ever be more than one instance of an equals object in existence then you must useequals
for equality comparison.Examples:
these are different object instances but are equal according to Integer's equality, so you must use
equals(Object obj)
in this case there will only be one instance of
FEMALE
in existence so==
is safe to use.