Java基础学习之字符串知识总结

一、前言

字符串是多个字符连接起来组合成的字符序列。字符串分为可变的字符串和不可变的字符串两种。

(1)不可变的字符串:当字符串对象创建完毕之后,该对象的内容(上述的字符序列)是不能改变的一旦内容改变就会创建一个新的字符串对象。Java中的String类的对象就是不可变的。

(2)可变的字符串:StringBuilder类和StringBuffer类的对象就是可变的;当对象创建完毕之后,该对象的内容发生改变时不会创建新的对象,也就是说对象的内容可以发生改变,当对象的内容发生改变时,对象保持不变,还是同一个。

String、StringBuffer、StringBuilder 都实现了 CharSequence 接口,字符串在底层其实就是char[],虽然它们都与字符串相关,但是其处理机制不同。

二、String 类(字符串常量)

String类表示不可变的字符串,当前String类对象创建完毕之后,该对象的内容(字符序列)是不变的,因为内容一旦改变就会创建一个一个新的对象。

String 类是final类,不可以继承。对String类型最好的重用方式是组合而不是继承。

2.1 String 类实例的创建

方式一:通过字面量赋值创建,需要注意这里是双引号:"",区别与字符char类型的单引号:'';

String s1 = "laofu";

方式二:通过构造器创建;

String s2 = new String(“laofu”);

两种方式的区别:

方式一:String s1 = “laofu”;

有可能只创建一个String对象,也有可能创建不创建String对象;如果在常量池中已经存在”laofu”,那么对象s1会直接引用,不会创建新的String对象;否则,会先在常量池先创建常量”laofu”的内存空间,然后再引用。

方式二:String s2 = new String(“laofu”);

最多会创建两个String对象,最少创建一个String对象。可使用new关键字创建对象是会在堆空间创建内存区域,这是第一个对象;然后对象中的字符串字面量可能会创建第二个对象,而第二个对象如方式一中所描述的那样,是有可能会不被创建的,所以至少创建一个String个对象。

上图中的常量池:用于存储常量的地方内存区域,位于方法区中。常量池又分为编译常量池和运行常量池两种:

编译常量池:当把字节码加载进JVM的时候,其中存储的是字节码的相关信息(如:行号等)。

运行常量池:其中存储的是代码中的常量数据。

① 使用字符串字面量创建的字符串,也就是单独使用""引号创建的字符串都是直接量,在编译期就会将其存储到常量池中;

② 使用new String("")创建的对象会存储到堆内存中,在运行期才创建;

③ 使用只包含直接量的字符串连接符如"aa" + "bb"创建的也是直接量,这样的字符串在编译期就能确定,所以也会存储到常量池中;

④ 使用包含String直接量的字符串表达式(如"aa" + s1)创建的对象是运行期才创建的,对象存储在堆中,因为其底层是创新了StringBuilder对象来实现拼接的;

2.2 String 对象的比较

① 使用”==”号:用于比较对象引用的内存地址是否相同

② 使用equals方法:在Object类中和”==”号相同,但在自定义类中,建议覆盖equals方法去实现比较自己内容的细节;由于String类覆盖已经覆盖了equals方法,所以其比较的是字符串内容

2.3 String对象的空值

① 对象引用为空, 此时s1没有初始化,也在JVM中没有分配内存空间。

String s1 = null; 

② 对象内容为空字符串, 比如: 此时对象s2已经初始化,值为“”,JVM已经为其分配内存空间。

String s2 = "";

2.4 字符串拼接

Java中的字符串可以通过是“+”实现拼接,那么代码中字符串拼接在JVM中又是如何处理的呢?我们通过一个例子说明:通过比较拼接字符串代码编译前后的代码来查看JVM对字符串拼接的处理。

JVM会对字符串拼接做一些优化操作。

① 如果字符串字面量之间的拼接(如"aa" + “bb”),创建的也是直接量,这种情况在编译期就能确定,所以也会存储到常量池中

② 如果是对象之间拼接,或者是对象和字面量之间的拼接,亦或是方法执行结果参与拼接,String内部会使用StringBuilder先来获取对象的值,然后使用append方法来执行拼接。这种情况只能在运行期才能确定变量的值和方法的返回值。

三、StringBuilder 与 StringBuffer(字符串变量)

StringBuffer 和 StringBuilder都表示可变的字符串,两种的功能方法都是相同的。但唯一的区别:

(1)StringBuffer:StringBuffer中的方法都使用了synchronized修饰符,表示同步操作,在多线程并发的时候可以保证线程安全,但在保证线程安全的时候,对其性能有一定影响,会降低其性能

(2)StringBuilder:StringBuilder中的方法都没有使用了synchronized修饰符,线程不安全,正因为如此,其性能较高

对并发安全没有很高要求的情况下,建议使用StringBuilder,因为其性能很高。

四、String、StringBuilder 与 StringBuffer

(1)由于 String 类的操作是产生新的 String 对象,而 StringBuilder 和 StringBuffer 只是一个字符数组的扩容而已,所以 String 类的操作要远慢于 StringBuffer 和 StringBuilder。

大部分情况下:StringBuilder > StringBuffer > String

String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象。每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。

而如果是使用 StringBuffer 类则结果就不一样了,每次结果都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,再改变对象引用。

(2)使用选择

使用 String 类的场景:在字符串不经常变化的场景中可以使用 String 类,例如常量的声明、少量的变量运算。

使用 StringBuffer 类的场景:在频繁进行字符串运算(如拼接、替换、删除等),并且运行在多线程环境中,则可以考虑使用 StringBuffer,例如 XML 解析、HTTP 参数解析和封装。

使用 StringBuilder 类的场景:在频繁进行字符串运算(如拼接、替换、和删除等),并且运行在单线程的环境中,则可以考虑使用 StringBuilder,如 SQL 语句的拼装、JSON 封装等。

到此这篇关于Java基础学习之字符串知识总结的文章就介绍到这了,更多相关Java字符串内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java 常量字符串过长的解决方法

    问题出现 在IDEA中,字符串长度超过65535,进行打印,IDEA会提示java: 常量字符串过长.使用javac 进行编译也会有类似的提示 解决办法 使用StringBuilder StringBuilder sb = new StringBuilder(); sb.append("String"); sb.append("String"); String str = sb.toString(); String[] parts = str.split("

  • Java8优雅的字符串拼接工具类StringJoiner实例代码

    StringJoiner是Java8新出的用于处理字符串拼接的工具类,可以让你的代码看起来更优雅,不拉跨. 假设现在遍历一个字符串集合,需求是每个元素按照 "." 分开. String a = "w", b = "d", c = "n", d = "m", e = "d"; List<String> list = new ArrayList<>(); list.a

  • Java 比较字符串实例详解

     Java 比较字符串实例详解 公司让实现一个自动清除1小时内数据,SQL不熟悉,无奈之下,只能本地DB存储当前时间+小时去和当前时间进行比对.折腾好半天,突然想到Java提供了一个方法,也是进行字符串比较的,傻眼了.一起来看看吧~ CompareTo()方法简介 首先,它属于java.lang.String包下,是Java提供的一个字符串比较的方法,详情介绍如下: CompareTo()返回值: int 返回值类型分别有三种,小于0,等于0,大于0 1. 如果字符串相等返回值0: 2. 如果第

  • Java将Date日期类型字段转换成json字符串的方法

    想必我们在做项目的时候,都会遇到服务端与客户端交互数据.一般情况下我们都会采用json格式或者xml格式,将服务端的数据转换成这两种格式之一. 但是,如果我们将数据转换成json格式的时候,我们也许会遇到Date日期型的数据转换成json格式后,并不是我们想要的格式.下面我们通过简单的demo 来说明这个问题. 我们按照一般json格式生成,会出现以下问题: 采用json:将数据生成json格式,需要导入相应的jar包,如下图: Student.java package com.xbmu.bea

  • Java 实现repalceAll只替换第二个匹配到的字符串

    String replace replaceFirst repaceAll区别 replace(char oldChar, char newChar) 返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的. replaceAll(String regex, String replacement) 使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串 replaceFirst(String regex, String rep

  • Java String类简单用法实战示例【字符串输出、比较】

    本文实例讲述了Java String类简单用法.分享给大家供大家参考,具体如下: 一 String类的实例化方式 1 代码 public class NewString { public static void main(String args[]) { String str1= "Hello World!"; // 直接赋值建立对象str1 System.out.println("str1:" + str1) ; //输出 String str2 = new St

  • java字符串格式化输出实例讲解

    代码如果不进行格式化的处理,那么在查阅上会浪费不少的时间.今天我们要说的是字符串的格式化处理,作为基础编程内容,相信大家都字符串都不陌生.我们可以把字符串进行连接,通过这种方法实现格式化的操作.下面我们就格式化的说明.字符串符号图解.实例带来介绍. 1.说明 java 在 JDK1.5 后对 PrintStream 功能进行了扩充,增加了格式化输出功能.直接使用 Print 即可.但是输出的时候需要指定输出的数据类型. 如果不使用格式化输出,就需要进行字符串连接,如果变量比较多,拼接就会显得繁琐

  • 浅谈java字符串比较到底应该用==还是equals

    当用new String("aaaa")对字符串做定义时,==会返回false,equals可以返回正常结果. 比如 System.out.println("a" == "a"); //true System.out.println("a".equals("a")); //true System.out.println("a".equals(new String("a"

  • java 替换docx文件中的字符串方法实现

    替换docx文件里面的 ${} 字符串 public class Main { public static void main(String[] args) throws Exception { String template = "C:\\Users\\lzh\\Desktop\\模板.docx"; String outSrc = "C:\\Users\\lzh\\Desktop\\简历.docx"; var is = new FileInputStream(te

  • java求数组元素重复次数和java字符串比较大小示例

    复制代码 代码如下: /** * Name: 求数组中元素重复次数对多的数和重复次数 * Description:  * 数组中的元素可能会重复,这个方法可以找出重复次数最多的数,同时可以返回重复了多少次. * 但需要知道这个数组中最大的元素是多少,如果无法确定,就悲剧啦~ * * @param array目标数组: *           max数组中数据的最大值: * @return 返回一个包含重复次数最多的数(value)和重复次数(maxCount)的map集合: *         

  • Java字符串比较方法equals的空指针异常的解决

    在Java语言中字符串比较有两种方式:== 和equals(). "=="比较的是针对两个String类型变量的引用,当两个String类型的变量指向同一个String对象(即同一个内存堆),则返回true.而equals()方法是对String对象封装的字符串内容进行比较,相同返回true. 在用equals方法与其他值做比较的时候,有可能会导致抛出空指针异常.写一个小程序来举例说明: public class StringEqual { public static void equ

  • java中利用栈实现字符串回文算法

    问题 给定一个由多个a和b组成的字符串数组,字符串中有一个特殊的字符X,位于字符串的正中间,例如(aaaabbbbXabaabbbb),如何判定该字符串是否回文 简单算法 定义两个下标分别指向字符串的头和尾,每次比较两个下标位置的值是否相等,如果不相等,那么输入的 字符串不是回文,如果相等,左边的下表加1,右边的下表减1,重复上述步骤直至两个下标都指向字符串的正中间或者确定字符串不是回文 /** * 判断字符串是否是回文 */ public int isPalindrome(String inp

  • Java字符串的压缩与解压缩的两种方法

    应用场景 当字符串太长, 需要将字符串值存入数据库时,如果字段长度不够,则会出现插入失败: 或者需要进行Http传输时,由于参数长度过长造成http传输失败等. 字符串压缩与解压方法 方法一:用 Java8中的gzip /** * 使用gzip压缩字符串 * @param str 要压缩的字符串 * @return */ public static String compress(String str) { if (str == null || str.length() == 0) { retu

  • Java8 将List转换为用逗号隔开的字符串的多种方法

    1.使用谷歌的Joiner转换 public static <T> String parseListToStr(List<T> list){ String result = Joiner.on(",").join(list); return result; } 2.使用lambda表达式遍历集合 public static <T> String parseListToStr2(List<T> list){ StringBuffer sb

  • java中常用的字符串的比较方法(两种)

    比较字符串比较常用的两个方法是运算符"="和String的equals方法. 使用"="比较两个字符串,是比较两个对象的的"地址"是否一致,本质就是判断两个变量是否指向同一个对象,如果是则返回true,否则返回的是false.而String类的equals方法则是比较两个字符串的内容是否一致,返回值也是一个布尔类型. 看下面的代码: public class TestString{ public static void main(String[]

  • 解决java 分割字符串成数组时,小圆点不能直接进行分割的问题

    问题描述: String preStr = "a.b.c"; // 这里要把该字符串按小圆点进行分割,成"a","b","c" String[] string = preStr.split("."); // 直接这样写是不行的 正确的写法是,对小圆点进行转义 String[] string = preStr.split("\\."); 补充知识:Java中不使用split方法实现字符串分

随机推荐