首页 > 编程开发 > Java    日期:2026-06-20 / 浏览

1,String原理介绍

1.1 String 构造

//使用字符串常量进行赋值
String s1 = "hello world";
System.out.println(s1);
//直接new String对象
String s2 = new String("hello world");
System.out.println(s2);
//使用字符组进行构造
char[] array = {'h','e','l','l','o'};
String s4 = new String(array);
System.out.println(s4);

其他构造方法

查看源码发现:String是引用类型,内部并不存储字符串本身

1.2 字符串常量池(StringTable)

字符串常量池在JVM是StringTable类,实际上是一个固定的HashTable(哈希表),字符串常量池在堆上。

1.3 字符串内存存储

public static void main(String[] args) {
    String str1 = "abc";
    String str2 = "abc";
    System.out.println(str1 == str2);
}
//true

  • str1在进行存储的时候,“abc”会存储到字符串常量池当中
  • 当str2再次存储的时候,先会检查字符串常量池当中是否存在"abc"常量,如果存在,则不再重复存储
public static void main(String[] args) {
    String str1 = new String("abc");
    String str2 = new String("abc");
    System.out.println(str1 == str2);
}
//false

  • 第一次存储的时候,会将“abc"存储到常量池当中
  • 每次new都会在堆中实例化新的对象
  • 存储str2的时候,会使用常量池的"abc”对象进行存储

2,常用方法介绍

2.1 ==比较是否引用同一个对象

内置类型,比较的是变量中的值;对于引用类型比较的是引用中的地址

public static void main(String[] args) {
    int a = 10;
    int b = 20;
    int c = 10;
    // 对于基本类型变量,==⽐较两个变量中存储的值是否相同 
    System.out.println(a == b);  // false  
    System.out.println(a == c);  // true  
    // 对于引⽤类型变量,==⽐较两个引⽤变量引⽤的是否为同⼀个对象
    String s1 = new String("hello");
    String s2 = new String("hello");
    String s3 = new String("world");
    String s4 = s1;
    System.out.println(s1 == s2);   // false
    System.out.println(s2 == s3);   // false
    System.out.println(s1 == s4);   // true
}

2.2 equals 方法:按字典序比较

字典序:字符大小的顺序

String类重写了父类Object中equals⽅法,Object中equals默认按照==⽐较,String重写equals⽅法 后,按照如下规则进⾏⽐较

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    return (anObject instanceof String aString)
            && (!COMPACT_STRINGS || this.coder == aString.coder)
            && StringLatin1.equals(value, aString.value);
}
@IntrinsicCandidate
public static boolean equals(byte[] value, byte[] other) {
    if (value.length == other.length) {
        for (int i = 0; i < value.length; i++) {
            if (value[i] != other[i]) {
                return false;
            }
        }
        return true;
    }
    return false;
}

示例

public static void main(String[] args) {
    String s1 = new String("hello");
    String s2 = new String("hello");
    String s3 = new String("Hello");
    // s1、s2、s3引⽤的是三个不同对象,因此==⽐较结果全部为false 
    System.out.println(s1 == s2);    // false   
    System.out.println(s1 == s3);    // false   
    // equals⽐较:String对象中的逐个字符
    // 虽然s1与s2引⽤的不是同⼀个对象,但是两个对象中放置的内容相同,因此输出true 
    // s1与s3引⽤的不是同⼀个对象,⽽且两个对象中内容也不同,因此输出false 
    System.out.println(s1.equals(s2));  // true
    System.out.println(s1.equals(s3));  // false
}

2.3 compareTo 方法:按字典序进行比较

与equals不同的是,equals返回的是boolean类型,而compareTo返回的是int类型。

  1. 先按照字典序次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值
  2. 如果前k个字符相等(k为两个字符长度最小值),返回值:两个字符串长度差值
public static void main(String[] args) {
    String s1 = new String("abc");
    String s2 = new String("ac");
    String s3 = new String("abc");
    String s4 = new String("abcdef");
    System.out.println(s1.compareTo(s2));   // 不同输出字符差值-1 
    System.out.println(s1.compareTo(s3));   // 相同输出 0 
    System.out.println(s1.compareTo(s4));   // 前k个字符完全相同,输出⻓度差值 -3 
}

2.4 compareToIgnoreCase 方法:与compareTo方法相同,但是忽略大小写

public static void main(String[] args) {
    String s1 = new String("abc");
    String s2 = new String("ac");
    String s3 = new String("ABc");
    String s4 = new String("abcdef");
    System.out.println(s1.compareToIgnoreCase(s2));   // 不同输出字符差值-1 
    System.out.println(s1.compareToIgnoreCase(s3));   // 相同输出 0 
    System.out.println(s1.compareToIgnoreCase(s4));   // 前k个字符完全相同,输出⻓度差值 -3 
}

2.5 字符串查找

方法 功能
char charAt(int index) 返回index位置上字符,如果index为负数或者越界,抛出IndexOutOfBoundsException异常
int indexOf(int ch)

返回ch第一次出现的位置,没有返回-1

int indexOf(int ch,int fromIndex) 从fromIndex位置出现找ch第一次出现的位置,没有返回-1
int indexOf(String str) 返回str第一次出现的位置,没有返回-1
int indexOf(String str,int fromIndex) 从fromIndex位置开始找str第一次出现的位置,没有返回-1
int lastIndexOf(int ch) 从后往前找,返回ch第一次出现的位置,没有返回-1
int lastIndexOf(int ch,int fromIndex)

从fromIndex位置开始找,从后往前找ch第一次出现的位置,没有返回-1

int lastIndexOf(String str) 从后往前找,返回str第一次出现的位置,没有返回-1
int lastIndesOf(String str,int fromIndex) 从fromIndex位置开始找,从后往前找str第一次出现的位置,没有返回-1
public static void main(String[] args) {
    String s = "aaabbbcccaaabbbccc";
    System.out.println(s.charAt(3));               // 'b'              
    System.out.println(s.indexOf('c'));            // 6              
    System.out.println(s.indexOf('c', 10));        // 15              
    System.out.println(s.indexOf("bbb"));          // 3              
    System.out.println(s.indexOf("bbb", 10));      // 12     
    System.out.println(s.lastIndexOf('c'));        // 17              
    System.out.println(s.lastIndexOf('c', 10));    // 8              
    System.out.println(s.lastIndexOf("bbb"));      // 12              
    System.out.println(s.lastIndexOf("bbb", 10));  // 3       
}           

2.6 转换

1. 数值和字符串转化

public static void main(String[] args) {
    // 数字转字符串
    String s1 = String.valueOf(1234);
    String s2 = String.valueOf(12.34);
    String s3 = String.valueOf(true);
    String s4 = String.valueOf(new Student("Hanmeimei", 18));
    System.out.println(s1);
    System.out.println(s2);
    System.out.println(s3);
    System.out.println(s4);
    System.out.println("=================================");
    // 字符串转数字
    int data1 = Integer.parseInt("1234");
    double data2 = Double.parseDouble("12.34");
    System.out.println(data1);
    System.out.println(data2);
}

2. 大小写转换

public static void main(String[] args) {
    String s1 = "hello";
    String s2 = "HELLO";
    // ⼩写转⼤写
    System.out.println(s1.toUpperCase());
    // ⼤写转⼩写
    System.out.println(s2.toLowerCase());
}

3. 字符串转数组

public static void main(String[] args) {
        String s = "hello";
        // 字符串转数组
        char[] ch = s.toCharArray();
        for (char x :ch) {
            System.out.print(x + " ");
        }
        System.out.println();
        // 数组转字符串
        String s2 = new String(ch);
        System.out.println(s2);
    }

4. 格式化

public static void main(String[] args) {
    String s = String.format("%d-%d-%d", 2026, 6,1);
    System.out.println(s);
}

2.7 字符串替换

String replaceAll(String regex,String replacement)    替换所有的指定内容

String replaceFirst(String regex,String replacement)   替换首个内容

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

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

2.8 字符串拆分

方法 功能
String[] split(String regex) 将字符串全部拆分
String[] split(String regex,int limit) 将字符串以指定的格式,拆分为limit组
public static void main(String[] args) {
        String st1 = "hello world yes no";
        String[] result = st1.split(" ");
        for (String x : result) {
            System.out.println(x);
        }
        //hello
        //world
        //yes
        //no
    }

部分拆分

public static void main(String[] args) {
        String st1 = "hello world yes no";
        String[] result = st1.split(" ",3);
        for (String x : result) {
            System.out.println(x);
        }
        //hello
        //world
        //yes no
    }

由于split传的参数涉及正则表达式,所有有些需要特殊处理

拆分IP地址

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

注意

  1. 字符“|” “*” “+”都得加上转义字符,前面加上“\\"
  2. 如果是“\"就写成“\\\\"
  3. 多个分隔符用  |  链接

多次拆分

String str = "name=zhangsan&age=18" ; 
String[] result = str.split("&") ;
for (int i = 0; i < result.length; i++) {
    String[] temp = result[i].split("=") ; 
    System.out.println(temp[0]+" = "+temp[1]);
}
public static void main(String[] args) {
        String str = "name=zhangsan&age=18" ;
        String[] result = str.split("=|&") ;
        for (String s : result) {
            System.out.println(s);
        }
    }

2.9 字符串的截取

方法 功能
String substring(int beginIndex) 从指定索引截取到结尾
String substring(int beginIndex,int endIndex) 截取部分内容
String str = "helloworld" ; 
System.out.println(str.substring(5));
System.out.println(str.substring(0, 5));

下标从0开始,范围是[ ),左闭右开

去除左右两边的空格

String trim()  去掉字符串中的左右空格,保留中间空格

String str = "   hello  world   " ; 
System.out.println("["+str+"]");
System.out.println("["+str.trim()+"]");

2.10 intern 方法

  • 当调用 intern() 方法时,如果字符串常量池中已经包含一个等于此String对象的字符串(由equals(Object)方法确定),则返回常量池中的字符串
  • 否则,将此String对象添加到常量池中,并返回此String对象的引用
public static void main(String[] args) {
    char[] ch = new char[]{'a', 'b', 'c'};
    String s1 = new String(ch);     // s1对象并不在常量池中 
    //s1.intern();    // s1.intern();调⽤之后,会将s1对象的引⽤放⼊到常量池中
    String s2 = "abc";  // "abc" 在常量池中存在了,s2创建时直接⽤常量池中"abc"的引⽤      
    System.out.println(s1 == s2);
}
// 输出false 
// 将上述⽅法打开之后,就会输出true

3,字符串的不可变性

String是一种不可变对象,字符串中的内容是不可改变的。

所有涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象

String之所以不可以被修改的原因是内部数组为私有成员

4,字符串修改

public static void main(String[] args) {
    String s = "hello";
    s = s + " world";
    System.out.println(s);  // 输出:hello world
}

这种字符串拼接的操作,会产生临时对象,拼接一次创建一个新对象,为了执行效率java提供了StringBufferStringBuilder

4.1 StringBuilder

参考文档

方法 说明
StringBuilder append(String str) 在尾部追加,相当于String的+=
char charAt(int index) 获取index位置的字符
int length() 获取字符串的长度
int capacity() 获取底层保存字符串空间总的大小
void ensureCapacity(int mininmumCapacity)

确保容量至少等于规定的最小值

void setCharAt(int index,char ch) 将index位置的字符设置为ch
int indexOf(String str) 返回str第一次出现的位置
int indexOf(String str,int fromIndex)

返回指定子串的第一次出现的字符串中的索引,从指定的索引开始

int lastIndexOf(String str) 返回最后一次出现str的位置
int lastIndexOf(String str,int fromIndex) 从fromIndex位置开始找str最后一次出现的
StringBuilder insert(int offset,String str) 从offset位置插入
StringBuilder deleteCharAt(int index) 删除index位置字符
StringBuilder delete(int start,int end) 删除[start,end)区间内的字符
StringBuilder replace(int start,int end,String str) 将[start,end)位置的字符替换为str
String substring(int start) 从start开始一直到末尾的字符以String的形式返回
String substring(int start,int end) 从start开始一直到end的字符以String的形式返回
StringBuilder reverse() 反转字符串
String toString() 将所有字符按照String的方式返回

String Builder的内容可以修改

String和String Builder想要相互转换

  • String变为StringBuilder: 利⽤StringBuilder的构造⽅法或append()⽅法
  • StringBuilder变为String: 调⽤toString()⽅法

4.2 String Buffer

功能基本上和String Builder一样

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

介绍文档

觉得上面的内容有用吗?快来点个赞吧!

点赞() 我要打赏

温馨提示 : 本站内容来自会员投稿以及互联网,所有源码及教程均为作者总结编辑,请大家在使用过程中提前做好备份,以免发生无法预知的错误,源码类教程请勿直接用于生产环境!

 可能感兴趣的文章