==运算符对String有什么用?

时间:2015-02-27 22:51:13

标签: java string

在Java中,如果要检查两个字符串是否相等,在它们的值相同的意义上,他/她需要使用equals方法。例如。 :

String foo = "foo"; 
String bar = "bar";
if(foo.equals(bar)) { /* do stuff */ }

如果想要检查参考相等性,他需要在两个字符串上使用==运算符。

if( foo == bar ) { /* do stuff */ }

所以我的问题是==运算符是否用于String类?为什么要比较字符串引用?

修改 问:如何比较字符串? ==如何工作? equals方法如何工作?

我要问的是==运算符对Java中的String类有什么用处?不重载它的理由是什么,以便进行深入的比较?

11 个答案:

答案 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(),我们可以继续在字符串上使用引用比较进行比较。

  

不重载它的理由是什么,以便进行深入的比较?

  1. 因为Java没有将运算符重载为design decision
  2. 运营商&#39; ==&#39;始终是引用运算符,equals()始终是方法。在C ++中你可以改变它,但许多人认为只是模糊了代码。

答案 7 :(得分:0)

  • 与检查整个字符串的相等性相比,检查引用更快

    • 假设您有大字符串(URL或DBMS查询),它们有多个引用。要检查它们是否相等,您可以逐个字符检查,也可以检查它们是否都引用同一个对象。
    • 实际上,java中的equals方法首先检查引用是否相同,并且只有在不进行时才检查,并逐字符进行检查。

  • Java充满了引用,因此,您可能需要一个案例,您需要检查两个变量是否引用相同的String / Object,而不是同时拥有相同String的每个副本,以便 您可以在一个地方更新字符串,它会反映在所有变量中。
    • 为此,equals方法没有帮助,因为它也检查副本是否相等。你需要检查它们是否都引用同一个对象,因此==进入图片。

答案 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方法。此类仅用于需要引用相等语义的罕见情况。