一篇让你读懂java中的字符串(String)(三)

简介: 一篇让你读懂java中的字符串(String)(三)

字符串替换处理

使用一个指定的新的字符串替换掉已有的字符串数据,可用的方法如下:

2.png


代码示例1:replaceAll方法

String str = "helloworld" ;
//结果为he__owor_d
System.out.println(str.replaceAll("l", "_"));

代码示例2:replaceFirst方法

String str = "helloworld" ;
//结果为he_loworld
System.out.println(str.replaceFirst("l", "_"));

代码示例3::replace方法

String str = "helloworld" ;
//结果为he__owor_d
System.out.println(str.replace("l", "_"));

可以发现replace方法与replaceAll方法的效果一样

来看下replace方法的源码吧:

2.png

可以看到replace方法的底层代码中的参数是CharSequence类型,但是我们自己传参的时候是string类型,这是为什么呢?

答:是因为发生了向上转型,String类实现了CharSequence这个接口,如下图所示:

2.png


注意事项: 由于字符串是不可变对象, 替换不修改当前字符串, 而是产生一个新的字符串


字符串拆分(用的非常多,需要多注意)

可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串。

可用方法如下:

2.png


代码示例1:split(String regex)方法

split方法返回的是一个String类型的数组,以下是多次拆分的代码,以后会经常出现

        String str = "username=zhangsan&password=123";
        //以“&”这个符号进行切割,切割一次后为username=zhangsan    password=123
        String[] strings = str.split("&");
        for (int i = 0; i < strings.length; i++) {
            //继续对第一次切割后的字符串进行切割
            String[] strings1 = strings[i].split("=");
            for (int j = 0; j < strings1.length; j++) {
            /*最终结果为:
            username
            zhangsan
            password
            123
            */
                System.out.println(strings1[j]);
            }
        }

还有我们会在leetcode刷题的时候经常遇见的使用空格来进行分割:

public class TestDemo5 {
    public static void main(String[] args) {
        //注意此处bcd与def之间有两个空格
        String str = "abc bcd  def";
        String[] str1 = str.split(" ");
        for (String s : str1) {
            System.out.println(s);
        }
    }
}
//输出结果为
abc
bcd
def

代码示例2:split(String regex,int limit)方法

limit=1说明只分了一组

        String str = "username=zhangsan&password=123";
        String[] strings = str.split("&",1);
        for (int i = 0; i < strings.length; i++) {
            //输出结果为username=zhangsan&password=123
            System.out.println(strings[i]);
        }

limit=2说明分为两组

        String str = "username=zhangsan&password=123";
        String[] strings = str.split("&",2);
        for (int i = 0; i < strings.length; i++) {
            /*输出结果为:
            username=zhangsan
            password=123
            */
            System.out.println(strings[i]);
        }

拆分是特别常用的操作. 一定要重点掌握. 另外有些特殊字符作为分割符可能无法正确切分, 需要加上转义


代码示例3:特殊情况

情况1:拆分ip地址这类(单个分隔符)

String str = "192.168.1.1" ; 
String[] result = str.split("\\.") ; 
for(String s: result) {
 /*输出结果为
 192
 168
 1
 1
 */
    System.out.println(s);
}

像ip地址这种拆分的时候,如果是拿点号(.)进行拆分的话,需要进行转义,第一次转义是转义点号,第二次转义是保留转义符号的作用,意思就是让第一个\作为转义符号来使用


情况2:多个分隔符的拆分(使用连字符“|”)

        String str = "java-split#bit";
        //用|作为连字符,将-和#这两个分隔符进行拆分
        String[] strings = str.split("-|#");
        for (int i = 0; i < strings.length; i++) {
            /*输出结果为:
               java
               split
               bit
            */
            System.out.println(strings[i]);
        }

注意事项:


字符"|“,”*“,”+“都得加上转义字符,前面加上”\"


而如果是"“,那么就得写成”\\".


如果一个字符串中有多个分隔符,可以用"|"作为连字符.


字符串截取

从一个完整的字符串之中截取出部分内容。可用方法如下:

2.png


代码示例1:substring(int beginIndex)方法

        String str = "abcdefg";
        String str1= str.substring(3);
        //输出结果为:defg
        System.out.println(str1);

注意事项:


索引从0开始,3就是索引为3所对应的那个数字,也就是d


代码示例2:substring(int beginIndex,int endIndex)

        String str = "abcdefg";
        String str1= str.substring(0,5);
        //输出结果为:abcde
        System.out.println(str1);

从0下标开始截取,截取到4号下标,不包含5号下标所对应的字符

注意事项:


注意前闭后开区间的写法, substring(0, 5) 表示包含 0 号下标的字符, 不包含 5 号下标

1

其他操作方法

2.png


trim方法

trim 会去掉字符串开头和结尾的空白字符(空格, 换行, 制表符等).

public class string {
    public static void main(String[] args) {
        String str = "   abc  de fg   ";
        //输出结果为:   abc  de fg   
        System.out.println(str);
        String str1=str.trim();
        //输出结果为:abc  de fg
        System.out.println(str1);
    }
}

toUpperCase方法

public class string {
    public static void main(String[] args) {
        String str = "abc";
        String str1=str.toUpperCase();
        //输出结果为:ABC
        System.out.println(str1);
    }
}

toLowerCase方法

public class string {
    public static void main(String[] args) {
        String str = "ABabc";
        String str1=str.toLowerCase();
        //输出结果为:ababc
        System.out.println(str1);
    }
}

注意事项:toUpperCase方法和toLowerCase方法这两个方法只转换字母,不转换中文字符。


intern方法(前面已经讲过)

concat方法(不经常用,不做过多赘述)

length方法

public class string {
    public static void main(String[] args) {
        String str = "abc";
        int length=str.length();
        //输出结果为:3
        System.out.println(length);
    }
}

注意事项:数组长度使用数组名称.length属性,而String中使用的是length()方法


isEmpty方法

public class string {
    public static void main(String[] args) {
        //定义一个空字符串
        String str = "";
        boolean boolean1=str.isEmpty();
        //输出结果为:true
        System.out.println(boolean1);
    }
}

注意有两种方式可以表示空字符串

第一种方式:String str=“”,这种方式代表指向的字符串对象什么都没有.

第二种方式:String str=null,这种方式代表不指向任何对象


join方法

2.png


StringBuffer 和 StringBuilder

首先给出其官方网址:

StringBuffer 类:点我进入官网

StringBuilder 类:点我进入官网

首先来回顾下String类的特点:

任何的字符串常量都是String对象,而且String的常量一旦声明不可改变,如果改变对象内容,改变的是其引用的指向而已。

通常来讲String的操作比较简单,但是由于String的不可更改特性,为了方便字符串的修改,提供StringBuffer和StringBuilder类。

StringBuffer 和 StringBuilder 大部分功能是相同的,我们主要介绍 StringBuffer

在String中使用"+"来进行字符串连接,但是这个操作在StringBuffer类中需要更改为append()方法


使用了append方法进行拼接后,新产生的字符串在字符串常量池就不再生成内存了,就直接在原内存上的字符串进行拼接


代码示例

public class string {
    public static void main(String[] args) {
        //append方法的字符串拼接是在原字符串基础上进行拼接的,并不是生成新的字符串
        StringBuffer stringBuffer=new StringBuffer("abcd");
        //输出结果为abcdefg
        System.out.println(stringBuffer.append("efg"));
    }
}

为什么append方法会在原字符串上进行拼接呢?

来看append方法的源码:

2.png

最后返回的是当前对象的引用(return this),所以就是在原字符串上进行拼接.

append方法可以传的参数类型很多:例如char[],char ,boolean,int,long,float,double,StringBuffer,CharSequence


String与StringBuffer(StringBuilder)的转换

String和StringBuffer(StringBuilder)类不能直接转换。如果要想互相转换,可以采用如下原则:

String变为StringBuffer(StringBuilder):利用StringBuffer(StringBuilder)的构造方法或append()方法 (常用)

StringBuffer(StringBuilder)变为String:调用toString()方法。(常用)


总结

String与StringBuffer,StringBuilder的区别(面试题)

StringBuffer,StringBuilder包含了一些String没有的方法 比如reverse方法


StringBuffer,StringBuilder是可变的,String是不可变的。String的每次拼接,都会产生新的对象。

StringBuffer,StringBuilder每次的拼接都返回的是this,说明是在原字符串上进行拼接的.


StringBuffer与StringBuilder区别(面试题)

先来看StringBuffer,StringBuilder的append方法:

StringBuffer类中的append方法是被synchronized修饰的,

这个关键字可以保证线程的安全.

2.png2.png


总结:


StringBuilder和String 出现在单线程情况下

StringBuffer因为有synchronized关键字,所以一般出现多线程情况下。


一般来说非多线程的情况下最好使用StringBuilder,原因是 synchronized关键字涉及到锁的问题,每次的开锁关锁都要消耗资源


StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作


String与StringBuilder区别(面试题)

既然都运用于单线程的情况下,那么这两者到底有什么区别呢?

1:String的拼接”+“会被优化 优化为StringBuilder中的append方法,来看分析:

我们将下面这段代码进行编译:

public class string {
    public static void main(String[] args) {
        String str="abc";
        str=str+"de";
        System.out.println(str);
    }
}

编译后得到的如下图所示:

2.png

可以看到底部进行了优化,那么对于上述代码来说其实底层在运行的时候的代码如下所示:(代码的执行方式跟图中是一样的)

public class string {
    public static void main(String[] args) {
        String str="abc";
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(str);
        stringBuilder.append("hello");
        String str1 = stringBuilder.toString();
        System.out.println(str1);
    }
}

所以说对于String类的”+“的拼接,底层虽然是StringBuilder类的append方法的优化,但是其仍然会产生大量的临时空间

再来看之前遗留的一个问题:

   public static void main(String[] args) {
        String str = "abc";
        for(int i = 0;i < 10;i++) {
            str += i;
        }
        System.out.println(str);
    }

上述代码之前我们说因为由于”+“号的拼接,导致会产生大量的临时变量,此时我们来使用StringBuilder的append方法来进行优化:


public class string {
    public static void main(String[] args) {
        String str = "abc";
        //在循环外定义StringBuilder对象
        StringBuilder sb = new StringBuilder();
        sb.append(str);
        for (int i = 0; i < 10; i++) {
             //循环内部使用append方法
            str  = sb.append(i).toString();
        }
        System.out.println(str);
    }
}

2:在循环当中 不可以使用String直接进行拼接 这样会产生大量的临时对象

包括优化之后的StringBuilder对象。所以每次定义StringBuilder对象的时候在循环外进行定义,然后在循环内部使用append方法.


小结

字符串操作是我们以后工作中非常常用的操作. 使用起来都非常简单方便, 一定要使用熟练. 指的注意的点:

1.字符串的比较, ==, equals, compareTo 之间的区别.

2.了解字符串常量池, 体会 “池” 的思想.

3.理解字符串不可变

4.split 的应用场景

5.StringBuffer 和 StringBuilder 的功能.


String练习题

练习题1

下面代码将输出什么内容:()

2.png

A.true

B.false

C.1

D.编译错误


答:B


原因是toLowerCase方法实际上返回值是一个新的字符串,我们来看源码:

2.png

再点toLowerCase:

2.png

可以看到返回的是new String这样的字符串,所以它的地址是对象中value数组的地址,而"admin"是存储在字符串常量池的,所以两者地址肯定不同.


练习题2

指出下列程序运行的结果()

2.png

A.good and abc

B.good and gbc

C.test ok and abc

D.test ok and gbc


答案:B
相关文章
|
4月前
|
SQL Java 索引
java小工具util系列2:字符串工具
java小工具util系列2:字符串工具
175 83
|
3月前
|
存储 JavaScript Java
Java 中的 String Pool 简介
本文介绍了 Java 中 String 对象及其存储机制 String Pool 的基本概念,包括字符串引用、构造方法中的内存分配、字符串文字与对象的区别、手工引用、垃圾清理、性能优化,以及 Java 9 中的压缩字符串特性。文章详细解析了 String 对象的初始化、内存使用及优化方法,帮助开发者更好地理解和使用 Java 中的字符串。
Java 中的 String Pool 简介
|
5月前
|
Java 测试技术 开发者
Java零基础-indexOf(String str)详解!
【10月更文挑战第14天】Java零基础教学篇,手把手实践教学!
156 65
|
4月前
|
存储 安全 Java
Java零基础-字符串详解
【10月更文挑战第18天】Java零基础教学篇,手把手实践教学!
126 60
|
3月前
|
缓存 安全 Java
java 为什么 String 在 java 中是不可变的?
本文探讨了Java中String为何设计为不可变类型,从字符串池的高效利用、哈希码缓存、支持其他对象的安全使用、增强安全性以及线程安全等方面阐述了不可变性的优势。文中还通过具体代码示例解释了这些优点的实际应用。
java 为什么 String 在 java 中是不可变的?
|
4月前
|
Java 数据库
java小工具util系列1:日期和字符串转换工具
java小工具util系列1:日期和字符串转换工具
83 26
|
4月前
|
JSON Java 关系型数据库
Java更新数据库报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
在Java中,使用mybatis-plus更新实体类对象到mysql,其中一个字段对应数据库中json数据类型,更新时报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
411 4
Java更新数据库报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
|
3月前
|
存储 Java
Java 11 的String是如何优化存储的?
本文介绍了Java中字符串存储优化的原理和实现。通过判断字符串是否全为拉丁字符,使用`byte`代替`char`存储,以节省空间。具体实现涉及`compress`和`toBytes`方法,前者用于尝试压缩字符串,后者则按常规方式存储。代码示例展示了如何根据配置决定使用哪种存储方式。
|
4月前
|
存储 缓存 安全
java 中操作字符串都有哪些类,它们之间有什么区别
Java中操作字符串的类主要有String、StringBuilder和StringBuffer。String是不可变的,每次操作都会生成新对象;StringBuilder和StringBuffer都是可变的,但StringBuilder是非线程安全的,而StringBuffer是线程安全的,因此性能略低。
117 8
|
4月前
|
Java
在Java中如何将基本数据类型转换为String
在Java中,可使用多种方法将基本数据类型(如int、char等)转换为String:1. 使用String.valueOf()方法;2. 利用+运算符与空字符串连接;3. 对于数字类型,也可使用Integer.toString()等特定类型的方法。这些方法简单高效,适用于不同场景。
175 7

热门文章

最新文章