Java中的String类

36 篇文章 0 订阅

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());   //也可以直接通过字符串调用
    }
}

字符串的构造

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

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

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

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

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

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

这是这种构造方式的源码:
在这里插入图片描述可以看到,其实是利用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));
    }

在这里插入图片描述

字符串查找

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

    }

有关字符串的转化

数值与字符串的相互转化
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

    }
大小写转换
public static void main(String[] args) {
        String str="hello";
        String str1="HeLLo";

        //小写转大写
        System.out.println(str.toUpperCase());      //HELLO

        //大写转小写
        System.out.println(str1.toLowerCase());     //hello
    }

大小写转换只针对字母;

字符串转数组
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
    }
格式化
public static void main(String[] args) {
        String s = String.format("%d-%d-%d", 2022, 7,30);
        System.out.println(s);
    }

字符串的替换

 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
        
    }

字符串的拆分

全部划分

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

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

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);                     
    }                                                
                                                     
}                                                    

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

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

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

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

多次划分;

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);
            }

        }

    }

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

public static void main(String[] args) {
        String str="hello,welcome to China";
        String [] s=str.split(",| ");
        for (String x:s) {
            System.out.println(x);
        }
    }

在这里插入图片描述

字符串的截取

public static void main(String[] args) {
        String str="hello my friend";

        //从指定索引截取到字符串结束
        System.out.println(str.substring(6));

        //截取从启始索引到结束索引的所有字符(左闭右开,不包含结束索引位置的字符)
        System.out.println(str.substring(4,9));
    }

在这里插入图片描述

字符串的左右空格

public static void main(String[] args) {
        String str="  h e l l o  ";

        System.out.println(str.trim());

        System.out.println(str);
    }

在这里插入图片描述

字符串常量池

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

字符串常量池

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

关于字符串常量池;

  • JVM中字符串常量池只有一份,全局共享;
  • 字符串常量池中的元素随着程序的不断运行逐渐增多,一开始是空的;
再谈字符串的创建方式
  • 直接使用字符串常量赋值
public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "hello";
        System.out.println(s1 == s2); // true
    }

在这里插入图片描述

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

在这里插入图片描述

  • 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
    }

如果不使用该方法,输出的结果是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);
    }

在这里插入图片描述这是上面这段代码的反汇编代码,可以看到,程序的执行过程是较为复杂的,同时在反汇编代码的第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

    }

这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);

    }
  • StringBuilder变为String: 调用toString()方法
public static void main(String[] args) {
        StringBuilder builder=new StringBuilder();
        //调用toString方法
        String str=builder.toString();
        System.out.println(str);
    }

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

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

over!

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值