• Java中的String类


    String类

    String类的简单认识

    String, 即字符串类型;在java代码中应用广泛,为了符合java面向对象的核心思想,java语言提供了String类;具体体现在代码中,就是当被双引号引起来时,代表一个字符串。在java中,不存在字符串结束标志的说法,一般判断字符串是否结束是通过字符串的长度来判断的;
    确定字符串长度的函数是 length( );

    public class Test2 {
        public static void main(String[] args) {
            
            String str="hello";
            System.out.println(str.length());
            System.out.println("hello".length());   //也可以直接通过字符串调用
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    字符串的构造

    字符串的构造方式有许多,但是最常用的主要有3种方式:

    • 直接使用常量字符串;
    	String str="hello";
    
    • 1

    这种构造方式实际只在内存中开辟了一块空间,将双引号引起来的内容保存在字符串常量池中;

    • 使用new String创建;
     String  str=new String("hello");
    
    • 1

    这种构造方式在内存中会开辟2块空间,即“hello”保存在字符串常量池中,同时new String 也是在堆上开辟了一块内存;

    • 使用字符数组进行构造;
     char [] chars= {'h','e','l','l','o'};
     String str=new String(chars);
    
    • 1
    • 2

    这是这种构造方式的源码:
    在这里插入图片描述可以看到,其实是利用copyOf又开辟了一块数组空间

    这种构造方式也是开辟了2块内存,即首先在堆上创建一个String对象,然后利用copyof重新开辟数组空间,将参数字符串数组中内容拷贝到String对象中;

    String的内在存储形式

    观察String的源码:
    在这里插入图片描述这是String类的成员属性,包含了2个部分,即value和hash,其中字符串的具体内容是存储在value部分的;因此String是一种引用类型,内部并不存储字符串本身;

    字符串的比较

    • 使用==比较2个字符串的地址是否一致,即是否指向同一个对象;
    • 使用equals逐个比较2个字符串中的字符是否一致,返回的是boolean类型;
    • 使用compareTo方法比较2个字符的差值,返回int 类型;
    • 使用equalsIgnoreCase( )或compareToIgnoreCase( )忽略大小写进行比较;
    public static void main(String[] args) {
            String str1="hello";
            String str2="hello";
            //比较2个字符串是否指向同一个对象
            System.out.println(str1==str2);
    
            String str3="hello";
            String str4="world";
            //逐个比较2个字符串的字符是否一致
            System.out.println(str3.equals(str4));
    
            String str5="hello";
            String str6="aello";
            //进行字符串的大小比较,返回差值
            System.out.println(str5.compareTo(str6));
    
            String str9="hello";
            String str10="hel";
            //如果前k个字符相等(k为两个字符长度最小值),返回两个字符串的长度差值
            System.out.println(str9.compareTo(str10));
    
            String str7="hello";
            String str8="Hello";
            //忽略大小写,比较方法与equals()一致
            System.out.println(str7.equalsIgnoreCase(str8));
            ///忽略大小写,比较方法与compareTo()一致
            System.out.println(str7.compareToIgnoreCase(str8));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    在这里插入图片描述

    字符串查找

    public static void main(String[] args) {
            String s = "ababcdddcbcdbdcdbc";
    
            //charAt(int index) 返回index位置上的字符
            System.out.println(s.charAt(3));  //b
    
            //indexOf(int ch) 返回ch第一次出现的位置,没有返回-1
            System.out.println(s.indexOf('c'));     //4
    
            //indexOf(int ch, int fromIndex)  从fromIndex位置开始找ch第一次出现的位置,没有返回-1
            System.out.println(s.indexOf('c', 5));     //8
    
            //indexOf(String str) 返回str第一次出现的位置,没有返回-1
            System.out.println(s.indexOf("bc"));        //3
    
            //indexOf(String str, int fromIndex) 从fromIndex位置开始找str第一次出现的位置,没有返回-1
            System.out.println(s.indexOf("bd", 8));       //12
    
            //lastIndexOf(int ch) 从后往前找,返回ch第一次出现的位置,没有返回-1
            System.out.println(s.lastIndexOf('c'));     //17
    
            //lastIndexOf(int ch, int fromIndex) 从fromIndex位置开始找,从后往前找ch第一次出现的位置,没有返回-1;
            System.out.println(s.lastIndexOf('c', 10));     //10
    
            // lastIndexOf(String str) 从后往前找,返回str第一次出现的位置,没有返回-1
            System.out.println(s.lastIndexOf("db"));        //15
    
            //lastIndexOf(String str, int fromIndex) 从fromIndex位置开始找,从后往前找str第一次出现的位置,没有返回-1
            System.out.println(s.lastIndexOf("cb", 8));     //8
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    有关字符串的转化

    数值与字符串的相互转化

    public static void main(String[] args) {
            //字符串转数字
            String str="0730";
    
            //Integer、Double是java中的包装类型,根据转化的数值进行选择
            System.out.println(Integer.valueOf(str));       //730
            System.out.println(Integer.valueOf("5678"));        //5678
            System.out.println(Double.valueOf("89.67"));        //89.67
    
            //数字转字符串
            System.out.println(String.valueOf(8765));       //8765
            System.out.println(String.valueOf(90.09));      //90.09
            System.out.println(String.valueOf(true));       //true
            System.out.println(String.valueOf('A'));        //A
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    大小写转换

    public static void main(String[] args) {
            String str="hello";
            String str1="HeLLo";
    
            //小写转大写
            System.out.println(str.toUpperCase());      //HELLO
    
            //大写转小写
            System.out.println(str1.toLowerCase());     //hello
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    大小写转换只针对字母;

    字符串转数组

    public static void main(String[] args) {
            //字符串转数组
            String str="hello";
            char[] chars=str.toCharArray();
            System.out.println(Arrays.toString(chars));     // [h, e, l, l, o]
    
            //数组转字符串
            char [] ch={'h','e','l','l','o'};
            String str1=new String(ch);
            System.out.println(str1);       //hello
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    格式化

    public static void main(String[] args) {
            String s = String.format("%d-%d-%d", 2022, 7,30);
            System.out.println(s);
        }
    
    • 1
    • 2
    • 3
    • 4

    字符串的替换

     public static void main(String[] args) {
            String str="asddsaasdfdsa";
    
            //替换掉字符串中所有的指定内容
            System.out.println(str.replace('a','p'));       //psddsppsdfdsp
            //替换字符串中指定的首个字符
            System.out.println(str.replaceFirst("s","m"));      //amddsaasdfdsa
            
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    字符串的拆分

    全部划分

    public static void main(String[] args) {
            String str="welcome to new world";
            
            //将所有字符串按照指定的分隔符拆分
            String [] s=str.split(" ");
            for (String st:s) {
                System.out.println(st);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述
    分组划分:

    public static void main(String[] args) {             
        String str = "welcome to new world";             
                                                         
        //根据规定的分隔符和分割后的组数划分(按顺序划分,不是平均分)                 
        String[] s = str.split(" ", 2);                  
        for (String s1 : s) {                            
             System.out.println(s1);                     
        }                                                
                                                         
    }                                                    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述特殊分隔符需要进行转义

    public static void main(String[] args) {                          
         String str="192.168.1.2" ;                                   
         String [] s=str.split("\\.")  ;//一些特殊的分隔符需要进行转义              
         for (String s1 : s) {                                        
              System.out.println(s1);                                 
         }                                                            
                                                                      
    }                                                                 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述特殊分隔符的转义方法:

    • 字符 " | " , " * " , " + "都得加上转义字符,前面加上 " \ " ;
    • 如果是 " \ " ,那么就得写成 " \\ " ;

    多次划分;

    public static void main(String[] args) {
    
            String str="1234&987=wer";
            String [] s=str.split("&");
            for (String s1:s) {
                String [] str1=s1.split("=");
                for (String s2:str1) {
                    System.out.println(s2);
                }
    
            }
    
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述
    需要多个分隔符同时划分时,使用“ | ”;

    public static void main(String[] args) {
            String str="hello,welcome to China";
            String [] s=str.split(",| ");
            for (String x:s) {
                System.out.println(x);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    字符串的截取

    public static void main(String[] args) {
            String str="hello my friend";
    
            //从指定索引截取到字符串结束
            System.out.println(str.substring(6));
    
            //截取从启始索引到结束索引的所有字符(左闭右开,不包含结束索引位置的字符)
            System.out.println(str.substring(4,9));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    字符串的左右空格

    public static void main(String[] args) {
            String str="  h e l l o  ";
    
            System.out.println(str.trim());
    
            System.out.println(str);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    字符串常量池

    前面提到,java中凡是双引号引起来的内容都是保存在字符串常量池中的,那么什么是字符串常量池呢?

    字符串常量池

    “池”:是编程中一种常见的,可以提高效率的方式,将程序当中,经常频繁使用的常量保存在池中,可以有效地提高程序的运行速度,同时节省内存,存放字符串常量的池就是字符串常量池,字符串常量池本质上是StringTable类,是一个固定大小的HashTable。

    关于字符串常量池;

    • JVM中字符串常量池只有一份,全局共享;
    • 字符串常量池中的元素随着程序的不断运行逐渐增多,一开始是空的;

    再谈字符串的创建方式

    • 直接使用字符串常量赋值
    public static void main(String[] args) {
            String s1 = "hello";
            String s2 = "hello";
            System.out.println(s1 == s2); // true
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    • 通过new创建String类对象
    public static void main(String[] args) {
            String s1=new String("hello");
            String s2=new String("hello");
            System.out.println(s1==s2);     //false
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    • intern()方法
    public static void main(String[] args) {
            char [] chars={'h','e','l','l','o'};
            String str=new String(chars);
            //intern()方法 手动将str对象的引用放入常量池中
            str.intern();
            String str1="hello";
            System.out.println(str==str1);//true
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    如果不使用该方法,输出的结果是false;当使用了该方法,就是把str对象的引用手动地放到了常量池中,后续str1创建时,首先到常量池中寻找,最后结果为true ;

    字符串的不可变性

    再次观察String的源码:

    在这里插入图片描述String类被final修饰,表明这个类是不可以被继承的;
    value被final修饰,表明value的值是不可以被修改的,但是这里不可修改的意思是不可以再value值的原有内存空间上修改,但如果是为它指定了新的内存,就是可以进行修改的;
    因此关于String的所有操作函数,实际都不是对字符串本身进行的修改,其最终返回的值都是一个新的引用;
    这是字符串的替换函数的源码,可以看到:
    在这里插入图片描述

    字符串的修改

    上面说到,String类是不能修改的,所有的修改都会创建新对象,因此这种修改的效率是较低的;

     public static void main(String[] args) {
            String str1="hello";
            String str2="world";
            String str=str1+str2;
            System.out.println(str);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述这是上面这段代码的反汇编代码,可以看到,程序的执行过程是较为复杂的,同时在反汇编代码的第3行new了一个StringBuilder对象,什么是StringBuilder呢?

    StringBuilder和StringBuffer

    为了避免对字符串进行修改时,发生的效率低下的情况,我们可以在对字符串进行修改时借助 StringBuilder和StringBuffer。

    public static void main(String[] args) {
            StringBuilder sb1 = new StringBuilder("hello");
            //根据索引设置字符的值
            sb1.setCharAt(0, 'H');
            System.out.println(sb1);        //Hello
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    这2个类提供了许多方法对字符串进行操作,同时这2个类与String最大的区别就在于String是不可修改的,但是这2个类是可以进行修改的;

    String和StringBuilder类互相转换

    • String变为StringBuilder: 利用StringBuilder的构造方法或append()方法;
     public static void main(String[] args) {
            String str="hello";
            
            //使用StringBuilder的构造方法
            StringBuilder builder=new StringBuilder(str);
            //使用其append()方法
            StringBuilder builder1=new StringBuilder();
            builder1.append(str);
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • StringBuilder变为String: 调用toString()方法
    public static void main(String[] args) {
            StringBuilder builder=new StringBuilder();
            //调用toString方法
            String str=builder.toString();
            System.out.println(str);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    StringBuffer与StringBuilder类似,与String的转换方法也类似;

    StringBuilder和StringBuffer、String的区别(!)

    • String的内容不可修改,StringBuffer与StringBuilder的内容可以修改;
    • StringBuffer与StringBuilder大部分功能是相似的;
    • StringBuffer属于线程安全操作;而StringBuilder属于线程不安全操作;

    over!

  • 相关阅读:
    python基于PHP+MySQL的校园帮忙领取快递平台
    02_Java基础语法
    PHP explode (多)分隔符(delimiters) 使用
    设计模式-Decorator模式(装饰者模式)
    Mall脚手架总结(四) —— SpringBoot整合RabbitMQ实现超时订单处理
    基于SSH开发物流仓储调度系统 课程设计 大作业 毕业设计
    第 4 章 串(串采用定长顺序存储结构实现)
    chatgpt谈论日本排放污水事件
    腾讯云服务器CVM和轻量应用服务器区别全方位对比
    vue混入mixin
  • 原文地址:https://blog.csdn.net/weixin_54175406/article/details/126065839