Java:字符串用==比较相等失效问题

文章目录

  • 前言
  • 一、字符串比较两字符串相等的方式
  • 二、Java中字符串存储的方式
    • 1.公共存储池
    • 2.何时会创建新的位置
    • 3.创建新位置的解释
  • 三、字符串比较方式
  • 总结

前言

之前在写Android项目时,从数据库中读出字符串,与代码中存在的明文字符串用==比较时,发生了两个字符串字面量相等,却比较结果不相等的问题,回归Java基础思考过后做出如下的解释。

一、字符串比较两字符串相等的方式

学过Java的同学都知道,Java比较两个字符串相等时,通常情况下有两种方式

  • equals()方法
  • A==B判等

我们学习Java的时候肯定老师视频或者书肯定推荐过使用第一种方式,但是我们在对字符串进行判空或者偶尔对本地字符串进行比较的时候,偶尔也可以使用==方式进行,就像如下情况似乎也可以成功,那么是怎么一回事呢。
Java:字符串用==比较相等失效问题_第1张图片

二、Java中字符串存储的方式

1.公共存储池

想要搞清楚上述的问题,我们必须先了解Java中字符串的存储方式:在Java中,你可以想象各种字符串存放在公共的存储池中,而字符串变量指向字符串公共存储池中的位置;如果你在程序运行内部复制字符串变量或是创建两个字面值一模一样的字符串,实际上新的变量并不会在字符串公共存储池中开辟新的空间,而是直接指向原来的字符串公共存储池中的位置。

如上述程序中的a和b,在创建时,都给他们赋予了相同的字面值——“111111”,但实际上指向了同一块字符串存储池中的位置

2.何时会创建新的位置

先说答案

  • 字符串+或subtstring拼接或取子串操作
  • StringBuffer/StringBuilder最后一步toString()方法产出的字符串
  • 从外部存储区域读入字符串变量,如数据库中读入

3.创建新位置的解释

  • 字符串拼接操作/取子串操作,每次都会将拼接或完成产生的新结果,放入到字符串池中,而后将字符串变量指向那一块存储区域。
  • StringBuffer/StringBuilder会产生一块缓存区域,每次往里面放新的字符串子串时,并不会写到字符串存储池中,而是先放到缓存区域,这样坐相比较子串拼接/取子串操作毫无疑问会大大提高效率,而最后一次toString()方法,才会将字符串放入到字符串存储池中。
  • 外部存储区域读入,参考StringBuffer,应是存在缓存区域,而后放入字符串存储池中产生新的字符池位置

补充一句:
StringBuffer/StringBuilder性能非常好,但是前者支持多线程,后者只支持单线程;前者效率相对较低,后者效率相对较高。这里指的较低只是他们二者比较,StringBuffer就算性能再低,读入时也是Scanner的10倍及以上

三、字符串比较方式

知道了上述知识,那我们继续分析字符串两种比较方式的本质:

  • ==只能够确定两个字符串是否位于字符串存储池中的位置是否相等,完全有可能,“111111"和"111”+"111"拼接出来的字符串字面值相等,但他们在字符串存储池中的位置不等,从而导致比较失败
  • equals("")方法比较的是二者的哈希值是否相等,而手写过字符串生成哈希值的小伙伴都知道,同一种哈希方法,两个字面值相等的字符串生成的哈希值绝对是相等的,我有时间的话开一篇博客把字符串生成哈希值的算法放上来。

总结

以上就是笔者对Java中字符串的理解,供大家参考,笔者最近太忙了, 本来想画画图帮助大家理解的,但是实在没有时间,碰到相关问题的小伙伴将就着看一下吧,有不懂或者想要指教的给笔者留言,感谢了。

你可能感兴趣的:(#,Java,后端,#,操作系统,java,开发语言,后端)