java新手入门——String类详解

目录
  • 一、创建字符串
    • 1. 直接赋值(常用)
    • 2. new String
    • 3. 字符数组转String
    • 4.String类中两种对象实例化的区别
  • 二、字符串比较相等
    • 1.直接比较字符串
  • 2.字符串在内存中的存储
    • 3.字符串常量池
    • 4.字符串比较equals
    • 5.理解字符串的不可变
    • 6.手动入池 intern()
    • 1.字符转字符串
    • 2.字符串转字符
    • 3.字节与字符串
    • 4.编码方式
    • 5.小结
  • 四、字符串常见操作
    • 1.字符串比较
    • 2.字符串查找
    • 3.字符串替换
    • 4.字符串拆分
    • 5.字符串截取
  • 五、StringBuffer 和 StringBuilder
    • 1.append()方法
    • 2.字符串反转 reverse( )
    • 3.删除指定范围的数据 delete( )
    • 4.插入数据 insert( )
    • 5.StringBuffer 和 StringBuilder的区别
  • 一、创建字符串
    • 1. 直接赋值(常用)
    • 2. new String
    • 3. 字符数组转String
    • 4.String类中两种对象实例化的区别
  • 二、字符串比较相等
    • 1.直接比较字符串
  • 2.字符串在内存中的存储
    • 3.字符串常量池
    • 4.字符串比较equals
    • 5.理解字符串的不可变
    • 6.手动入池 intern()
  • 三、字符字节与字符串
    • 1.字符转字符串
    • 2.字符串转字符
    • 3.字节与字符串
    • 4.编码方式
    • 5.小结
  • 四、字符串常见操作
    • 1.字符串比较
    • 2.字符串查找
    • 3.字符串替换
    • 4.字符串拆分
    • 5.字符串截取
  • 五、StringBuffer 和 StringBuilder
    • 1.append()方法
    • 2.字符串反转 reverse( )
    • 3.删除指定范围的数据 delete( )
    • 4.插入数据 insert( )
    • 5.StringBuffer 和 StringBuilder的区别
  • 六、总结
  • 一、创建字符串
    • 1. 直接赋值(常用)
    • 2. new String
    • 3. 字符数组转String
    • 4.String类中两种对象实例化的区别
  • 二、字符串比较相等
    • 1.直接比较字符串
  • 2.字符串在内存中的存储
    • 3.字符串常量池
    • 4.字符串比较equals
    • 5.理解字符串的不可变
    • 6.手动入池 intern()
    • 1.字符转字符串
    • 2.字符串转字符
    • 3.字节与字符串
    • 4.编码方式
    • 5.小结
  • 四、字符串常见操作
    • 1.字符串比较
    • 2.字符串查找
    • 3.字符串替换
    • 4.字符串拆分
    • 5.字符串截取
  • 五、StringBuffer 和 StringBuilder
    • 1.append()方法
    • 2.字符串反转 reverse( )
    • 3.删除指定范围的数据 delete( )
    • 4.插入数据 insert( )
    • 5.StringBuffer 和 StringBuilder的区别
  • 一、创建字符串
    • 1. 直接赋值(常用)
    • 2. new String
    • 3. 字符数组转String
    • 4.String类中两种对象实例化的区别
  • 二、字符串比较相等
    • 1.直接比较字符串
  • 2.字符串在内存中的存储
    • 3.字符串常量池
    • 4.字符串比较equals
    • 5.理解字符串的不可变
    • 6.手动入池 intern()
  • 三、字符字节与字符串
    • 1.字符转字符串
    • 2.字符串转字符
    • 3.字节与字符串
    • 4.编码方式
    • 5.小结
  • 四、字符串常见操作
    • 1.字符串比较
    • 2.字符串查找
    • 3.字符串替换
    • 4.字符串拆分
    • 5.字符串截取
  • 五、StringBuffer 和 StringBuilder
    • 1.append()方法
    • 2.字符串反转 reverse( )
    • 3.删除指定范围的数据 delete( )
    • 4.插入数据 insert( )
    • 5.StringBuffer 和 StringBuilder的区别
  • 六、总结

一、创建字符串

创建字符串的方式有很多种,当是常见的一般就三种

1. 直接赋值(常用)

String str = "hello world !";

2. new String

String str = new String("hello world !");

3. 字符数组转String

char[] array = {'a', 'b', 'c'};
String str = new String(array);

但以后一般都是用第一种创建方式
注意事项:

"hello" 这样的字符串字面值常量, 类型也是 String.String 也属于引用类型. String str ="Hello"

4.String类中两种对象实例化的区别

直接赋值:只会开辟一块堆内存空间,并且该字符串对象可以自动保存在对象池中以供下次使用。构造方法:会开辟两块堆内存空间,不会自动保存在对象池中,可以使用intern()方法手工入池。

二、字符串比较相等

1.直接比较字符串

我们知道两个整形可以直接用 == 比较相等,那如果用 == 比较String类相等会发生什么呢?

代码:

public static void main(String[] args) {
        String str1 = "hello";
        String str2 = new String("hello");
        System.out.println(str1 == str2);
        String str3 = "he"+"llo";//编译的时候这个地方相当于 String str3 = "hello";
        System.out.println(str1 == str3);
        String str4 = "he";
        String str5 = "llo";
        String str6 = str4+str5;
        System.out.println(str1 == str6);
        String str7 = "he"+new String("llo");
        System.out.println(str1 == str7);
    }

运行结果:

我们知道String属于引用类型,所以str存的是地址。那么比较的就是地址。
只要new了就会在堆上开辟内存,所以不相等。直接说可能有点抽象,下面简单通过内存图来判断字符串是否相等。

2.字符串在内存中的存储

接上面的例子我们来看一下字符串在内存中的存储来判断相等

注意:

1.只要new了就会在堆上开辟内存,那么必定不会相等。

2.相同的字符串在字符串常量池里只会存一份。

3.字符串常量池

String类的设计使用了共享设计模式

在JVM底层实际上会自动维护一个对象池(字符串常量池)

如果现在采用了直接赋值的模式进行String类的对象实例化操作,那么该实例化对象(字符串内容)将自动保存到这个对象池之中.如果下次继续使用直接赋值的模式声明String类对象,此时对象池之中如若有指定内容,将直接进行引用如若没有,则开辟新的字符串对象而后将其保存在对象池之中以供下次使用

4.字符串比较equals

Java 中要想比较字符串是否相等的话,就需要使用String提供的equals方法

String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1.equals(str2));
// System.out.println(str2.equals(str1)); // 或者这样写也行
// 执行结果
true

equals使用的注意事项:
现在需要比较 str 和 “Hello” 两个字符串是否相等, 我们该如何来写呢?

String str = new String("Hello");
// 方式一
System.out.println(str.equals("Hello"));
// 方式二
System.out.println("Hello".equals(str));

在上面的代码中, 哪种方式更好呢?

更推荐使用 “方式二”. 一旦 str 是 null, 方式一的代码会抛出异常, 而方式二不会

String str = null;
// 方式一
System.out.println(str.equals("Hello")); // 执行结果 抛出 java.lang.NullPointerException 异
常
// 方式二
System.out.println("Hello".equals(str)); // 执行结果 false

注意事项: “Hello” 这样的字面值常量, 本质上也是一个 String 对象, 完全可以使用 equals 等 String 对象的方法

5.理解字符串的不可变

字符串是一种不可变对象. 它的内容不可改变.
String 类的内部实现也是基于 char[] 来实现的, 但是 String 类并没有提供 set 方法之类的来修改内部的字符数组.

代码示例:

String str = "hello" ;
str = str + " world" ;
str += "!!!" ;
System.out.println(str);
// 执行结果
hello world!!!

形如 += 这样的操作, 表面上好像是修改了字符串, 其实不是. 内存变化如下:

+= 之后 str 打印的结果却是变了, 但是不是 String 对象本身发生改变, 而是 str 引用到了其他的对象.

回顾引用:

引用相当于一个指针, 里面存的内容是一个地址. 我们要区分清楚当前修改到底是修改了地址对应内存的内容发生改变了, 还是引用中存的地址改变了.

6.手动入池 intern()

我们知道字符串常量是存在字符串常量池当中的,而new的是在堆上开辟内存。

而String的 intern()方法可以把String对象手动入到字符串常量池中

// 该字符串常量并没有保存在对象池之中
String str1 = "hello" ;
String str2 = new String("hello") ;
System.out.println(str1 == str2);
// 执行结果
false
String str1 = "hello" ;
String str2 = new String("hello").intern()  ;
System.out.println(str1 == str2);
// 执行结果
true

如果str2没有
intern()方法的时候,它是指向堆上的new的String对象的,而使用了intern()方法后,就会直接指向字符串常量池的
”hello“,如果调用intern()方法的时候字符串常量池中没有 "hello"这个字符串,则会把它放入池中。

三、字符字节与字符串

1.字符转字符串

代码示例 :

		char[] array = {'h','e','l','l','o'};
        String str1 = new String(array);
        String str2 = new String(array,1,2);
        System.out.println(str1);
        System.out.println(str2);
        //运行结果
        //hello
        //el

注意:第一个参数是偏移量,偏移量是从0开始的,第二个是参数是往后从偏移量开始的位置走几步。且下标不能越界!

2.字符串转字符


指定获取字符串里的某一个字符:

		String str = "hello";
        char ch = str.charAt(4);
        System.out.println(ch);
        //运行结果
        //o

字符串转字符数组代码示例:

		String str = "hello";
        char[] array = str.toCharArray();
        for (char s : array) {
            System.out.print(s+" ");
        }

运行结果

3.字节与字符串

用法和上面的类似

代码示例:

     	byte[] bytes = {97,98,99,100};
        String str = new String(bytes,1,3);
        System.out.println(str);
        String str2 = "abcd";
        byte[] bytes1 = str2.getBytes();
        System.out.println(Arrays.toString(bytes1));

运行结果

4.编码方式

运行结果 :

常见的编码方式有 utf-8 和 GBK ,不过编码方式一般只对汉字有影响。

5.小结

那么何时使用 byte[], 何时使用 char[] 呢?

byte[] 是把 String 按照一个字节一个字节的方式处理, 这种适合在网络传输, 数据存储这样的场景下使用. 更适合 针对二进制数据来操作.char[] 是吧 String 按照一个字符一个字符的方式处理, 更适合针对文本数据来操作, 尤其是包含中文的时候

回忆概念: 文本数据 vs 二进制数据

一个简单粗暴的区分方式就是用记事本打开能不能看懂里面的内容.
如果看的懂, 就是文本数据(例如 .java 文件), 如果看不懂, 就是二进制数据(例如 .class 文件).

四、字符串常见操作

1.字符串比较

上面使用过String类提供的equals()方法,该方法本身是可以进行区分大小写的相等判断。除了这个方法之外,String类还提供有如下的比较操作:

代码示例:

		String str = "abcd";
        System.out.println("abcd".equals(str));![在这里插入图片描述](https://img-blog.csdnimg.cn/20210612164343418.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81Mzk0Njg1Mg==,size_16,color_FFFFFF,t_70#pic_center)
        System.out.println("Abcd".equalsIgnoreCase(str));//不区分大小写
        //运行结果
        //true
        //true

**compareTo()**方法前面博客有详细介绍,这里就不多说了。可以看看—>compareTo方法

在String类中compareTo()方法是一个非常重要的方法,该方法返回一个整型,该数据会根据大小关系返回三类内
容:

相等:返回0.小于:返回内容小于0.大于:返回内容大于0。

2.字符串查找

从一个完整的字符串之中可以判断指定内容是否存在,对于查找方法有如下定义:

代码示例 :

		String str = "abcdefg";
        找子串
        System.out.println(str.contains("efg"));
        从头开始找指定字符串,找到返回下标,找不到返回 -1
        System.out.println(str.indexOf("d"));
        指定位置开始找指定字符串
        System.out.println(str.indexOf("d",2));
        从后向前找指定字符串
        System.out.println(str.lastIndexOf("fg"));
        判断是否以指定字符串开头
        System.out.println(str.startsWith("abc"));
        从指定位置判断是否以该字符串开头
        System.out.println(str.startsWith("de", 3));

用法都是通过 String类点出方法名,注意就收放回值就好了。

3.字符串替换

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

代码示例:

String str = "helloworld" ;
System.out.println(str.replaceAll("l", "!"));
System.out.println(str.replaceFirst("l", "!"));

运行结果

注意如果替换的是特殊字符,则需要使用转义字符。
代码示例:

	String str1 = "192\\168\\1\\1" ;
        System.out.println(str1.replaceAll("\\\\", "+"));
        String str2 = "www.baidu.com";
        System.out.println(str2.replaceAll("\\.", "%20"));

运行结果

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

4.字符串拆分

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

代码示例:

		String str1 = "192.168.1.1" ;
        String[] array = str1.split("\\.");
        for (String s : array) {
            System.out.println(s);
        }

运行结果

注意:下面的的这段代码是不能被拆分的

		String str1 = "192\168\1\1" ;
        String[] array = str1.split("\\\\");
        for (String s : array) {
            System.out.println(s);
        }

运行结果:

因为 \ 后面跟两到三个数字会被转义成一个八进制数字。

注意事项:

字符"|","*","+“都得加上转义字符,前面加上”".而如果是"",那么就得写成"\".如果一个字符串中有多个分隔符,可以用"|"作为连字符.

多次拆分代码示例:

		String str = "name=zhangsan&age=18";
        String[] result = str.split("&|=") ;
        for (String s : result) {
            System.out.println(s);
        }

运行结果:

5.字符串截取

从一个完整的字符串之中截取出部分内容。

代码示例:

		String str = "abcdef";
        System.out.println(str.substring(3));
        System.out.println(str.substring(2, 4));//左闭右开
        运行结果
        def
        cd

注意事项:

索引从0开始注意前闭后开区间的写法, substring(0, 5) 表示包含 0 号下标的字符, 不包含 5 号下标 6.其他操作方法


这些都比较简单,用的时候查就好了。

五、StringBuffer 和 StringBuilder

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

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

通常来讲String的操作比较简单,但是由于String的不可更改特性,为了方便字符串的修改,提供StringBuffer和StringBuilder类。
StringBuffer 和 StringBuilder 大部分功能是相同的,只有较小的区别。

1.append()方法

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

public synchronized StringBuffer append(各种数据类型 b)

代码示例:

		StringBuffer str1 = new StringBuffer("abcd");
        StringBuilder str2 = new StringBuilder("abcd");
        str1.append(123);
        str2.append("hij");
        System.out.println(str1);
        System.out.println(str2);

运行结果:

StringBuffer 和 StringBuilder 大部分功能是相同的,它们的append()方法的方法可以拼接各种数据类型。

注意:

String和StringBuffer最大的区别在于:String的内容无法修改,而StringBuffer的内容可以修改。频繁修改字符串的情况考虑使用StingBuffer。

因为 String通过+拼接会产生临时对象,而 StringBuffer 和 StringBuilder 只会在当前对象上进行拼接。

2.字符串反转 reverse( )

代码示例:

		StringBuffer str1 = new StringBuffer("abcdefg");
        StringBuilder str2 = new StringBuilder("654321");
        System.out.println(str1.reverse());
        System.out.println(str2.reverse());

运行结果:

3.删除指定范围的数据 delete( )

代码示例:

		StringBuffer str1 = new StringBuffer("abcdefg");
        StringBuilder str2 = new StringBuilder("654321");
        System.out.println(str1.delete(2, 5));
        System.out.println(str2.delete(4, 6));

运行结果:

4.插入数据 insert( )

代码示例:

		StringBuffer str1 = new StringBuffer("abcdefg");
        StringBuilder str2 = new StringBuilder("654321");
        str1.insert(0,"你好吗").delete(0,1);
        System.out.println(str1);
        System.out.println(str2.delete(0, 3).insert(0, "你好世界"));

运行结果:

5.StringBuffer 和 StringBuilder的区别

来看一下 StringBuffer 和 StringBuilder 的 append 方法

1.String的拼接会产生临时对象,但是后两者每次都只是返回当前对象的引用

2.String的加号拼接,会被底层优化为一个StringBuilder

3.StringBuilder和String,一般如果不涉及到多线程的情况下才会使用

4.StringBuffer(创建锁、销毁锁、都是耗费资源的)

总结

1.如果以后涉及到字符串的拼接,一定要使用 StringBuffer 和 StringBuilder 的 append()方法

2.注意String类中两种对象实例化的区别

3.相同的字符串在字符串常量池中只会存一份

一、创建字符串

创建字符串的方式有很多种,当是常见的一般就三种

1. 直接赋值(常用)

String str = "hello world !";

2. new String

String str = new String("hello world !");

3. 字符数组转String

char[] array = {'a', 'b', 'c'};
String str = new String(array);

但以后一般都是用第一种创建方式
注意事项:

"hello" 这样的字符串字面值常量, 类型也是 String.String 也属于引用类型. String str ="Hello"

4.String类中两种对象实例化的区别

直接赋值:只会开辟一块堆内存空间,并且该字符串对象可以自动保存在对象池中以供下次使用。构造方法:会开辟两块堆内存空间,不会自动保存在对象池中,可以使用intern()方法手工入池。

二、字符串比较相等

1.直接比较字符串

我们知道两个整形可以直接用 == 比较相等,那如果用 == 比较String类相等会发生什么呢?

代码:

public static void main(String[] args) {
        String str1 = "hello";
        String str2 = new String("hello");
        System.out.println(str1 == str2);
        String str3 = "he"+"llo";//编译的时候这个地方相当于 String str3 = "hello";
        System.out.println(str1 == str3);
        String str4 = "he";
        String str5 = "llo";
        String str6 = str4+str5;
        System.out.println(str1 == str6);
        String str7 = "he"+new String("llo");
        System.out.println(str1 == str7);
    }

运行结果:

我们知道String属于引用类型,所以str存的是地址。那么比较的就是地址。

只要new了就会在堆上开辟内存,所以不相等。直接说可能有点抽象,下面简单通过内存图来判断字符串是否相等。

2.字符串在内存中的存储

接上面的例子我们来看一下字符串在内存中的存储来判断相等

注意:

1.只要new了就会在堆上开辟内存,那么必定不会相等。

2.相同的字符串在字符串常量池里只会存一份。

3.字符串常量池

String类的设计使用了共享设计模式

在JVM底层实际上会自动维护一个对象池(字符串常量池)

如果现在采用了直接赋值的模式进行String类的对象实例化操作,那么该实例化对象(字符串内容)将自动保存到这个对象池之中.如果下次继续使用直接赋值的模式声明String类对象,此时对象池之中如若有指定内容,将直接进行引用如若没有,则开辟新的字符串对象而后将其保存在对象池之中以供下次使用

4.字符串比较equals

Java 中要想比较字符串是否相等的话,就需要使用String提供的equals方法

String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1.equals(str2));
// System.out.println(str2.equals(str1)); // 或者这样写也行
// 执行结果
true

equals使用的注意事项:
现在需要比较 str 和 “Hello” 两个字符串是否相等, 我们该如何来写呢?

String str = new String("Hello");
// 方式一
System.out.println(str.equals("Hello"));
// 方式二
System.out.println("Hello".equals(str));

在上面的代码中, 哪种方式更好呢?
更推荐使用 “方式二”. 一旦 str 是 null, 方式一的代码会抛出异常, 而方式二不会

String str = null;
// 方式一
System.out.println(str.equals("Hello")); // 执行结果 抛出 java.lang.NullPointerException 异
常
// 方式二
System.out.println("Hello".equals(str)); // 执行结果 false

注意事项: “Hello” 这样的字面值常量, 本质上也是一个 String 对象, 完全可以使用 equals 等 String 对象的方法

5.理解字符串的不可变

字符串是一种不可变对象. 它的内容不可改变.
String 类的内部实现也是基于 char[] 来实现的, 但是 String 类并没有提供 set 方法之类的来修改内部的字符数组.

代码示例:

String str = "hello" ;
str = str + " world" ;
str += "!!!" ;
System.out.println(str);
// 执行结果
hello world!!!

形如 += 这样的操作, 表面上好像是修改了字符串, 其实不是. 内存变化如下:

+= 之后 str 打印的结果却是变了, 但是不是 String 对象本身发生改变, 而是 str 引用到了其他的对象.

回顾引用:

引用相当于一个指针, 里面存的内容是一个地址. 我们要区分清楚当前修改到底是修改了地址对应内存的内容发生改变了, 还是引用中存的地址改变了.

6.手动入池 intern()

我们知道字符串常量是存在字符串常量池当中的,而new的是在堆上开辟内存。
而String的 intern()方法可以把String对象手动入到字符串常量池中

// 该字符串常量并没有保存在对象池之中
String str1 = "hello" ;
String str2 = new String("hello") ;
System.out.println(str1 == str2);
// 执行结果
false
String str1 = "hello" ;
String str2 = new String("hello").intern()  ;
System.out.println(str1 == str2);
// 执行结果
true

如果str2没有
intern()方法的时候,它是指向堆上的new的String对象的,而使用了intern()方法后,就会直接指向字符串常量池的
”hello“,如果调用intern()方法的时候字符串常量池中没有 "hello"这个字符串,则会把它放入池中。

三、字符字节与字符串

1.字符转字符串

代码示例 :

		char[] array = {'h','e','l','l','o'};
        String str1 = new String(array);
        String str2 = new String(array,1,2);
        System.out.println(str1);
        System.out.println(str2);
        //运行结果
        //hello
        //el

注意:第一个参数是偏移量,偏移量是从0开始的,第二个是参数是往后从偏移量开始的位置走几步。且下标不能越界!

2.字符串转字符

指定获取字符串里的某一个字符:

		String str = "hello";
        char ch = str.charAt(4);
        System.out.println(ch);
        //运行结果
        //o

字符串转字符数组代码示例:

		String str = "hello";
        char[] array = str.toCharArray();
        for (char s : array) {
            System.out.print(s+" ");
        }

运行结果

3.字节与字符串

用法和上面的类似
代码示例:

     	byte[] bytes = {97,98,99,100};
        String str = new String(bytes,1,3);
        System.out.println(str);
        String str2 = "abcd";
        byte[] bytes1 = str2.getBytes();
        System.out.println(Arrays.toString(bytes1));

运行结果

4.编码方式

运行结果 :

常见的编码方式有 utf-8 和 GBK ,不过编码方式一般只对汉字有影响。

5.小结

那么何时使用 byte[], 何时使用 char[] 呢?

byte[] 是把 String 按照一个字节一个字节的方式处理, 这种适合在网络传输, 数据存储这样的场景下使用. 更适合 针对二进制数据来操作.char[] 是吧 String 按照一个字符一个字符的方式处理, 更适合针对文本数据来操作, 尤其是包含中文的时候

回忆概念: 文本数据 vs 二进制数据

一个简单粗暴的区分方式就是用记事本打开能不能看懂里面的内容.
如果看的懂, 就是文本数据(例如 .java 文件), 如果看不懂, 就是二进制数据(例如 .class 文件).

四、字符串常见操作

1.字符串比较

上面使用过String类提供的equals()方法,该方法本身是可以进行区分大小写的相等判断。除了这个方法之外,String类还提供有如下的比较操作:

代码示例:

		String str = "abcd";
        System.out.println("abcd".equals(str));![在这里插入图片描述](https://img-blog.csdnimg.cn/20210612164343418.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81Mzk0Njg1Mg==,size_16,color_FFFFFF,t_70#pic_center)
        System.out.println("Abcd".equalsIgnoreCase(str));//不区分大小写
        //运行结果
        //true
        //true

**compareTo()**方法前面博客有详细介绍,这里就不多说了。可以看看—>compareTo方法
在String类中compareTo()方法是一个非常重要的方法,该方法返回一个整型,该数据会根据大小关系返回三类内
容:

相等:返回0.小于:返回内容小于0.大于:返回内容大于0。

2.字符串查找

从一个完整的字符串之中可以判断指定内容是否存在,对于查找方法有如下定义:

代码示例 :

		String str = "abcdefg";
        找子串
        System.out.println(str.contains("efg"));
        从头开始找指定字符串,找到返回下标,找不到返回 -1
        System.out.println(str.indexOf("d"));
        指定位置开始找指定字符串
        System.out.println(str.indexOf("d",2));
        从后向前找指定字符串
        System.out.println(str.lastIndexOf("fg"));
        判断是否以指定字符串开头
        System.out.println(str.startsWith("abc"));
        从指定位置判断是否以该字符串开头
        System.out.println(str.startsWith("de", 3));

用法都是通过 String类点出方法名,注意就收放回值就好了。

3.字符串替换

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

代码示例:

String str = "helloworld" ;
System.out.println(str.replaceAll("l", "!"));
System.out.println(str.replaceFirst("l", "!"));

运行结果

注意如果替换的是特殊字符,则需要使用转义字符。
代码示例:

	String str1 = "192\\168\\1\\1" ;
        System.out.println(str1.replaceAll("\\\\", "+"));
        String str2 = "www.baidu.com";
        System.out.println(str2.replaceAll("\\.", "%20"));

运行结果

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

4.字符串拆分

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

代码示例:

		String str1 = "192.168.1.1" ;
        String[] array = str1.split("\\.");
        for (String s : array) {
            System.out.println(s);
        }

运行结果

注意:下面的的这段代码是不能被拆分的

		String str1 = "192\168\1\1" ;
        String[] array = str1.split("\\\\");
        for (String s : array) {
            System.out.println(s);
        }

运行结果:

因为 \ 后面跟两到三个数字会被转义成一个八进制数字。

注意事项:

字符"|","*","+“都得加上转义字符,前面加上”".而如果是"",那么就得写成"\".如果一个字符串中有多个分隔符,可以用"|"作为连字符.

多次拆分代码示例:

		String str = "name=zhangsan&age=18";
        String[] result = str.split("&|=") ;
        for (String s : result) {
            System.out.println(s);
        }

运行结果:

5.字符串截取

从一个完整的字符串之中截取出部分内容。

代码示例:

		String str = "abcdef";
        System.out.println(str.substring(3));
        System.out.println(str.substring(2, 4));//左闭右开
        运行结果
        def
        cd

注意事项:

索引从0开始注意前闭后开区间的写法, substring(0, 5) 表示包含 0 号下标的字符, 不包含 5 号下标 6.其他操作方法

这些都比较简单,用的时候查就好了。

五、StringBuffer 和 StringBuilder

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

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

通常来讲String的操作比较简单,但是由于String的不可更改特性,为了方便字符串的修改,提供StringBuffer和StringBuilder类。
StringBuffer 和 StringBuilder 大部分功能是相同的,只有较小的区别。

1.append()方法

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

public synchronized StringBuffer append(各种数据类型 b)

代码示例:

		StringBuffer str1 = new StringBuffer("abcd");
        StringBuilder str2 = new StringBuilder("abcd");
        str1.append(123);
        str2.append("hij");
        System.out.println(str1);
        System.out.println(str2);

运行结果:

StringBuffer 和 StringBuilder 大部分功能是相同的,它们的append()方法的方法可以拼接各种数据类型。

注意:

String和StringBuffer最大的区别在于:String的内容无法修改,而StringBuffer的内容可以修改。频繁修改字符串的情况考虑使用StingBuffer。

因为 String通过+拼接会产生临时对象,而 StringBuffer 和 StringBuilder 只会在当前对象上进行拼接。

2.字符串反转 reverse( )

代码示例:

		StringBuffer str1 = new StringBuffer("abcdefg");
        StringBuilder str2 = new StringBuilder("654321");
        System.out.println(str1.reverse());
        System.out.println(str2.reverse());

运行结果:

3.删除指定范围的数据 delete( )

代码示例:

		StringBuffer str1 = new StringBuffer("abcdefg");
        StringBuilder str2 = new StringBuilder("654321");
        System.out.println(str1.delete(2, 5));
        System.out.println(str2.delete(4, 6));

运行结果:

4.插入数据 insert( )

代码示例:

		StringBuffer str1 = new StringBuffer("abcdefg");
        StringBuilder str2 = new StringBuilder("654321");
        str1.insert(0,"你好吗").delete(0,1);
        System.out.println(str1);
        System.out.println(str2.delete(0, 3).insert(0, "你好世界"));

运行结果:

5.StringBuffer 和 StringBuilder的区别

来看一下 StringBuffer 和 StringBuilder 的 append 方法

1.String的拼接会产生临时对象,但是后两者每次都只是返回当前对象的引用

2.String的加号拼接,会被底层优化为一个StringBuilder

3.StringBuilder和String,一般如果不涉及到多线程的情况下才会使用

4.StringBuffer(创建锁、销毁锁、都是耗费资源的)

六、总结

1.如果以后涉及到字符串的拼接,一定要使用 StringBuffer 和 StringBuilder 的 append()方法

2.注意String类中两种对象实例化的区别

3.相同的字符串在字符串常量池中只会存一份

希望大家可以多多关注我们的其他文章!

一、创建字符串

创建字符串的方式有很多种,当是常见的一般就三种

1. 直接赋值(常用)

String str = "hello world !";

2. new String

String str = new String("hello world !");

3. 字符数组转String

char[] array = {'a', 'b', 'c'};
String str = new String(array);

但以后一般都是用第一种创建方式
注意事项:

"hello" 这样的字符串字面值常量, 类型也是 String.String 也属于引用类型. String str ="Hello"

4.String类中两种对象实例化的区别

直接赋值:只会开辟一块堆内存空间,并且该字符串对象可以自动保存在对象池中以供下次使用。构造方法:会开辟两块堆内存空间,不会自动保存在对象池中,可以使用intern()方法手工入池。

二、字符串比较相等

1.直接比较字符串

我们知道两个整形可以直接用 == 比较相等,那如果用 == 比较String类相等会发生什么呢?

代码:

public static void main(String[] args) {
        String str1 = "hello";
        String str2 = new String("hello");
        System.out.println(str1 == str2);
        String str3 = "he"+"llo";//编译的时候这个地方相当于 String str3 = "hello";
        System.out.println(str1 == str3);
        String str4 = "he";
        String str5 = "llo";
        String str6 = str4+str5;
        System.out.println(str1 == str6);
        String str7 = "he"+new String("llo");
        System.out.println(str1 == str7);
    }

运行结果:


我们知道String属于引用类型,所以str存的是地址。那么比较的就是地址。
只要new了就会在堆上开辟内存,所以不相等。直接说可能有点抽象,下面简单通过内存图来判断字符串是否相等。

2.字符串在内存中的存储

接上面的例子我们来看一下字符串在内存中的存储来判断相等

注意:

1.只要new了就会在堆上开辟内存,那么必定不会相等。

2.相同的字符串在字符串常量池里只会存一份。

3.字符串常量池

String类的设计使用了共享设计模式

在JVM底层实际上会自动维护一个对象池(字符串常量池)

如果现在采用了直接赋值的模式进行String类的对象实例化操作,那么该实例化对象(字符串内容)将自动保存到这个对象池之中.如果下次继续使用直接赋值的模式声明String类对象,此时对象池之中如若有指定内容,将直接进行引用如若没有,则开辟新的字符串对象而后将其保存在对象池之中以供下次使用

4.字符串比较equals

Java 中要想比较字符串是否相等的话,就需要使用String提供的equals方法

String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1.equals(str2));
// System.out.println(str2.equals(str1)); // 或者这样写也行
// 执行结果
true

equals使用的注意事项:

现在需要比较 str 和 “Hello” 两个字符串是否相等, 我们该如何来写呢?

String str = new String("Hello");
// 方式一
System.out.println(str.equals("Hello"));
// 方式二
System.out.println("Hello".equals(str));

在上面的代码中, 哪种方式更好呢?

更推荐使用 “方式二”. 一旦 str 是 null, 方式一的代码会抛出异常, 而方式二不会

String str = null;
// 方式一
System.out.println(str.equals("Hello")); // 执行结果 抛出 java.lang.NullPointerException 异
常
// 方式二
System.out.println("Hello".equals(str)); // 执行结果 false

注意事项: “Hello” 这样的字面值常量, 本质上也是一个 String 对象, 完全可以使用 equals 等 String 对象的方法

5.理解字符串的不可变

字符串是一种不可变对象. 它的内容不可改变.

String 类的内部实现也是基于 char[] 来实现的, 但是 String 类并没有提供 set 方法之类的来修改内部的字符数组.

代码示例:

String str = "hello" ;
str = str + " world" ;
str += "!!!" ;
System.out.println(str);
// 执行结果
hello world!!!

形如 += 这样的操作, 表面上好像是修改了字符串, 其实不是. 内存变化如下:

+= 之后 str 打印的结果却是变了, 但是不是 String 对象本身发生改变, 而是 str 引用到了其他的对象.

回顾引用:

引用相当于一个指针, 里面存的内容是一个地址. 我们要区分清楚当前修改到底是修改了地址对应内存的内容发生改变了, 还是引用中存的地址改变了.

6.手动入池 intern()

我们知道字符串常量是存在字符串常量池当中的,而new的是在堆上开辟内存。

而String的 intern()方法可以把String对象手动入到字符串常量池中

// 该字符串常量并没有保存在对象池之中
String str1 = "hello" ;
String str2 = new String("hello") ;
System.out.println(str1 == str2);
// 执行结果
false
String str1 = "hello" ;
String str2 = new String("hello").intern()  ;
System.out.println(str1 == str2);
// 执行结果
true

如果str2没有
intern()方法的时候,它是指向堆上的new的String对象的,而使用了intern()方法后,就会直接指向字符串常量池的
”hello“,如果调用intern()方法的时候字符串常量池中没有 "hello"这个字符串,则会把它放入池中。

三、字符字节与字符串

1.字符转字符串


代码示例 :

		char[] array = {'h','e','l','l','o'};
        String str1 = new String(array);
        String str2 = new String(array,1,2);
        System.out.println(str1);
        System.out.println(str2);
        //运行结果
        //hello
        //el

注意:第一个参数是偏移量,偏移量是从0开始的,第二个是参数是往后从偏移量开始的位置走几步。且下标不能越界!

2.字符串转字符


指定获取字符串里的某一个字符:

		String str = "hello";
        char ch = str.charAt(4);
        System.out.println(ch);
        //运行结果
        //o

字符串转字符数组代码示例:

		String str = "hello";
        char[] array = str.toCharArray();
        for (char s : array) {
            System.out.print(s+" ");
        }

运行结果

3.字节与字符串

用法和上面的类似

代码示例:

     	byte[] bytes = {97,98,99,100};
        String str = new String(bytes,1,3);
        System.out.println(str);
        String str2 = "abcd";
        byte[] bytes1 = str2.getBytes();
        System.out.println(Arrays.toString(bytes1));

运行结果

4.编码方式

运行结果 :

常见的编码方式有 utf-8 和 GBK ,不过编码方式一般只对汉字有影响。

5.小结

那么何时使用 byte[], 何时使用 char[] 呢?

byte[] 是把 String 按照一个字节一个字节的方式处理, 这种适合在网络传输, 数据存储这样的场景下使用. 更适合 针对二进制数据来操作.char[] 是吧 String 按照一个字符一个字符的方式处理, 更适合针对文本数据来操作, 尤其是包含中文的时候

回忆概念: 文本数据 vs 二进制数据

一个简单粗暴的区分方式就是用记事本打开能不能看懂里面的内容.
如果看的懂, 就是文本数据(例如 .java 文件), 如果看不懂, 就是二进制数据(例如 .class 文件).

四、字符串常见操作

1.字符串比较

上面使用过String类提供的equals()方法,该方法本身是可以进行区分大小写的相等判断。除了这个方法之外,String类还提供有如下的比较操作:

代码示例:

		String str = "abcd";
        System.out.println("abcd".equals(str));![在这里插入图片描述](https://img-blog.csdnimg.cn/20210612164343418.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81Mzk0Njg1Mg==,size_16,color_FFFFFF,t_70#pic_center)
        System.out.println("Abcd".equalsIgnoreCase(str));//不区分大小写
        //运行结果
        //true
        //true

**compareTo()**方法前面博客有详细介绍,这里就不多说了。可以看看—>compareTo方法

在String类中compareTo()方法是一个非常重要的方法,该方法返回一个整型,该数据会根据大小关系返回三类内
容:

相等:返回0.小于:返回内容小于0.大于:返回内容大于0。

2.字符串查找

从一个完整的字符串之中可以判断指定内容是否存在,对于查找方法有如下定义:

代码示例 :

		String str = "abcdefg";
        找子串
        System.out.println(str.contains("efg"));
        从头开始找指定字符串,找到返回下标,找不到返回 -1
        System.out.println(str.indexOf("d"));
        指定位置开始找指定字符串
        System.out.println(str.indexOf("d",2));
        从后向前找指定字符串
        System.out.println(str.lastIndexOf("fg"));
        判断是否以指定字符串开头
        System.out.println(str.startsWith("abc"));
        从指定位置判断是否以该字符串开头
        System.out.println(str.startsWith("de", 3));

用法都是通过 String类点出方法名,注意就收放回值就好了。

3.字符串替换

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

代码示例:

String str = "helloworld" ;
System.out.println(str.replaceAll("l", "!"));
System.out.println(str.replaceFirst("l", "!"));

运行结果

注意如果替换的是特殊字符,则需要使用转义字符。

代码示例:

	String str1 = "192\\168\\1\\1" ;
        System.out.println(str1.replaceAll("\\\\", "+"));
        String str2 = "www.baidu.com";
        System.out.println(str2.replaceAll("\\.", "%20"));

运行结果

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

4.字符串拆分

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

代码示例:

		String str1 = "192.168.1.1" ;
        String[] array = str1.split("\\.");
        for (String s : array) {
            System.out.println(s);
        }

运行结果

注意:下面的的这段代码是不能被拆分的

		String str1 = "192\168\1\1" ;
        String[] array = str1.split("\\\\");
        for (String s : array) {
            System.out.println(s);
        }

运行结果:

因为 \ 后面跟两到三个数字会被转义成一个八进制数字。

注意事项:

字符"|","*","+“都得加上转义字符,前面加上”".而如果是"",那么就得写成"\".如果一个字符串中有多个分隔符,可以用"|"作为连字符.

多次拆分代码示例:

		String str = "name=zhangsan&age=18";
        String[] result = str.split("&|=") ;
        for (String s : result) {
            System.out.println(s);
        }

运行结果:

5.字符串截取

从一个完整的字符串之中截取出部分内容。

代码示例:

		String str = "abcdef";
        System.out.println(str.substring(3));
        System.out.println(str.substring(2, 4));//左闭右开
        运行结果
        def
        cd

注意事项:

索引从0开始注意前闭后开区间的写法, substring(0, 5) 表示包含 0 号下标的字符, 不包含 5 号下标 6.其他操作方法

这些都比较简单,用的时候查就好了。

五、StringBuffer 和 StringBuilder

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

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

通常来讲String的操作比较简单,但是由于String的不可更改特性,为了方便字符串的修改,提供StringBuffer和StringBuilder类。
StringBuffer 和 StringBuilder 大部分功能是相同的,只有较小的区别。

1.append()方法

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

public synchronized StringBuffer append(各种数据类型 b)

代码示例:

		StringBuffer str1 = new StringBuffer("abcd");
        StringBuilder str2 = new StringBuilder("abcd");
        str1.append(123);
        str2.append("hij");
        System.out.println(str1);
        System.out.println(str2);

运行结果:

StringBuffer 和 StringBuilder 大部分功能是相同的,它们的append()方法的方法可以拼接各种数据类型。

注意:

String和StringBuffer最大的区别在于:String的内容无法修改,而StringBuffer的内容可以修改。频繁修改字符串的情况考虑使用StingBuffer。

因为 String通过+拼接会产生临时对象,而 StringBuffer 和 StringBuilder 只会在当前对象上进行拼接。

2.字符串反转 reverse( )

代码示例:

		StringBuffer str1 = new StringBuffer("abcdefg");
        StringBuilder str2 = new StringBuilder("654321");
        System.out.println(str1.reverse());
        System.out.println(str2.reverse());

运行结果:

3.删除指定范围的数据 delete( )

代码示例:

		StringBuffer str1 = new StringBuffer("abcdefg");
        StringBuilder str2 = new StringBuilder("654321");
        System.out.println(str1.delete(2, 5));
        System.out.println(str2.delete(4, 6));

运行结果:

4.插入数据 insert( )

代码示例:

		StringBuffer str1 = new StringBuffer("abcdefg");
        StringBuilder str2 = new StringBuilder("654321");
        str1.insert(0,"你好吗").delete(0,1);
        System.out.println(str1);
        System.out.println(str2.delete(0, 3).insert(0, "你好世界"));

运行结果:

5.StringBuffer 和 StringBuilder的区别

来看一下 StringBuffer 和 StringBuilder 的 append 方法

1.String的拼接会产生临时对象,但是后两者每次都只是返回当前对象的引用

2.String的加号拼接,会被底层优化为一个StringBuilder

3.StringBuilder和String,一般如果不涉及到多线程的情况下才会使用

4.StringBuffer(创建锁、销毁锁、都是耗费资源的)

总结

1.如果以后涉及到字符串的拼接,一定要使用 StringBuffer 和 StringBuilder 的 append()方法

2.注意String类中两种对象实例化的区别

3.相同的字符串在字符串常量池中只会存一份

一、创建字符串

创建字符串的方式有很多种,当是常见的一般就三种

1. 直接赋值(常用)

String str = "hello world !";

2. new String

String str = new String("hello world !");

3. 字符数组转String

char[] array = {'a', 'b', 'c'};
String str = new String(array);

但以后一般都是用第一种创建方式
注意事项:

"hello" 这样的字符串字面值常量, 类型也是 String.String 也属于引用类型. String str ="Hello"

4.String类中两种对象实例化的区别

直接赋值:只会开辟一块堆内存空间,并且该字符串对象可以自动保存在对象池中以供下次使用。构造方法:会开辟两块堆内存空间,不会自动保存在对象池中,可以使用intern()方法手工入池。

二、字符串比较相等

1.直接比较字符串

我们知道两个整形可以直接用 == 比较相等,那如果用 == 比较String类相等会发生什么呢?

代码:

public static void main(String[] args) {
        String str1 = "hello";
        String str2 = new String("hello");
        System.out.println(str1 == str2);
        String str3 = "he"+"llo";//编译的时候这个地方相当于 String str3 = "hello";
        System.out.println(str1 == str3);
        String str4 = "he";
        String str5 = "llo";
        String str6 = str4+str5;
        System.out.println(str1 == str6);
        String str7 = "he"+new String("llo");
        System.out.println(str1 == str7);
    }

运行结果:

我们知道String属于引用类型,所以str存的是地址。那么比较的就是地址。

只要new了就会在堆上开辟内存,所以不相等。直接说可能有点抽象,下面简单通过内存图来判断字符串是否相等。

2.字符串在内存中的存储

接上面的例子我们来看一下字符串在内存中的存储来判断相等

注意:

1.只要new了就会在堆上开辟内存,那么必定不会相等。

2.相同的字符串在字符串常量池里只会存一份。

3.字符串常量池

String类的设计使用了共享设计模式

在JVM底层实际上会自动维护一个对象池(字符串常量池)

如果现在采用了直接赋值的模式进行String类的对象实例化操作,那么该实例化对象(字符串内容)将自动保存到这个对象池之中.如果下次继续使用直接赋值的模式声明String类对象,此时对象池之中如若有指定内容,将直接进行引用如若没有,则开辟新的字符串对象而后将其保存在对象池之中以供下次使用

4.字符串比较equals

Java 中要想比较字符串是否相等的话,就需要使用String提供的equals方法

String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1.equals(str2));
// System.out.println(str2.equals(str1)); // 或者这样写也行
// 执行结果
true

equals使用的注意事项:

现在需要比较 str 和 “Hello” 两个字符串是否相等, 我们该如何来写呢?

String str = new String("Hello");
// 方式一
System.out.println(str.equals("Hello"));
// 方式二
System.out.println("Hello".equals(str));

在上面的代码中, 哪种方式更好呢?

更推荐使用 “方式二”. 一旦 str 是 null, 方式一的代码会抛出异常, 而方式二不会

String str = null;
// 方式一
System.out.println(str.equals("Hello")); // 执行结果 抛出 java.lang.NullPointerException 异
常
// 方式二
System.out.println("Hello".equals(str)); // 执行结果 false

注意事项: “Hello” 这样的字面值常量, 本质上也是一个 String 对象, 完全可以使用 equals 等 String 对象的方法

5.理解字符串的不可变

字符串是一种不可变对象. 它的内容不可改变.

String 类的内部实现也是基于 char[] 来实现的, 但是 String 类并没有提供 set 方法之类的来修改内部的字符数组.

代码示例:

String str = "hello" ;
str = str + " world" ;
str += "!!!" ;
System.out.println(str);
// 执行结果
hello world!!!

形如 += 这样的操作, 表面上好像是修改了字符串, 其实不是. 内存变化如下:

+= 之后 str 打印的结果却是变了, 但是不是 String 对象本身发生改变, 而是 str 引用到了其他的对象.

回顾引用:

引用相当于一个指针, 里面存的内容是一个地址. 我们要区分清楚当前修改到底是修改了地址对应内存的内容发生改变了, 还是引用中存的地址改变了.

6.手动入池 intern()

我们知道字符串常量是存在字符串常量池当中的,而new的是在堆上开辟内存。

而String的 intern()方法可以把String对象手动入到字符串常量池中

// 该字符串常量并没有保存在对象池之中
String str1 = "hello" ;
String str2 = new String("hello") ;
System.out.println(str1 == str2);
// 执行结果
false
String str1 = "hello" ;
String str2 = new String("hello").intern()  ;
System.out.println(str1 == str2);
// 执行结果
true

如果str2没有
intern()方法的时候,它是指向堆上的new的String对象的,而使用了intern()方法后,就会直接指向字符串常量池的
”hello“,如果调用intern()方法的时候字符串常量池中没有 "hello"这个字符串,则会把它放入池中。

三、字符字节与字符串

1.字符转字符串

代码示例 :

		char[] array = {'h','e','l','l','o'};
        String str1 = new String(array);
        String str2 = new String(array,1,2);
        System.out.println(str1);
        System.out.println(str2);
        //运行结果
        //hello
        //el

注意:第一个参数是偏移量,偏移量是从0开始的,第二个是参数是往后从偏移量开始的位置走几步。且下标不能越界!

2.字符串转字符

指定获取字符串里的某一个字符:

		String str = "hello";
        char ch = str.charAt(4);
        System.out.println(ch);
        //运行结果
        //o

字符串转字符数组代码示例:

		String str = "hello";
        char[] array = str.toCharArray();
        for (char s : array) {
            System.out.print(s+" ");
        }

运行结果

3.字节与字符串

用法和上面的类似

代码示例:

     	byte[] bytes = {97,98,99,100};
        String str = new String(bytes,1,3);
        System.out.println(str);
        String str2 = "abcd";
        byte[] bytes1 = str2.getBytes();
        System.out.println(Arrays.toString(bytes1));

运行结果

4.编码方式

运行结果 :

常见的编码方式有 utf-8 和 GBK ,不过编码方式一般只对汉字有影响。

5.小结

那么何时使用 byte[], 何时使用 char[] 呢?

byte[] 是把 String 按照一个字节一个字节的方式处理, 这种适合在网络传输, 数据存储这样的场景下使用. 更适合 针对二进制数据来操作.char[] 是吧 String 按照一个字符一个字符的方式处理, 更适合针对文本数据来操作, 尤其是包含中文的时候

回忆概念: 文本数据 vs 二进制数据

一个简单粗暴的区分方式就是用记事本打开能不能看懂里面的内容.

如果看的懂, 就是文本数据(例如 .java 文件), 如果看不懂, 就是二进制数据(例如 .class 文件).

四、字符串常见操作

1.字符串比较

上面使用过String类提供的equals()方法,该方法本身是可以进行区分大小写的相等判断。除了这个方法之外,String类还提供有如下的比较操作:

代码示例:

		String str = "abcd";
        System.out.println("abcd".equals(str));![在这里插入图片描述](https://img-blog.csdnimg.cn/20210612164343418.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81Mzk0Njg1Mg==,size_16,color_FFFFFF,t_70#pic_center)
        System.out.println("Abcd".equalsIgnoreCase(str));//不区分大小写
        //运行结果
        //true
        //true

**compareTo()**方法前面博客有详细介绍,这里就不多说了。可以看看—>compareTo方法

在String类中compareTo()方法是一个非常重要的方法,该方法返回一个整型,该数据会根据大小关系返回三类内
容:

相等:返回0.小于:返回内容小于0.大于:返回内容大于0。

2.字符串查找

从一个完整的字符串之中可以判断指定内容是否存在,对于查找方法有如下定义:

代码示例 :

		String str = "abcdefg";
        找子串
        System.out.println(str.contains("efg"));
        从头开始找指定字符串,找到返回下标,找不到返回 -1
        System.out.println(str.indexOf("d"));
        指定位置开始找指定字符串
        System.out.println(str.indexOf("d",2));
        从后向前找指定字符串
        System.out.println(str.lastIndexOf("fg"));
        判断是否以指定字符串开头
        System.out.println(str.startsWith("abc"));
        从指定位置判断是否以该字符串开头
        System.out.println(str.startsWith("de", 3));

用法都是通过 String类点出方法名,注意就收放回值就好了。

3.字符串替换

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

代码示例:

String str = "helloworld" ;
System.out.println(str.replaceAll("l", "!"));
System.out.println(str.replaceFirst("l", "!"));

运行结果

注意如果替换的是特殊字符,则需要使用转义字符。

代码示例:

	String str1 = "192\\168\\1\\1" ;
        System.out.println(str1.replaceAll("\\\\", "+"));
        String str2 = "www.baidu.com";
        System.out.println(str2.replaceAll("\\.", "%20"));

运行结果

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

4.字符串拆分

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

代码示例:

		String str1 = "192.168.1.1" ;
        String[] array = str1.split("\\.");
        for (String s : array) {
            System.out.println(s);
        }

运行结果

注意:下面的的这段代码是不能被拆分的

		String str1 = "192\168\1\1" ;
        String[] array = str1.split("\\\\");
        for (String s : array) {
            System.out.println(s);
        }

运行结果:

因为 \ 后面跟两到三个数字会被转义成一个八进制数字。

注意事项:

字符"|","*","+“都得加上转义字符,前面加上”".而如果是"",那么就得写成"\".如果一个字符串中有多个分隔符,可以用"|"作为连字符.

多次拆分代码示例:

		String str = "name=zhangsan&age=18";
        String[] result = str.split("&|=") ;
        for (String s : result) {
            System.out.println(s);
        }

运行结果:

5.字符串截取

从一个完整的字符串之中截取出部分内容。

代码示例:

		String str = "abcdef";
        System.out.println(str.substring(3));
        System.out.println(str.substring(2, 4));//左闭右开
        运行结果
        def
        cd

注意事项:

索引从0开始注意前闭后开区间的写法, substring(0, 5) 表示包含 0 号下标的字符, 不包含 5 号下标 6.其他操作方法

这些都比较简单,用的时候查就好了。

五、StringBuffer 和 StringBuilder

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

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

通常来讲String的操作比较简单,但是由于String的不可更改特性,为了方便字符串的修改,提供StringBuffer和StringBuilder类。
StringBuffer 和 StringBuilder 大部分功能是相同的,只有较小的区别。

1.append()方法

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

public synchronized StringBuffer append(各种数据类型 b)

代码示例:

		StringBuffer str1 = new StringBuffer("abcd");
        StringBuilder str2 = new StringBuilder("abcd");
        str1.append(123);
        str2.append("hij");
        System.out.println(str1);
        System.out.println(str2);

运行结果:

StringBuffer 和 StringBuilder 大部分功能是相同的,它们的append()方法的方法可以拼接各种数据类型。

注意:

String和StringBuffer最大的区别在于:String的内容无法修改,而StringBuffer的内容可以修改。频繁修改字符串的情况考虑使用StingBuffer。

因为 String通过+拼接会产生临时对象,而 StringBuffer 和 StringBuilder 只会在当前对象上进行拼接。

2.字符串反转 reverse( )

代码示例:

		StringBuffer str1 = new StringBuffer("abcdefg");
        StringBuilder str2 = new StringBuilder("654321");
        System.out.println(str1.reverse());
        System.out.println(str2.reverse());

运行结果:

3.删除指定范围的数据 delete( )

代码示例:

		StringBuffer str1 = new StringBuffer("abcdefg");
        StringBuilder str2 = new StringBuilder("654321");
        System.out.println(str1.delete(2, 5));
        System.out.println(str2.delete(4, 6));

运行结果:

4.插入数据 insert( )

代码示例:

		StringBuffer str1 = new StringBuffer("abcdefg");
        StringBuilder str2 = new StringBuilder("654321");
        str1.insert(0,"你好吗").delete(0,1);
        System.out.println(str1);
        System.out.println(str2.delete(0, 3).insert(0, "你好世界"));

运行结果:

5.StringBuffer 和 StringBuilder的区别

来看一下 StringBuffer 和 StringBuilder 的 append 方法

1.String的拼接会产生临时对象,但是后两者每次都只是返回当前对象的引用

2.String的加号拼接,会被底层优化为一个StringBuilder

3.StringBuilder和String,一般如果不涉及到多线程的情况下才会使用

4.StringBuffer(创建锁、销毁锁、都是耗费资源的)

六、总结

1.如果以后涉及到字符串的拼接,一定要使用 StringBuffer 和 StringBuilder 的 append()方法

2.注意String类中两种对象实例化的区别

3.相同的字符串在字符串常量池中只会存一份

希望大家可以多多关注我们的其他文章!

(0)

相关推荐

  • 快速入门介绍Java中强大的String.format()

    前言 从 Java 5.0 开始,String 类新增了一个强大的字符串格式化方法 format().这个方法到现在用的人还是不多,实在是一种浪费.本文带你快速过一遍这个方法的功能,将来你要用到格式化文本的时候,可能就不需要再借用第三方类库或自己去实现了. 首先看一个简单例子: String formatted = String.format("%s今年%d岁.", "小李", 30); // "小李今年30岁." 不用我多解释,你也可以看出:

  • JavaScript JSON.stringify()的使用总结

    一.使用方法 1.基本用法 JSON.stringify()可以把一个JavaScript对象序列化为一个JSON字符串. let json1 = { title: "Json.stringify", author: [ "浪里行舟" ], year: 2021 }; let jsonText = JSON.stringify(json1); 默认情况下,JSON.stringify()会输出不包含空格或缩进的JSON字符串,因此jsonText的值是这样的: &q

  • Java String保存字符串的机制

    String 真的是 Immutable 的吗 Java 中的 Unicode 字符串会按照 Latin1(所有的字符都小于 0xFF 时)或者 UTF16 的编码格式保存在 String 中,保存为 byte 数组: private final byte[] value; 通常所说的 Immutable 都是指 final bytes 在 String 初始化后就不会修改,所有字符串的相关操作都是不会修改原数组而是创建新的副本. 但是数组元素理论上是可以修改的,比如下面通过反射的方式,将字符串

  • Java基础入门语法--String类

    今天带大家了解一下java的基础法语---String 字符串是我们以后工作中非常常用到的类型. 使用起来都非常简单方便, 我们一定要使用熟练. 那么C语言中是否有字符串类型? 答案是 " 没有 " !! char *p = " hello"; 那么p 的类型是一个字符串类型么? 不是,p是一个指针!! 而在 Java当中 是有 字符串类型的--String 一.定义方式 创建字符串的方式有很多种,常见的构造 String 的方式如以下: 方式一:直接赋值法 Str

  • java新手入门——String类详解

    目录 一.创建字符串 1. 直接赋值(常用) 2. new String 3. 字符数组转String 4.String类中两种对象实例化的区别 二.字符串比较相等 1.直接比较字符串 2.字符串在内存中的存储 3.字符串常量池 4.字符串比较equals 5.理解字符串的不可变 6.手动入池 intern() 1.字符转字符串 2.字符串转字符 3.字节与字符串 4.编码方式 5.小结 四.字符串常见操作 1.字符串比较 2.字符串查找 3.字符串替换 4.字符串拆分 5.字符串截取 五.St

  • 基于Java中的StringTokenizer类详解(推荐)

    StringTokenizer是字符串分隔解析类型,属于:Java.util包. 1.StringTokenizer的构造函数 StringTokenizer(String str):构造一个用来解析str的StringTokenizer对象.java默认的分隔符是"空格"."制表符('\t')"."换行符('\n')"."回车符('\r')". StringTokenizer(String str,String delim)

  • Java Date与String的相互转换详解

    Java Date与String的相互转换详解 前言: 我们在注册网站的时候,往往需要填写个人信息,如姓名,年龄,出生日期等,在页面上的出生日期的值传递到后台的时候是一个字符串,而我们存入数据库的时候确需要一个日期类型,反过来,在页面上显示的时候,需要从数据库获取出生日期,此时该类型为日期类型,然后需要将该日期类型转为字符串显示在页面上,Java的API中为我们提供了日期与字符串相互转运的类DateForamt.DateForamt是一个抽象类,所以平时使用的是它的子类SimpleDateFor

  • JAVA中的Configuration类详解

    本文主要研究的是Java中的Configuration类的用法,涉及maven自动加载,pom.xml配置和简单的Java代码,具体如下. properties文件是Java平台默认的配置文件格式,其优点是格式清晰,简单易懂,使用commons-configuration读取properties文件也比较简单,代码如下: 基本用法: 1.加载jar包,我使用maven自动加载,pom.xml配置如下: <dependency> <groupId>commons-configurat

  • Java基础之Object类详解

    object类的介绍 object是所有类的直接父类或者是间接父类,为什么这么说呢? 可以查询java8的API帮助文档: 可见在这样的一个类树中,所有的类的根还是Object类 在IDEA中新建一个类,系统会默认继承Object类 public class Pet extends Object{ } 那么Dog继承了Pet类的属性和行为方法,还会继承Object类的属性和行为方法了吗?这一点是肯定的,Pet类作为Object类的子类,Dog类作为Pet类的子类,所以说Object是Dog类的间

  • Java精确计算BigDecimal类详解

    引言 float和double类型的主要设计目标是为了科学计算和工程计算.他们执行二进制浮点运算,这是为了在广域数值范围上提供较为精确的快速近似计算而精心设计的.然而,它们没有提供完全精确的结果,所以不应该被用于要求精确结果的场合.但是,商业计算往往要求结果精确,这时候BigDecimal就派上大用场啦. 先看下面代码 public static void main(String[] args) { System.out.println(0.2 + 0.1); System.out.printl

  • Java项目常见工具类详解

    目录 JWT工具类 MD5工具类 视频点播工具类 公共常量工具类 日期操作工具类 Http客户端工具类 获取IP工具类 JWT工具类 这里一共涉及四个方法: 传入用户信息获得token 传入token字符串判断token是否存在与有效 传入HttpServletRequest,通过获取Header中的token判断是否存在与有效 根据token获取用户id public class JwtUtils { //token过期时间 public static final long EXPIRE =

  • Java并发编程ThreadLocalRandom类详解

    目录 为什么需要ThreadLocalRandom ThreadRandom原理详解 为什么需要ThreadLocalRandom java.util.Random一直都是使用比较广泛的随机数生成工具类,而且java.lang.Math中的随机数生成也是使用的java.util.Random实例. 我们下面看一下java.util.Random的使用方法: import java.util.Random; public class code_4_threadRandom { public sta

  • Java SpringMVC 异常处理SimpleMappingExceptionResolver类详解

    Spring3.0 对异常的处理方式总共有两种: 一种是使用 HandlerExceptionResolver 接口,并且 Spring 已经提供默认的实现类 SimpleMappingExceptionResolver. 第二种方法是在 Controller 内部实现,灵活性更高. 从目前的调查结果来看,这两种方式不能共存.我们一般在项目中使用第一种方法. 下面分别描述一下这两种使用方式: 一.基于 HandlerExceptionResolver 接口的方式 使用这种方式只需要实现 reso

  • Java String类详解_动力节点Java学院整理

    引题 在Java语言的所有数据类型中,String类型是比较特殊的一种类型,同时也是面试的时候经常被问到的一个知识点,本文结合Java内存分配深度分析关于String的许多令人迷惑的问题.下面是本文将要涉及到的一些问题,如果读者对这些问题都了如指掌,则可忽略此文. 1.Java内存具体指哪块内存?这块内存区域为什么要进行划分?是如何划分的?划分之后每块区域的作用是什么?如何设置各个区域的大小? 2.String类型在执行连接操作时,效率为什么会比StringBuffer或者StringBuild

随机推荐