在Java中,如果要检查两个字符串是否相等,在它们的值相同的意义上,他/她需要使用equals
方法。例如。 :
String foo = "foo";
String bar = "bar";
if(foo.equals(bar)) { /* do stuff */ }
如果想要检查参考相等性,他需要在两个字符串上使用==运算符。
if( foo == bar ) { /* do stuff */ }
所以我的问题是==运算符是否用于String类?为什么要比较字符串引用?
修改
我 不 问:如何比较字符串? ==如何工作? equals
方法如何工作?
我要问的是==运算符对Java中的String类有什么用处?不重载它的理由是什么,以便进行深入的比较?
答案 0 :(得分:15)
想象一个线程安全的Queue<String>
充当生产者线程和消费者线程之间的通信通道。使用特殊String
表示终止似乎是完全合理的。
// Deliberate use of `new` to make sure JVM does not re-use a cached "EOT".
private static final String EOT = new String("EOT");
...
// Signal we're done.
queue.put(EOT);
// Meanwhile at the consumer end of the queue.
String got = queue.get();
if ( got == EOT ) {
// Tidy shutdown
}
请注意,这对以下内容具有弹性:
queue.put("EOT");
因为"EOT" != EOT
即使"EOT".equals(EOT)
为true
。
答案 1 :(得分:10)
它的用途是什么?在正常练习中并不多,但您总是可以编写一个对intern()
- ed字符串进行操作的类,然后可以使用==
来比较它们。
为什么它不被重载是一个更简单的问题:因为Java中没有运算符重载。 (为了搞砸了一点,+
运算符对于字符串来说是过载的,这样做是为了使字符串操作稍微麻烦一些。但你可以说这只是语法糖而且肯定没有运算符在字节码级别上用Java重载。)
缺少重载==
运算符使得运算符的使用更加模糊,至少对于引用类型而言。 (也就是说,直到引入自动装箱/拆箱点,这再次混淆了水域,但那是另一个故事。)它还允许你有类似IdentityHashMap
的类似行为的类你放入它的每个物体的方式。
说了这么多,避免运营商超载的决定(如果可能)是a fairly arbitrary design choice。
答案 2 :(得分:0)
==
运算符比较两个对象之间的引用。例如,如果String x和String y引用两个不同的东西,那么==
运算符将显示false。但是,如果String.equals()
方法彼此引用,但是它们(例如“Hello”,“World”等)是相同的,则{{1}}方法不进行比较。
答案 3 :(得分:0)
// A.java
String foo1 = "foo";
// B.java
String bar1 = "foo";
在编译时实现的所有字符串文字都添加到字符串常量池中。因此,当您在两个不同的类中有两个不同的String声明时,将不会创建两个String对象,并且foo1
和&amp; bar1
引用值foo
的相同String实例。既然你在两个不同的变量中有相同的String引用,你可以只使用==
检查这两个字符串是否相等,这是快速的,因为它只是比较位模式,如{{1}中所示方法,比较每个字符,通常用于两个不同的String实例但内容相同。
事实上,如果你看一下String类中的equals()
实现,他们做的第一个检查是使用equals()
进行参考比较,因为它们看起来可能与你不同,但是如果它们是&#39; re字符串文字或者如果他们已经被其他人实习,那么你所拥有的就是两个变量中的单一引用。
==
此外, public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
// remaining code
}
不仅适用于字符串,它还用于比较任何两个位模式,无论是原语还是引用
答案 4 :(得分:0)
1。&#34; ==&#34;比较操作是两个变量的值相等,对于一个引用类型变量,由堆内存地址中的两个变量表示是相同的,即堆栈具有相同的内容。
2.&#34; equals&#34;两个操作变量是否表示对堆中同一对象的引用,即是否内容相同。
答案 5 :(得分:0)
String s =&#34; string1&#34 ;;在池String中创建1个引用和1个对象 s1 =&#34; string1&#34 ;;只创建一个引用并指向s是什么 指着。
s == s1 // true
String s2 = new String(&#34; string1&#34;);在堆中创建一个对象,一个在 游泳池和一个参考。
//Since, s2 is pointing to different object so,
s2 == s // false
s1 == s // false
问题: 因此,假设我们要检查应用程序在运行时在池中创建和存储多少个唯一的String对象
我们可以有一个单例对象,它可以将所有String引用存储在一个数组中。
从前面的s,s1和s2的例子中,最后对于s和s1,创建了1个对象,对于s2,1个对象(总共2个)。
//If we use equals method, all
s.equals(s1) // gives true
s1.equals(s2) // gives true
//So, number of references present in the array of singleton object will be our
//total number of objects created which equals to 3 // doesn't match actual
//count which is 2
我们可以使用==来检查引用是否相等,所以如果引用相等,我们将不会增加池中唯一String对象的计数,并且对于每个不相等的结果,我们将递增计数。
这里,
代表
s // count = 1
s1 == s // count remains same
s2 == s // false, so count = 1 + 1 = 2
//We get total number of unique String objects created and got stored in pool using ==
答案 6 :(得分:0)
简单回答......
为什么要比较字符串引用?
因为他们想以非常快的方式比较String 值。
字符串不总是interned()。字符串常量是,但字符串可能是在堆上手动创建的。在手动创建的字符串上使用intern(),我们可以继续在字符串上使用引用比较进行值比较。
不重载它的理由是什么,以便进行深入的比较?
答案 7 :(得分:0)
与检查整个字符串的相等性相比,检查引用更快。
答案 8 :(得分:0)
这似乎是之前被问过的,并且在这里得到了相当流行的答案:
Why didn't == operator string value comparison make it to Java?
简单的答案是:一致性
我认为这只是一致性,或者是最不惊讶的原则&#34;。 字符串是一个对象,因此如果被处理则会令人惊讶 与其他对象不同。
答案 9 :(得分:0)
虽然这不是根本原因,但用法可能是提高性能:在执行繁重的计算之前,“内化”你的字符串(intern()
)并仅使用==
进行比较。
答案 10 :(得分:0)
我要问的是==运算符对Java中的String类有什么用处? 不重载它的理由是什么,以便进行深入比较?
==和等于完全不同的用途。 ==确认是否存在引用相等 等于确认对象是否包含相同的内容。
引用相等的示例是IdentityHashMap。 可能存在这样的情况:只有向IdentityHashMap插入内容的对象才有权获取/删除该对象。
重载引用相等可能会导致java的不必要的复杂性。 例如 if(字符串) { 做深刻的平等 } 其他 { 做参考 - 平等 }
/ ********************************************** ******************* /
公共类IdentityHashMap扩展AbstractMap实现了Map,Serializable,Cloneable
此类使用哈希表实现Map接口,在比较键(和值)时使用引用相等性代替对象相等性。换句话说,在IdentityHashMap中,当且仅当(k1 == k2)时,两个密钥k1和k2被认为是相等的。 (在正常的Map实现中(如HashMap),当且仅当(k1 == null?k2 == null:k1.equals(k2))时,两个键k1和k2被认为是相等的。)
这个类不是通用的Map实现!虽然这个类实现了Map接口,但它故意违反了Map的一般契约,它要求在比较对象时使用equals方法。此类仅用于需要引用相等语义的罕见情况。