String#equals和String#contentEquals方法之间的区别

如何解决String#equals和String#contentEquals方法之间的区别

||
String#equals
方法和
String#contentEquals
方法有什么区别?     

解决方法

        
String#equals()
不仅比较String的内容,还检查另一个对象是否也是
String
的实例。 “ 4”仅比较内容(字符序列),不检查其他对象是否也是“ 3”的实例。只要是涵盖A.o的
CharSequence
的实现,它就可以是任何东西。
String
StringBuilder
StringBuffer
CharBuffer
等。     ,        简单地说:ѭ11是
String.equals()
的聪明兄弟,因为它在实现上比implementation12ѭ更自由。 有某些原因导致使用单独的“ 11”方法。我认为最重要的原因是:
equals
方法必须自反。那意味着:
x.equals(y) == y.equals(x)
。这意味着
aString.equals(aStringBuffer)
必须与as18ѭ相同。这将需要Java API开发人员在StringBuffer,StringBuilder和CharSequence的“ 19”方法中对String进行一些特殊的实现。这将是一团糟。 因此,这就是
String.contentEquals
出现的时候。这是一种独立的方法,不必遵循
Object.equals
的严格要求和规则。这样,您可以更自由地实现“平等内容”的感觉。例如,这使您可以在StringBuffer和String之间进行智能比较。 再说一下到底有什么区别:
String.contentEquals()
可以比较
String
,a8ѭ,a9ѭ,a6ѭ以及它们所有派生类的内容。如果参数的类型为String,则执行
String.equals()
String.equals()
仅比较String对象。所有其他对象类型均视为不相等。
String.contentEquals()
可以智能地比较
StringBuffer
StringBuilder
。它不会调用笨拙的“ 32”方法,该方法会将整个内容复制到新的String对象。相反,它与底层的“ 33”数组进行了比较,这很棒。     ,        这个答案已经由dbw发布,但是他删除了,但是在比较执行时间,抛出什么异常, 如果查看源代码String#equals和String#contentEquals,很显然,对于
String#contentEquals
有两种覆盖的方法,其中一种采用
StringBuilder
,而另一些采用
CharSequence
。 他们之间的区别 如果提供的参数为
null
,则
String#contentEquals
将抛出NPE,但
String#equals
将返回
false
String#equals
仅在提供的参数为
instance of String
时比较内容,否则在所有其他情况下将返回
false
,但另一方面
String#contentEquals
检查实现接口
CharSequence
的所有对象的内容。 您还可以调整代码,以使
String#contentEquals
返回错误的结果或想要的结果,方法是重写传递的参数的
equals
方法,如下所示,但不能对
String#equals
进行那些调整。 只要
s
包含任何3个字符长的
string
,下面的代码将始终生成
true
    String s= new String(\"abc\");// \"abc\";
    System.out.println(s.contentEquals(new CharSequence() 
    {

        @Override
        public CharSequence subSequence(int arg0,int arg1) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public int length() {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public char charAt(int arg0) {
            // TODO Auto-generated method stub
            return 0;
        }


        @Override
        public boolean equals(Object obj) 
        {
           return true;
        }
    }));
如果提供的参数是
instance of String
并且两个
String
的长度相同但内容不相等,则
String#contentEquals
会比
String#Equals
慢。 例如,如果字符串是
String s = \"madam\"
String argPassed = \"madan\"
,那么
s.contentEquals(argPassed)
将比
s.equals(argPassed)
花费几乎两倍的执行时间。 如果两个字符串的内容长度都不相同,则在几乎所有可能的情况下,函数
String#contentEquals
的性能将优于then54。 还有一点要补充
String
对象中的
String#contentEquals
也将与
StringBuilder
的内容进行比较并提供适当的结果,而
String#Equals
将返回
false
    ,        
contentEquals(CharSequence cs)
: 让您检查给定字符串值与接口
java.lang.CharacterSequence
的任何实现实例是否相等(例如
CharBuffer
Segment
String
StringBuffer
StringBuilder
equals(Object anObject)
: 可让您仅使用
java.lang.String
类型的任何实例检查给定字符串值的相等性 RTFC :) 由于阅读源代码是理解它的最佳方式,因此我将分享这两种方法的实现(自jdk 1.7.0_45起)
public boolean contentEquals(CharSequence cs) {
    if (value.length != cs.length())
        return false;
    // Argument is a StringBuffer,StringBuilder
    if (cs instanceof AbstractStringBuilder) {
        char v1[] = value;
        char v2[] = ((AbstractStringBuilder) cs).getValue();
        int i = 0;
        int n = value.length;
        while (n-- != 0) {
            if (v1[i] != v2[i])
                return false;
            i++;
        }
        return true;
    }
    // Argument is a String
    if (cs.equals(this))
        return true;
    // Argument is a generic CharSequence
    char v1[] = value;
    int i = 0;
    int n = value.length;
    while (n-- != 0) {
        if (v1[i] != cs.charAt(i))
            return false;
        i++;
    }
    return true;
}
public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String) anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                        return false;
                i++;
            }
            return true;
        }
    }
    return false;
 }
还有另一个String#contentEquals()方法:
public boolean contentEquals(StringBuffer sb) {
    synchronized(sb) {
        return contentEquals((CharSequence)sb);
    }
}
    ,
String
equals(Object o)
方法仅进行does3ѭ比较。但是
contentEquals(CharSequence cs)
类的检查扩展了
AbstractStringBuilder
类,即
StringBuffer
StringBuilder
String
类(它们都是
CharSequence
类型)。
String str = \"stackoverflow\";
StringBuilder builder = new StringBuilder(str);
System.out.println(str.equals(builder));
System.out.println(str.contentEquals(builder));
输出:
false
true
first stmt的输出为
false
,因为
builder
不是
String
类型,因此
equals()
返回
false
,但是
contentEquals()
检查所有类型的内容,如
StringBuilder
StringBuffer
String
,并且内容相同,因此为
true
。 如果提供的参数是
null
,则
contentEquals
将抛出
NullPointerException
,但equal19ѭ将返回false,因为equals()检查instanceOf(
if (anObject instance of String)
),如果参数是
null
,则返回false。     ,        
equals()
contentEquals()
String
类中的两种方法,用于将两个
strings
string
StringBuffer
进行比较。
contentEquals()
的参数为
StringBuffer
String(charSequence)
equals()
用于比较两个
strings
contentEquals()
用于比较
String
StringBuffer
的内容。 方法
contentEquals
equals
public boolean contentEquals(java.lang.StringBuffer);
public boolean contentEquals(java.lang.CharSequence);
public boolean equals(Object o)
这是描述两种方法的代码
public class compareString {
    public static void main(String[] args) {
        String str1 = \"hello\";    
        String str2 = \"hello\";

        StringBuffer sb1 = new StringBuffer(\"hello\");
        StringBuffer sb2 = new StringBuffer(\"world\");

        boolean result1 = str1.equals(str2);        // works nice and returns true
        System.out.println(\" str1.equals(str2) - \"+ result1);

        boolean result2 = str1.equals(sb1);         // works nice and returns false
        System.out.println(\" str1.equals(sb1) - \"+ result2);

        boolean result3 = str1.contentEquals(sb1);  // works nice and returns true
        System.out.println(\" str1.contentEquals(sb1) - \"+ result3);

        boolean result4 = str1.contentEquals(sb2);  // works nice and returns false
        System.out.println(\" str1.contentEquals(sb2) - \"+ result4);

        boolean result5 = str1.contentEquals(str2);  // works nice and returns true
        System.out.println(\" str1.contentEquals(str2) - \"+ result5);
    }
}
输出:
 str1.equals(str2) - true
 str1.equals(sb1) - false
 str1.contentEquals(sb1) - true
 str1.contentEquals(sb2) - false
 str1.contentEquals(str2) - true
    ,        
contentEquals()
方法检查的是are3ѭ,
StringBuffer
等某种字符序列的内容是否相同。     ,        String#equals将Object作为参数,并检查其是否为String对象的实例。如果参数对象是字符串对象,则它将逐字符比较内容。如果两个字符串对象的内容相同,则返回true。 String#contentEquals将CharSequence接口作为参数。 CharSequence可以通过两种方式实现-通过使用i)字符串类或(ii)AbstractStringBuilder(StringBuffer,StringBuilder的父类) 在contentEquals()中,将在检查任何对象实例之前比较长度。如果长度相同,则检查参数对象是否为AbstractStringBuilder的实例。如果是这样(即StringBuffer或StringBuilder),则逐字符检查内容。如果参数是String对象的实例,则从String#contentEquals调用String#equals。 简而言之, 如果参数也是String对象,则String#equals逐字符比较内容。如果参数对象实现CharSequence接口,则String#contentEquals比较内容。 万一我们比较两个相同长度的字符串内容,因为String#contentEquals内部调用String#equals作为String对象,则String#contentEquals速度会变慢。 如果我们尝试比较内容长度不同的对象(例如\“ abc \”与\“ abcd \”),则String#contentEquals比String#equals更快。因为长度是在任何对象实例检查之前进行比较的。     ,        顺便说一句,造成这种差异的历史原因是String最初没有超类,因此String.equals()将String作为其参数。当CharSequence作为String的超类引入时,它需要自己的一个相等性测试,该测试适用于所有CharSequence实现,并且不会与String已经使用的equals()相冲突...因此我们得到了CharSequence.contentEquals( ),由String继承。 如果Java 1.0中已经存在CharSequence,那么我们可能只具有CharSequence.equals()而String会简单地实现它。 啊,不断发展的语言所带来的乐趣...     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-