到目前为止,我一直在程序中使用==操作符来比较所有字符串。但是,我遇到了一个bug,把其中一个改为.equals(),它修复了这个bug。
==坏了吗?什么时候应该使用,不应该使用?有什么区别?
- 另外,如果要重写.equals()方法,请确保要重写.hashcode()方法,否则将导致违反等价关系b/w equals和hashcode。更多信息请参考Java文档。
- 留下一个链接来解释为什么==在对象上的工作方式:stackoverflow.com/a/19966154/2284641
- EDCOX1(0)将工作一段时间,因为Java有一个字符串池,它试图重用常用字符串的内存引用。但是==比较对象是相等的,而不是值…因此,.equals()是您想要使用的正确用途。
- 决不使用= =测试字符串是否相同,除非您喜欢跟踪细微的错误并研究Java字符串交互过程的复杂性。"12"=="1"+2是假的(可能)
==检验参考相等性(是否为同一对象)。
.equals()检验值是否相等(逻辑上是否"相等")。
objects.equals()在调用.equals()之前检查null,这样就不必(从jdk7开始提供,在guava中也提供)。
将EDCOX1的4内容与任何EDCOX1(5)的内容进行比较(可从Java 1.5获得)。
因此,如果要测试两个字符串是否具有相同的值,您可能需要使用Objects.equals()。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| // These two have the same value
new String("test"). equals("test") // --> true
// ... but they are not the same object
new String("test") =="test" // --> false
// ... neither are these
new String("test") == new String("test") // --> false
// ... but these are because literals are interned by
// the compiler and thus refer to the same object
"test" =="test" // --> true
// ... string literals are concatenated by the compiler
// and the results are interned.
"test" =="te" +"st" // --> true
// ... but you should really just call Objects.equals()
Objects. equals("test", new String("test")) // --> true
Objects. equals(null, "test") // --> false
Objects. equals(null, null) // --> true |
你几乎总是想使用Objects.equals()。在罕见的情况下,你知道你在处理内部字符串,你可以使用==。
来自JLS 3.10.5。字符串文字:
Moreover, a string literal always refers to the same instance of class String. This is because string literals - or, more generally, strings that are the values of constant expressions (§15.28) - are"interned" so as to share unique instances, using the method String.intern.
类似的例子也可在JLS 3.10.5-1中找到。
- 我猜在爪哇你应该说"参考"而不是"指针"。
- 如果你能这样做,这个方法有什么用处?
- @Xokas11:CompareTo通常用于排序。
- Equals、CompareTo和HashCode都与必须履行的合同直接相关。只有equals和hashcode在所有对象上都是多态的。CompareTo来自Comparable。
- 我一直认为这是Java的不足,如果使用C++,重写EDCOX1,0的字符串类方法应该做到这一点
- +1表示"测试"=="!测试".substring(1)==>错误行。我本可以把它标为真的,只是…但正如您所说,编译器无法在编译时确定结果,因此这2个内存位置将引用两个不同的内存位置…我不会发现的……-)
- 只是一个注释equals()将这个字符串与另一个字符串进行了精确的比较,但是equalsIgnoreCase()将这个字符串与另一个字符串进行了比较,忽略了大小写方面的考虑。
- 除非你有充分的理由,否则一定要使用equalsIgnoreCase()。只有很少的性能权衡(如果有的话),而且如果提供程序的话,安全性要高得多。
- 我不认为它是Java的一个不足之处,使用EDOCX1,4对多个事物来说,对于新手来说是够混乱的了!字符串是一个对象,因此必须调用该对象上的函数来处理它(在这种情况下比较值)。就好像我们希望'4==4'比较内存中的指针一样。必须以不同的方式处理不同的数据类型。字符串是对象,因此使用它们!
- SnaKoc文档中的"混乱"问题是由Java的另一个不足/特性引起的:Java不支持指针。EDOCX1 4比EDCOX1(6)更直,如果Java支持重写操作符==:"EDCOX1,8",我宁愿使用EDCOX1 4Ω来比较对象。2其他缺少Java(与C++相比):(a)不支持结构数据。(b)不支持无符号整数。
- Java确实使用指针,但是它们被抽象成对象引用,它是一个设计决策,提供了一个整体的程序安全级别,即使指针和指针算法有高水平的理解,也不能总是用指针来保证。我认为结构化数据(struct)是Java8中的一种,或者可能已经被推回到Java9中。不管怎么说,Java是Java,它是块状的,是珍珠。:
- 还要注意,.equals()通常与==相同,字符串是少数例外之一,如果要比较自己的类,则需要重新定义(重写).equals()方法。
- @Kajacx good point+1,我想还没有人提到。如果您有一个自定义对象,那么.edquals()不知道如何比较对象内部的值,因此可以覆盖它并实现您自己的.equals()。
- @SimonNickerson ==是否比较了所有面向对象语言中的对象?
- @bbvarghe no.在c中,例如,它在字符串上超载以实现值相等…对于python(它有is操作符来实现引用相等)。
- @蛇博士-我们可以说是相反的。除非你有充分的理由,否则一定要使用equals()。你所说的安全完全取决于上下文。例如,在比较密码以确定用户是否输入了正确的密码时,忽略大小写差异是不安全的。
- @我希望你不要用纯文本检查密码!密码至少应存储为char[],因为String是可变的。(请参阅stackoverflow.com/questions/8881291/…)——不管怎样,这当然取决于上下文。我的一般规则是:使用.equalsIgnoreCase(),除非你有充分的理由(比如案件)。有太多次我被用户输入像SOMESTRING之类的东西而不是预期的SOMESTRING之类的东西烧坏了,然后报告程序就坏了(caps lock on或其他东西)。
- 为了澄清每个人的观点,在Java中,EDCOX1×5是必要的,因为它比较两个对象的EDCOX1×6,而不是EDCOX1 7。==将比较references(为简单起见,考虑指针)。您可以使用==比较两个对象,但是如果引用不相同,它就不会给出预期的结果。它可能在某些情况下工作,例如使用字符串,但不可靠。当您创建一个与内存中另一个字符串具有相同值的新字符串时,JVM会有一些魔力,在某些情况下,它基本上只是创建对相同内存位置的新引用。只需使用.equals()…
- @ SnakeDoc??字符串不可变。
- @snakedoc——这些都是安全考虑因素,因此,它们都依赖于上下文。并非所有的应用程序都使用完美的安全性——顺便说一下,这是不存在的。密码只是一个例子。如果您更喜欢测试密码散列上的相等性,而不是密码,那么同样的情况是:为了安全起见,测试时考虑到大小写的差异。
- @尼古拉斯·巴布利斯科,我不知道我说它们在哪里是可变的。总之,我发现在我的工作中使用.equalSignoreCase()的频率要高得多,因为我经常处理用户提供的文件(配置文件)或直接输入。如果您希望使用哈希,那么这就是使用.equals()的"好理由"。否则,期望某个值的字符串并中断程序是愚蠢的,因为用户打开了caps lock(doh!)。它对上下文敏感,但我再次发现,我最终更经常使用.equalSignoreCase(),通常是为了保护运行时不受坏用户的影响…
- 等式操作符不做任何普通人直觉上认为它做的事情的另一个原因是因为Java不支持操作符重载。
- 小附加注释:每次在Java代码中使用"MyString"时,实际上是在创建一个具有自动生成名称的私有静态字符串。在同一个类中使用"mystring"两次应该产生相同的引用,因为编译器使用相同的静态类字段。它只是语法上的糖分,类似于为构造for(Object o: collection) {}创建匿名迭代器的方式。
- ==对于基元有用,而不是在可以时使用对象。
- 马奎斯-另一方面,运算符重载(如C++)是为什么平等操作符有时不做任何普通人会直觉地认为它做的事情。关于Java中的运算符,至少可以查看代码和WYSIWYG。
- 关于文本连接,如果从文本创建的字符串对象无条件地连接到后面一行,那么编译时会发生这种情况吗?
- 一个次要的编辑,==并不比.equals"便宜得多",因为string.equals中的第一条语句为:if(this==anObject)return true;。
- HenrikPaul是的,这是Java术语。但是Java中的引用更像C++术语中的指针,因为C++中的引用行为类似于语义上引用的对象。
- 本文有很好的解释codenuggets.com/2014/06/24/java-equals-method
- 你开玩笑吧,==测试只是为了参考,而不是价值。
- 如果您想比较/检查空字符串,则可以使用iSimple()(从Java 1.6)。
- ==也只适用于基元数据类型,如int。字符串的工作方式与基元类型不同
- 字符串是一个对象,当两个对象引用相同的内存位置时,==为真;当两个对象中存储的内容相同时,equals()为真。例如,Employee对象,那么我们可以重写Equals来指定雇员的相等性(emp id或name或两者兼有),但如果我们使用==则再次表示引用相等性。如果我们希望我们的对象(或字符串)具有可比性,那么实现具有方法compareTo()的Comparable接口。然后,我们可以定义如何比较Employee对象(例如,使用EMP ID或名称或两者)。当您要对员工(或字符串)进行排序时,这很有用。
- @扭矩:您的结论可能不正确,因为大多数比较(在大多数程序中)都是不相等的,因此如果测试失败,必须继续附加逻辑。我还没有研究实现,但是我假设下一个测试是长度测试。这通常足以区分两个字符串,所以额外的成本通常不算太大,但绝对不止是一个比较。
- @toolmakersteve但是这是不相关的,如果它没有通过引用比较,那么首先使用它甚至是无效的(用于比较字符串值),更不用说更有效的操作了。
- 当您将已知常量与"可能"具有字符串的变量进行比较时,请从该常量开始,因为该变量可能包含空值。这样就不必检查空值。像这样的东西:"某个常数"。等于(某个变量)
- @无赖-你误解了扭矩提出的观点,以及我对它的反应。显然,如果你想要的功能是equals,那么你必须使用equals。Torque对性能做出了错误的断言,我指出了这一点。[我只是费心指出这一点,因为有那么多人投票赞成torque的评论,这意味着他们没有意识到他的逻辑是错误的。]
- "在罕见的情况下,你知道你在处理实习生字符串,你的can使用==",一般你是实习生,所以你可以使用==。实习后,你应该(与can相反)使用==。
- 由于Java没有指针,因此建议使用Word引用,并强烈劝阻使用字指针……!
- 与s1.equals(s2)相比,Objects.equals(s1, s2)具有潜在的优势,它告诉读者我知道s1不是空的。我会发现我是否错了。这是否真的是一种优势取决于具体情况。
- 我知道你是从哪里来的,但这开始听起来像是一个隐含的非空断言,此时我鼓励RequireNoNull而不是重载Equals检查。
- 还有一件事要补充,使这个答案更为可怕:EDCOX1(14)这是引用比较,但它仍然打印真,因为Java优化它,所以"A"和"B"指的是同一个对象。但不要混淆,对于所有其他数据类型(字符串除外),这将是错误的。这是面试中经常被问到的问题。
- @马克西姆,这是由"test" =="test" => true的例子和关于实习的评论所涵盖的。
- @阿隆马恩帕,完全同意,只是语法上有点不同。有人会被欺骗。
- Apache提供了一个StringUtils类,它有一个更有用的方法来处理这个方程,它检查它是否为空。
- 这对我来说是非常让人沮丧的。感谢发布答案!
- 为什么new string("test")==new string("test")结果为false?
- 由于创建了两个具有两个不同引用的对象,因此new String("test") == new String("test")结果是错误的,使用==比较引用。
- 另一个很好的例子:string s1="123"+"456";string s3=new string("123456");s3==s1//false string s4="123456";s4==s1//true
- 只需尝试"str1.equals(str2)"或"str1.equalSignoreCase(str2)"。这通常在if-else条件语句中使用。您甚至可以尝试使用"comapre",但在这种情况下,retutn类型将是布尔型的。
==测试对象引用,.equals()测试字符串值。
有时看起来好像EDCOX1 0比较值,因为Java做一些幕后的东西,以确保相同的在线字符串实际上是同一个对象。
例如:
1 2 3 4 5 6 7 8 9 10 11
| String fooString1 = new String("foo");
String fooString2 = new String("foo");
// Evaluates to false
fooString1 == fooString2 ;
// Evaluates to true
fooString1. equals(fooString2 );
// Evaluates to true, because Java uses the same object
"bar" =="bar"; |
但要注意空值!
==处理null字符串很好,但从空字符串调用.equals()将导致异常:
1 2 3 4 5 6 7 8
| String nullString1 = null;
String nullString2 = null;
// Evaluates to true
System. out. print(nullString1 == nullString2 );
// Throws a NullPointerException
System. out. print(nullString1. equals(nullString2 )); |
因此,如果你知道fooString1可能是空的,那么就通过写信告诉读者
1
| System. out. print(fooString1 != null && fooString1. equals("bar")); |
以下是较短的,但它不太明显,它检查null(从Java 7):
1
| System. out. print(Objects. equals(fooString1, "bar")); |
- 有时看起来好像"=="比较值,--==总是比较值!(只是某些值是引用!)
- 唉,没有ISNULLUNVIDENE()的静态方法,也没有操作符的自定义重载,这使得Java中的这部分比Cype或Python更笨拙。由于Java没有扩展方法,所以不能编写自己的实用工具来扩展JavaLang.Stand。正确的?有没有想过对字符串进行子类化,添加静态实用方法,然后总是使用mystring?带有两个参数的静态方法用于进行空安全比较,在该子类中也很好。
- groovy通过安全导航操作员(groovy.codehaus.org/…)?.使这变得更加容易。这将把nullString1?.equals(nullString2);转换成一个完全空的语句。但是,如果您有validString?.equals(nullString);,这将不会有帮助——这仍然会引发一个异常。
- 在Java中比较可空字符串的短方法:StAdppOrth.COM/问题/ 11271554 /和Helip;
- JONCOOMBS Java支持子类和创建自己的方法。然而,由于某些原因,很少有类被标记为final,字符串就是其中之一,因此我们无法扩展。我们可以创建其他类,并在那里创建实用程序类,它以两个字符串作为参数,并在那里实现我们的逻辑。另外,对于空值检查其他一些库,比如Spring和ApacheHe的好方法集合,可以使用它。
- @CharleswoodvalidString.equals(null)应该返回false,而不是抛出异常。(以这种方式为object.equals指定,string.equals也遵循这种方式。)
- ==比较对象的引用,.equals()方法比较字符串内容,即字符串。如果要比较字符串,请使用.equals()方法。它非常有用
- 你救了我一天。我正在从可能的空值调用.equals,有时出错。+ 1
- 如前所述小心…字符串文本用于字符串池。因此,String s1 ="Java"; String s2 ="Java" ; s1 == s2 : true。
- 我喜欢使用"literalString".等于(str)语法。它很紧凑,避免了空引用。
==比较对象引用。
.equals()比较字符串值。
有时,==给出了比较字符串值的幻象,如下所示:
这是因为,当您创建任何字符串文字时,JVM首先在字符串池中搜索该文字,如果找到匹配项,则会为新字符串提供相同的引用。因此,我们得到:
(a==b)==>真
1 2
| String Pool
b ----------------->"test" <-----------------a |
但是,在以下情况下,==失败:
在这种情况下,对于new String("test")语句,将在堆上创建新的字符串,并且该引用将提供给b,因此b将在堆上而不是在字符串池中提供引用。
现在,a指向字符串池中的字符串,而b指向堆中的字符串。因此我们得到:
如果(a==b)===>错误。
1 2 3 4 5
| String Pool
"test" <-------------------- a
Heap
"test" <-------------------- b |
虽然.equals()总是比较字符串的值,因此在这两种情况下它都是正确的:
所以使用.equals()总是更好的。
- .equals()比较两个实例,但实现equals来比较它们。这可能是比较ToString的输出,也可能不是。
- @Jacob对象类.equals()方法比较实例(引用/地址),其中as字符串类.equals()方法被重写以比较内容(chars)
- 很好地指出了字符串池和Java堆的差异,因为它们肯定是不一样的。在字符串池中,Java试图"缓存"EDCOX1×1个对象以节省内存占用,如EDCOX1,1称为不可变的(我希望,我在这里正确地说)。还要检查stackoverflow.com/questions/3052442/&hellip;
==运算符检查两个字符串是否完全相同。
.equals()方法将检查两个字符串是否具有相同的值。
- 一般来说,我强烈推荐Apache CuMon库:Caluns.Apache .org/Ont/Corm Lang/JavaDoc/API2.6/Org/&ZWnJ;& 8203;and Helip;java.
- 如果要计算字符串的顺序,也可以使用.compareto()方法。
Java中的字符串是不可变的。这意味着每当您试图更改/修改字符串时,都会得到一个新的实例。不能更改原始字符串。这样做是为了缓存这些字符串实例。典型的程序包含大量的字符串引用,缓存这些实例可以减少内存占用并提高程序的性能。
当使用==运算符进行字符串比较时,您不会比较字符串的内容,而是实际比较内存地址。如果两者都相等,则返回"真"和"假"。而字符串中的equals则比较字符串内容。
所以问题是,如果所有字符串都缓存在系统中,那么为什么==返回false,而等于返回true?嗯,这是可能的。如果您创建了一个新的字符串(如String str = new String("Testing")),那么即使缓存中已经包含了一个具有相同内容的字符串,也会在缓存中创建一个新的字符串。简而言之,"MyString" == new String("MyString")总是返回false。
Java还讨论了函数String(),它可以在一个字符串中使用,使其成为缓存的一部分,因此EDCOX1(3)将返回true。
注意:==运算符要比等于快得多,因为您要比较两个内存地址,但您需要确保代码不会在代码中创建新的字符串实例。否则你会遇到错误。
确保你明白原因。这是因为==比较只比较引用;equals()方法对内容进行逐字比较。
当您为a和b调用new时,每个新的引用都指向字符串表中的"foo"。引用是不同的,但内容是相同的。
是的,很糟糕…
==表示您的两个字符串引用是完全相同的对象。您可能听说过这种情况,因为Java保留了一个文本表(它所做的),但情况并非总是如此。某些字符串以不同的方式加载,由其他字符串等构造,因此您决不能假定两个相同的字符串存储在同一位置。
等于为你做了真正的比较。
是的,==不适合比较字符串(任何对象,除非您知道它们是规范的)。==只是比较对象引用。.equals()等同性检验。对于字符串,它们通常是相同的,但正如您所发现的,这并不总是有保证的。
Java有一个字符串池,Java在该池中管理字符串对象的内存分配。在Java中看到字符串池
使用==运算符检查(比较)两个对象时,它将地址相等性比较到字符串池中。如果两个字符串对象具有相同的地址引用,则返回true,否则返回false。但如果要比较两个字符串对象的内容,则必须重写equals方法。
equals实际上是对象类的方法,但它被重写为字符串类,并给出了一个比较对象内容的新定义。
1 2
| Example:
stringObjectOne.equals(stringObjectTwo); |
但请记住,它尊重字符串的情况。如果要进行不区分大小写的比较,则必须使用String类的EqualSignoreCase方法。
让我们看看:
1 2 3 4 5 6 7 8 9 10 11 12 13
| String one ="HELLO";
String two ="HELLO";
String three = new String("HELLO");
String four ="hello";
one == two ; // TRUE
one == three ; // FALSE
one == four ; // FALSE
one. equals(two ); // TRUE
one. equals(three ); // TRUE
one. equals(four ); // FALSE
one. equalsIgnoreCase(four ); // TRUE |
- 我明白这是对这个大问题的迟回答。我可以问一下现有答案中没有提到的内容吗?
- @神秘的,他增加了equalsIgnoreCase,这可能是提供信息的新鲜。
我同意扎切拉提的回答。
但你能做的是在非文字字符串上调用intern()。
来自Zacherates的例子:
1 2
| // ... but they are not the same object
new String("test") =="test" ==> false |
如果你实习的非文字字符串相等是true。
1
| new String("test"). intern() =="test" ==> true |
- 这通常不是个好主意。Interning相对昂贵,可以(矛盾地)>>increase<==进行字符串比较所带来的性能优势。
EDCOX1 0比较Java中的对象引用,对于EDCOX1和4个对象也不例外。
为了比较对象(包括String的实际内容),必须使用equals方法。
如果使用EDCOX1(0)将两个EDCOX1的4个对象进行比较,结果是true,那是因为EDOCX1×4个对象被交互,并且Java虚拟机具有多个引用指向EDCOX1×4的同一个实例。我们不应该期望用==作为true来比较一个String对象,该对象包含与另一个String对象相同的内容。
.equals()比较类中的数据(假设函数已实现)。==比较指针位置(对象在内存中的位置)。
如果两个对象(不讨论原语)指向同一对象实例,则==返回true。如果两个对象在Java中包含与EDCOX1和30相关的数据EDCOX1,30,则EDCOX1 1返回true。
那可能对你有帮助。
==执行引用相等性检查,这两个对象(本例中的字符串)是否引用内存中的同一个对象。
equals()方法将检查两个对象的内容或状态是否相同。
显然,==速度更快,但如果你想知道2个String是否持有相同的文本,在许多情况下会(可能)给出错误的结果。
当然,推荐使用equals()方法。
别担心性能。鼓励使用String.equals():
执行String.equals()首先检查引用是否相等(使用==),如果两个字符串通过引用相同,则不进行进一步的计算!
如果两个字符串引用不相同,String.equals()将接下来检查字符串的长度。这也是一个快速的操作,因为String类存储字符串的长度,不需要计算字符或代码点。如果长度不同,则不进行进一步检查,我们知道它们不能相等。
只有到目前为止,这两个字符串的内容才会被实际比较,这将是一个简短的比较:并不是所有的字符都会被比较,如果我们发现一个不匹配的字符(在两个字符串中的同一位置),就不会再检查其他字符。
当所有这些都说了又做了,即使我们保证字符串是实习生,使用equals()方法仍然不是人们可能认为的那种开销,这绝对是推荐的方法。如果您想要有效的引用检查,那么在语言规范和实现保证相同的枚举值将是相同的对象(通过引用)的情况下使用枚举。
- Obviously == is faster--实际上,.equals(String)的实施首先检查==,然后再做其他检查,所以我想说速度差不多是一样的。
- public boolean equals(Object anObject) { if (this == anObject) { return true; } ...
如果你像我一样,当我第一次使用Java时,我想使用"=="操作符来测试两个字符串实例是否相等,但不管是好是坏,这都不是Java中正确的方法。
在本教程中,我将演示几种不同的方法来正确地比较Java字符串,从我大部分时间使用的方法开始。在这个Java字符串比较教程的末尾,我还将讨论为什么在比较Java字符串时,"=="操作符不起作用。
选项1:与等值方法比较的Java字符串大部分时间(可能是95%的时间),我将字符串与Java字符串类的等值方法进行比较,如下所示:
1
| if (string1.equals(string2)) |
这个字符串等于方法查看两个Java字符串,如果它们包含完全相同的字符串,则它们被认为是相等的。
用equals方法查看一个快速字符串比较示例,如果运行以下测试,则不会认为两个字符串相等,因为字符不完全相同(字符的大小写不同):
1 2 3 4 5 6 7 8 9
| String string1 ="foo";
String string2 ="FOO";
if (string1. equals(string2 ))
{
// this line will not print because the
// java string equals method returns false:
System. out. println("The two strings are the same.")
} |
但是,当两个字符串包含完全相同的字符串时,equals方法将返回true,如本例中所示:
1 2 3 4 5 6 7 8 9
| String string1 ="foo";
String string2 ="foo";
// test for equality with the java string equals method
if (string1. equals(string2 ))
{
// this line WILL print
System. out. println("The two strings are the same.")
} |
选项2:与EqualSignoreCase方法的字符串比较
在一些字符串比较测试中,您将希望忽略字符串是大写还是小写。如果要以不区分大小写的方式测试字符串是否相等,请使用String类的EqualSignoreCase方法,如下所示:
1 2 3 4 5 6 7 8 9
| String string1 ="foo";
String string2 ="FOO";
// java string compare while ignoring case
if (string1. equalsIgnoreCase(string2 ))
{
// this line WILL print
System. out. println("Ignoring case, the two strings are the same.")
} |
选项3:与Ctraseto方法比较Java字符串
还有一种比较常见的第三种方法来比较Java字符串,也就是使用String类CaseReto方法。如果两个字符串完全相同,CompareTo方法将返回值0(零)。下面是这个字符串比较方法的一个简单示例:
1 2 3 4 5 6 7 8 9
| String string1 ="foo bar";
String string2 ="foo bar";
// java string compare example
if (string1. compareTo(string2 ) == 0)
{
// this line WILL print
System. out. println("The two strings are the same.")
} |
当我在Java中写这个关于平等的概念时,注意到Java语言在基本Java对象类中包含了一个平等方法。每当您创建自己的对象,并且希望提供一种方法来查看对象的两个实例是否"相等"时,应该重写(并实现)类中的这个相等方法(以Java语言在String Error方法中提供此相等/比较行为的方式)。
您可能想看看这个==、.equals()、compare to()和compare()。
- 对于字符串文本,如string string1="foo bar";string string2="foo bar";您可以直接使用==运算符来测试内容相等性
- 在谷歌应用程序中,"compareto"脚本是不可能的。我尝试安装"equals"这是唯一可行的解决方案…
功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public float simpleSimilarity (String u, String v ) {
String[] a = u. split("");
String[] b = v. split("");
long correct = 0;
int minLen = Math. min(a. length, b. length);
for (int i = 0; i < minLen ; i ++) {
String aa = a [i ];
String bb = b [i ];
int minWordLength = Math. min(aa. length(), bb. length());
for (int j = 0; j < minWordLength ; j ++) {
if (aa. charAt(j ) == bb. charAt(j )) {
correct ++;
}
}
}
return (float) (((double) correct ) / Math. max(u. length(), v. length()));
} |
测试:
1 2 3 4 5 6 7 8 9 10 11 12
| String a ="This is the first string.";
String b ="this is not 1st string!";
// for exact string comparison, use .equals
boolean exact = a. equals(b );
// For similarity check, there are libraries for this
// Here I'll try a simple example I wrote
float similarity = simple_similarity (a,b ); |
- 这与其他答案有何不同?为什么按你的建议做呢?
- @把关于==和equals之间的区别的问题标出来,已经有其他的解决方案来回答了,我只是提供了一种不同的方法来松散地比较字符串。
==运算符检查两个引用是否指向同一对象。.equals()检查实际字符串内容(值)。
注意,.equals()方法属于Object类(所有类的超级类)。您需要根据类需求重写它,但是对于字符串,它已经实现,并且它检查两个字符串是否具有相同的值。
==比较对象的参考值,而java.lang.String类中存在的equals()方法比较String对象(与另一个对象)的内容。
- 不挑剔,但String的equals()方法实际上是在String类中,而不是在Object类中。Object中的默认equals()不会比较内容相同,事实上,当引用相同时返回true。
- @雅各布肖恩:当grepcode关闭时,上述链接不再工作。下面是实现的替代方案:[内联链接](ZRePoCult.COM/Java/OpenJDK/100.2/Java.Base/Java/Lang//Helip);
我认为当你定义一个String时,你定义了一个对象。所以你需要使用.equals()。使用原始数据类型时,使用==,但使用String和任何对象时,必须使用.equals()。
- 还要注意,==不适用于char[]
- "char[]"不是基元数据类型!它是一个"char"数组。数组本身不是原始数据类型。
如果equals()方法存在于java.lang.Object类中,则需要检查对象状态的等效性!也就是说,对象的内容。而==操作符需要检查实际对象实例是否相同。
例子
考虑两个不同的参考变量,str1和str2:
如果你使用equals()。
1
| System. out. println((str1. equals(str2 ))?"TRUE":"FALSE"); |
如果使用==,则输出为TRUE。
1
| System. out. println((str1 ==str2 ) ?"TRUE" :"FALSE"); |
现在您将得到作为输出的FALSE,因为str1和str2都指向两个不同的对象,即使它们共享相同的字符串内容。这是因为new String()每次都会创建一个新对象。
operator==始终用于对象引用比较,而string class.equals()方法则用于内容比较:
1 2 3 4
| String s1 = new String("abc");
String s2 = new String("abc");
System. out. println(s1 == s2 ); // It prints false (reference comparison)
System. out. println(s1. equals(s2 )); // It prints true (content comparison) |
还可以使用compareTo()方法比较两个字符串。如果compareTo结果为0,则两个字符串相等,否则所比较的字符串不相等。
==比较引用,不比较实际字符串。如果确实使用new String(somestring).intern()创建了每个字符串,则可以使用==运算符比较两个字符串,否则只能使用equals()或compareto方法。
所有对象都保证有一个.equals()方法,因为对象包含一个返回布尔值的方法.equals()。如果需要进一步定义定义,则子类的任务是重写此方法。没有它(即使用==时),只检查两个对象之间的内存地址是否相等。字符串重写这个.equals()方法,它不使用内存地址,而是返回字符级别的字符串比较,以确保相等。
一个关键的注意事项是,字符串存储在一个块池中,所以一旦创建了一个字符串,它就永远存储在同一个地址的程序中。字符串不变,它们是不变的。这就是为什么如果您有大量的字符串处理要做,那么使用常规的字符串连接是一个坏主意。相反,您将使用提供的StringBuilder类。记住,指向这个字符串的指针可能会改变,如果您有兴趣查看两个指针是否相同,那么执行==是一个很好的方法。字符串本身没有。
- "一旦创建了一个字符串,它就永远存储在同一个地址的程序中"——这是完全错误的。只有编译时常量字符串表达式(可能涉及final String变量)和程序显式实习生的字符串存储在您所称的"块池"中。所有其他String对象都将在不再有活动引用时进行垃圾收集,就像任何其他类型的对象一样。此外,虽然整个实习机制需要不可变性来工作,但它在其他方面与此无关。
- 字符串比较可以通过Equals或EqualSignoreCase方法来完成,该方法实际比较字符串的内容。但==符号只需检查参考值。对于这种情况,字符串池中的字符串文本可以正常工作。string s1=new string("a");string s2=new string("a");在这种情况下,s1==s2为假,但s1.equals(s2)为真。
在Java中,when the"=="社is used to出现2检查对象,它的对象,参见if the to see to the same在记忆的地方。在其他的话,它检查看如果names are the 2对象的same to the references基本存储的位置。P></
the Java字符串类的equals()真的overrides the默认执行对象级和EN -茶overrides the method that only the values EN检查知道,not of the strings,在记忆的位置。This means that if You Call the method to equals()2出现的字符串对象,那么只要of characters is the actual序列都是平等的,平等的事情考虑的对象。P></
The == operator checks if the two strings are exactly the same object.
The .equals() method check if the two strings have the same value.
- 除非其中一个为空,因为如果s为空,s.equals(s2)将崩溃,导致比较失败。当然,这并不真正与答案相矛盾;这只是一个警告。
- 不,它不会崩溃,它会抛出NullPointerException,导致无法进行比较。