相同字符串,但是equals为false?我多年的java白学了吗?
作者:Sicimike
blog.csdn.net/Baisitao_/article/details/92667122
前言
有时候写代码会遇到一些莫名其妙的问题,两个字符串明明toString()打印一模一样,但是equals就是为false。
问题
直接看代码
public static void main(String[] args) {String s1 = "helloworld";String s2 = "helloworld";System.out.println(s1.equals(s2));
}
这代码应该够简单了,毫无疑问输出true啊。但是我们还是实际操作一下:
这是什么情况,居然输出了false,我多年的java白学了吗?
结论
其实这个问题很简单,因为字符串s1中包含了不可打印字符
,可以把两个字符串复制到 QQ/TIM 看一下就知道了,或者直接按F12审查元素也可以看到。或者我们继续在Java代码中查看
public static void main(String[] args) {String s1 = "helloworld";String s2 = "helloworld";System.out.println(s1.equals(s2));System.out.println(Arrays.toString(s1.getBytes()));System.out.println(Arrays.toString(s2.getBytes()));
}
这下应该很清楚的知道了为什么两个字符串toString()看起来一样,但是equals却为false。
不可见字符从哪来
说一个最常见的场景,window下新建一个test.txt文件(用window自带的记事本),随便写点什么,就“helloworld”吧。保存(另存为)的时候选择UTF-8编码。
这种方式保存的文件,window会在文件头部添加一个字符,叫做BOM(byte-order mark,字节顺序标记)以UTF-8编码时是三个字节,分别是EF BB BF
,用来标记这是一个UTF8编码的文件。程序读取文件时,会把BOM头一起读入内存:
public static void compareContent() {InputStream is = null;try {is = new FileInputStream(new File("D:\\test.txt"));byte[] buff = new byte[16];int nRead = 0;StringBuilder sb = new StringBuilder();while ((nRead = is.read(buff)) != -1) {sb.append(new String(buff, 0, nRead));}//UTF-8文件读取的字符串String fileStr = sb.toString();//程序定义的字符串,此处不包含不可打印字符String localStr = "helloworld";System.out.println(fileStr.toString());System.out.println(localStr.toString());System.out.println("文件字符串:" + Arrays.toString(fileStr.getBytes()));System.out.println("本地字符串:" + Arrays.toString(localStr.getBytes()));} catch (IOException e) {e.printStackTrace();} finally {if (is != null) {try {is.close();} catch (IOException e) {e.printStackTrace();}}}}
运行结果如下:
除了前三个字节,后面的内容其实是一模一样的。
解决办法
如果文件非要以UTF-8编码保存,可以有以下几种方法:
保存的时候去掉BOM头(notepad++支持以UTF-8无BOM格式编码)
程序做兼容,兼容代码如下:
public static String deleteUTF8Bom(String fileStr) {byte[] UTF8_BOM_BYTES = new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF};byte[] bytes = fileStr.getBytes();if (bytes[0] == UTF8_BOM_BYTES[0]&& bytes[1] == UTF8_BOM_BYTES[1]&& bytes[2] == UTF8_BOM_BYTES[2]) {return new String(bytes, 3, bytes.length - 3);}return fileStr;
}
总结
这个问题不太容易发现,但是其实也是属于基础内容。也说明眼见不一定为实,看到的字符串不一定就是真正的字符串。
@Autowire和@Resource注解使用的正确姿势,这些年我一直用错了!!
华为面试官:为什么 HashMap 的加载因子是0.75?
强大:MyBatis 流式查询
华为面试官:为什么 HashMap 的加载因子是0.75?
SpringBoot+OAuth2+JWT实现单点登录SSO完整教程,竟如此简单优雅!
趣头条面试题:ThreadLocal是什么?怎么用?为什么用它?有什么缺点
Springboot启动扩展点超详细总结,再也不怕面试官问了
趣头条面试题:ThreadLocal是什么?怎么用?为什么用它?有什么缺点
List去除重复数据的五种方式,学到了...
SpringBoot操作ES进行各种高级查询(必须收藏)
点击阅读全文前往微服务电商教程
相同字符串,但是equals为false?我多年的java白学了吗?相关推荐
- 可怕!原来我们看到的世界地图一直都是“错”的!多年的地理白学了...
▲ 点击查看 几乎每个家庭都会有两张地图:一张世界地图,一张中国地图. 薄薄的两张纸,蕴藏着让每个人学会"看世界"的磅礴力量. 哈佛上一任校长,也是300多年来唯一一位女校长德鲁· ...
- 原来我们看到的世界地图竟这样震撼!多年的地理白学了...
▲ 点击查看 几乎每个家庭都会有两张地图:一张世界地图,一张中国地图. 薄薄的两张纸,蕴藏着让每个人学会"看世界"的磅礴力量. 哈佛上一任校长,也是300多年来唯一一位女校长德鲁· ...
- JAVA中String字符串比较equals()和equalsIgnoreCase()的区别
标签: equals和equalsIgnoreC 2012-11-11 16:03 65644人阅读 评论(0) 收藏 举报 分类: JAVA(3) 1.使用equals( )方法比较两个字符串是 ...
- JAVA中字符串比较equals()和equalsIgnoreCase()的区别
1.使用equals( )方法比较两个字符串是否相等.它具有如下的一般形式: boolean equals(Object str) 这里str是一个用来与调用字符串(String)对象做比较的字符串( ...
- java equals equalsignorecase 性能_JAVA中字符串比较equals()和equalsIgnoreCase()的区别
JAVA中字符串比较equals()和equalsIgnoreCase()的区别 1.使用equals( )方法比较两个字符串是否相等.它具有如下的一般形式: boolean equals(Objec ...
- python中运行结果为false-python 两个一样的字符串用==结果为false问题的解决
有时候我们需要判断两个字符串内容是否相等,判断内容相等,我们用"==",但是有时候发现print(str1)和print(str2)眼看着一模一样,但是用==时却是false 可能 ...
- python字符串equals方法_判断字符串相等-Equals(上)
本次课程是零基础课程,只要熟悉计算机的基本应用和操作,一般可以完成本次课程学习.本课程深入浅出的介绍了C#语言的基本语法结构.条件选择.循环.异常处理.数组.集合.值类型和应用类型.字符串的常用方法. ...
- java学习中,字符串使用(比较、构造方法)(java 学习中的小记录)
java学习中,字符串使用(比较.构造方法)(java 学习中的小记录)作者:王可利(Star·星星) String的使用 1.在内存中是如何保存字符串. == :比较的是地址(引用数据类型) equ ...
- Java从键盘输入n行字符串_Java十四天零基础入门-Java布尔类型
不闲聊!!!不扯淡!!!小UP只分享Java相关的资源干货 Java布尔类型 在Java语言中布尔类型的值只包括true和false,没有其他值,不包括1和0,布尔类型的数据在开发中主要使用在逻辑判断 ...
最新文章
- mysql1401错误_mysql错误代号-I(1401~1450)
- 数组---进制转换(查表法)
- docker es持久化_Docker 搭建 ES 集群并整合 Spring Boot
- WordPress 常用快捷键列表
- 新SQL Server 2016示例数据库
- 揭开 Python 内存分配时的小秘密!
- Hadoop——Yarn(4)
- OC中方法与函数的区别
- 基于Matlab的hdb3编译码设计,基于MATLAB的HDB3编译码实现
- Radius协议简单介绍
- 实体连锁电商会员运营方案
- python中re模块的span_python3正则模块re的使用方法详解
- 联发科:上半年营收2980亿台币,下半年全面发力5G芯片,并布局6G
- 《近代名老中医经验集》出版
- D. Little Girl and Maximum XOR(贪心)
- Windows redis最新版本5.0.9下载
- RPA 的优点与缺点
- mininet构建双路由器实验
- 小程序直播,助力教育机构获客
- R语言ARIMA集成模型预测时间序列分析