文章目录

  • 一、String类
  • 1、String简介
  • 2、字符串常量池
  • 二、字符串常用方法
  • 1、str.equals()
  • 2、get相关的方法
  • 3、截取相关的方法
  • 4、转换相关的方法
  • 5、分隔相关的方法
  • 三、StringBuilder
  • 1、StringBuilder原理图
  • 2、StringBuilder构造方法
  • 3、append方法
  • 4、String和StringBuilder相互转换
  • 四、String相关面试题
  • 1、String、StringBuffer、StringBuilder 的区别?
  • 2、String str="aaa" 与 String str=new String("aaa")一样吗?
  • 3、判断下列执行结果
  • 4、数组有没有 length()方法?String 有没有 length()方法


一、String类

1、String简介
java.lang.String类代表字符串。
    API当中说:Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。
    其实就是说:程序当中所有的双引号字符串,都是String类的对象。(就算没有new,也照样是。)

字符串的特点:
    1. 字符串的内容永不可变。【重点】
    2. 正是因为字符串不可改变,所以字符串是可以共享使用的。
    3. 字符串效果上相当于是char[]字符数组,但是底层原理是byte[]字节数组。

创建字符串的常见3+1种方式。
三种构造方法:
    public String():创建一个空白字符串,不含有任何内容。
    public String(char[] array):根据字符数组的内容,来创建对应的字符串。
    public String(byte[] array):根据字节数组的内容,来创建对应的字符串。
一种直接创建:
    String str = "Hello"; // 右边直接用双引号

注意:直接写上双引号,就是字符串对象。
/*
    创建字符串的常见3+1种方式。
    三种构造方法:
        public String():创建一个空白字符串,不含有任何内容。
        public String(char[] array):根据字符数组的内容,来创建对应的字符串。
        public String(byte[] array):根据字节数组的内容,来创建对应的字符串。
    一种直接创建:
        String str = "Hello"; // 右边直接用双引号

    注意:直接写上双引号,就是字符串对象。
 */
public class Demo01String {

    public static void main(String[] args) {

        // 使用空参构造
        String str1 = new String(); // 小括号留空,说明字符串什么内容都没有。
        System.out.println("第1个字符串:" + str1);

        // 根据字符数组创建字符串
        char[] charArray = { 'A', 'B', 'C' };
        String str2 = new String(charArray);
        System.out.println("第2个字符串:" + str2);

        // 根据字节数组创建字符串
        byte[] byteArray = { 97, 98, 99 };
        String str3 = new String(byteArray);
        System.out.println("第3个字符串:" + str3);

        // 直接创建
        String str4 = "Hello";
        String str5 = new String("asas");
        System.out.println("第4个字符串:" + str4);
    }

}
2、字符串常量池

什么是字符串常量池?

字符串常量池位于堆内存中,专门用来存储字符串常量,可以提高内存的使用率,避免开辟多块空间存储相同的字符串,在创建字符串时 JVM 会首先检查字符串常量池,如果该字符串已经存在池中,则返回它的引用,如果不存在,则实例化一个字符串放到池中,并返回其引用。

程序当中直接写上的双引号字符串,就在字符串常量池中。
    对于基本类型来说,==是进行数值的比较。
    对于引用类型来说,==是进行【地址值】的比较。
/*
字符串常量池:
    程序当中直接写上的双引号字符串,就在字符串常量池中。
    对于基本类型来说,==是进行数值的比较。
    对于引用类型来说,==是进行【地址值】的比较。
 */
public class Demo02StringPool {

    public static void main(String[] args) {
        String str1 = "abc";
        String str2 = "abc";

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

        System.out.println(str1 == str2); // true
        System.out.println(str1 == str3); // false
        System.out.println(str2 == str3); // false
    }

}

java的String字符串可以赋值多少字符 java string字符串_bc

二、字符串常用方法

1、str.equals()

==是进行对象的地址值比较,如果确实需要字符串的内容比较,可以使用两个方法:

(1)public boolean equals(Object obj):
    参数可以是任何对象,只有参数是一个字符串并且内容相同的才会给true;否则返回false。
注意事项:
    1. 任何对象都能用Object进行接收。
    2. equals方法具有对称性,也就是a.equals(b)和b.equals(a)效果一样。
    3. 如果比较双方一个常量一个变量,推荐把常量字符串写在前面。
推荐:"abc".equals(str)
不推荐:str.equals("abc")

(2)public boolean equalsIgnoreCase(String str):忽略大小写,进行内容比较。
2、get相关的方法

String当中与获取相关的常用方法有:

public int length():
    获取字符串当中含有的字符个数,拿到字符串长度。
public String concat(String str):
    将当前字符串和参数字符串拼接成为返回值新的字符串。
public char charAt(int index):
    获取指定索引位置的单个字符。(索引从0开始。)
public int indexOf(String str):
    查找参数字符串在本字符串当中首次出现的索引位置,如果没有返回-1值。
3、截取相关的方法

字符串的截取方法:

public String substring(int index):
    截取从参数位置一直到字符串末尾,返回新字符串。
public String substring(int begin, int end):
    截取从begin开始,一直到end结束,中间的字符串。
备注:[begin,end),包含左边,不包含右边。
4、转换相关的方法

String当中与转换相关的常用方法有:

public char[] toCharArray():
        将当前字符串拆分成为字符数组作为返回值。
public byte[] getBytes():
        获得当前字符串底层的字节数组。
public String replace(CharSequence oldString, CharSequence newString):
        将所有出现的老字符串替换成为新的字符串,返回替换之后的结果新字符串。
备注:CharSequence意思就是说可以接受字符串类型。
5、分隔相关的方法

分割字符串的方法:

public String[] split(String regex):
    按照参数的规则,将字符串切分成为若干部分。
注意事项:
split方法的参数其实是一个“正则表达式”,今后学习。
今天要注意:如果按照英文句点“.”进行切分,必须写"\\."(两个反斜杠)

三、StringBuilder

1、StringBuilder原理图

java的String字符串可以赋值多少字符 java string字符串_System_02


2、StringBuilder构造方法

java.lang.StringBuilder类:字符串缓冲区,可以提高字符串的效率。

构造方法:
    StringBuilder() 
        构造一个不带任何字符的字符串生成器,其初始容量为 16 个字符。
    StringBuilder(String str) 
        构造一个字符串生成器,并初始化为指定的字符串内容。
3、append方法

StringBuilder的常用方法:

public StringBuilder append(...):
    添加任意类型数据的字符串形式,并返回当前对象自身。
public class Demo02StringBuilder {
    public static void main(String[] args) {
        //创建StringBuilder对象
        StringBuilder bu = new StringBuilder();
        //使用append方法往StringBuilder中添加数据
        //append方法返回的是this,调用方法的对象bu,this==bu
        StringBuilder bu2 = bu.append("abc");//把bu的地址赋值给了bu2
        System.out.println(bu);//"abc"
        System.out.println(bu2);//"abc"
        System.out.println(bu==bu2);//比较的是地址 true

        //使用append方法无需接收返回值
        bu.append("abc");
        bu.append(1);
        bu.append(true);
        bu.append(8.8);
        bu.append('中');
        System.out.println(bu);//abc1true8.8中

        /*
            链式编程:方法返回值是一个对象,可以继续调用方法
         */
        System.out.println("abc".toUpperCase().toLowerCase().toUpperCase());
        bu.append("abc").append(1).append(true).append(8.8).append('中');
        System.out.println(bu);//abc1true8.8中

    }
}
4、String和StringBuilder相互转换

StringBuilder和String可以相互转换:

(1)String->StringBuilder:可以使用StringBuilder的构造方法
    StringBuilder(String str) 
        构造一个字符串生成器,并初始化为指定的字符串内容。
        
(2)StringBuilder->String:可以使用StringBuilder中的toString方法
    public String toString():
        将当前StringBuilder对象转换为String对象。
public class Demo03StringBuilder {
    public static void main(String[] args) {
        //1、String->StringBuilder
        String str = "hello";
        System.out.println("str:"+str);
        StringBuilder bu = new StringBuilder(str);
        //往StringBuilder中添加数据
        bu.append("world");
        System.out.println("bu:"+bu);

        //2、StringBuilder->String
        String s = bu.toString();
        System.out.println("s:"+s);
    }
}

四、String相关面试题

1、String、StringBuffer、StringBuilder 的区别?

可变性:
String类中使用字符数组保存字符串,private final char value[],所以string对象是不可变的。

StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,char[] value,这两种对象都是可变的。

线程安全性:
StringBuffer是线程安全的,StringBuilder是线程不安全的,StringBuffer在StringBuilder的方法之上加了同步锁(synchronized)修饰,保证线程安全。但他们两个中的所有方法都是相同的。

性能

每次对String 类型进行改变的时候,都会生成一个新的String对象,然后将指针指向新的String 对象。
StringBuffer每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并改变对象引用。
相同情况下使用StirngBuilder 相比使用StringBuffer 仅能获得10%~15% 左右的性能提升,但却要冒多线程不安全的风险。

对于三者使用的总结

如果要操作少量的数据用 = String

单线程操作字符串缓冲区 下操作大量数据 = StringBuilder

多线程操作字符串缓冲区 下操作大量数据 = StringBuffer
补充: 如果一个String类型的字符串,在编译时就可以确定是一个字符串常量,则编译完成之后,字符串会自动拼接成一个常量。此时String的速度比StringBuilder和StringBuffer的性能更好。

2、String str=“aaa” 与 String str=new String(“aaa”)一样吗?

不同,内存分配的方式不同。

String str=“aaa”,创建了1个对象,创建的"aaa"是常量,jvm将其分配在常量池中;
String str=new String(“aaa”),创建了2个对象,一个是在常量池中,一个在堆内存中。

3、判断下列执行结果

判断下面代码的执行结果

1	String s1 = new String("abc");    
2	String s2 = "abc";
3	System.out.println(s1 == s2);   //false
4	System.out.println(s1.equals(s2));   //true

原因:s1记录的是堆内存中对象的地址,s2记录的是常量池中的地址

1	String s1 = "a" + "b" + "c";
2	String s2 = "abc";
3	System.out.println(s1 == s2);        //true    
4	System.out.println(s1.equals(s2));   //true

原因:java中有常量优化机制,编译时就把 “a” + “b” + "c"变成“abc”赋值给s1

1	String s1 = "ab";
2	String s2 = "abc";
3	String s3 = s1 + "c";
4	System.out.println(s3 == s2);            //false
5	System.out.println(s3.equals(s2));       //true

原因:因为s1是一个变量,jvm运行的时候不认为s3=“abc”,也就是无法使用常量池。因此s3会重新创建一个对象。

4、数组有没有 length()方法?String 有没有 length()方法

数组没有 length()方法 ,有 length 的属性。String 有 length()方法。JavaScript中,获得字符串的长度是通过 length 属性得到的,这一点容易和 Java 混淆。