String类详解(Java)

基本语法

  1. String类是用来保存字符串常量的类,具有内容不变性
  2. 格式
    • String str = “hello”;
    • String str = new String(“hello”);
  3. String类细节
  1. String类有很多的构造器(重载),常用的有String(String s)、String(char[] a)、String(char[] a,int startIndex,int count)、String(byte[] b)(这个构造器常用于网络编程)
  2. String类实现了两个重要的接口
    1. Serializable:String可以串行化,可以在网络传输
    2. Comparable:String对象可以相互比较大小
  3. String的内容具有不变性
    1. String类由final关键字修饰,表示该类不能被其他类所继承
    2. String类中的一个 char[] value 数组由final关键字修饰,表示该数组的地址不可被修改。

详解equals与"=="

  • equals与"=="均为比较,其中equals比较的是两个字符串内容是否相同。 " == “比较的是两个字符串的"值”,即两个字符串的地址。
  • 首先我们需要理解String类对象创建的底层机制。String类存放的字符串常量来自堆中的常量池,常量池的本质是一个哈希表。
    1. 当创建一个对象时,例如:String a = “Hello”,底层会先在常量池中寻找是否存在"Hello"这个字符串常量,如果存在,就在栈中创建一个对象引用指向常量池中该字符串常量,如果不存在就现在常量池中创建"Hello"常量,然后再在栈中创建一个对象引用指向常量池中该字符串常量在这里插入图片描述

    2. 当用String b = new String(“Hello”)创建一个对象时,首先依旧会在堆中的常量池中寻找是否有"Hello"常量,然后在堆中创建一个新的对象指向常量池中的”Hello“字符串常量.然后再在栈中创建对象引用指向堆中创建的对象在这里插入图片描述

  1. 因此当用equals比较String类对象a和b时结果为true;用"=="比较String对象a和b时结果为false
String a = "Hello";
String b = new String("Hello");
a==b; //false
a.equals(b); //true

String类常用方法

equals //区分大小写,判断内容是否相等
equalslgnoreCase //忽略大小写,判断内容是否相等
length //获取字符串的长度
indexOf //获取字符(字符串)在字符串中第1次出现的索引,索引从0开始,找不到就返回-1
lastIndexOf //获取字符(字符串)在字符串中最后1次出现的索引,索引从0开始,找不到返回-1
substring //截取指定范围的字串
substring(n) //从索引n处开始取之后的所有字符
substring(n1,n2) //从索引n1处开始截取到n2-1的位置
trim //去前后空格
charAt //获取某索引处的字符,注意不能使用Str[index]这种方式
toUpperCase //转换成大写
toLowerCase //转换成小写
contact //拼接字符串
s.contact(“hhh”).contact(“hhh”).contact(heiheihei)
replace //替换字符串
s1 =s .replace(“aa”,“bbb”);将字符串中的aa全部转换成bbb
s.replace方法对s字符串不作影响
split //以某种字符为标志将字符串进行分割
s.split(’,’);//以’,'为分割将字符串分成若干个字串
toCharArray //将字符串转换成字符数组
compareTo //比较两个字符串大小,当两个字符串长度相等时,返回第一个不相等字符的差(前者-后者)
//字符串不相等时,如果在较小字符串中能够找到不相等的字符与前者一样,如果已有的字符全部相等则返回两个字符串长度的差(前者-后者)
format //格式化字符串
format的内容和c语言的printf语句内容相同

public class TestDemo {
    public static void main(String[] args) {
        //把字符数组转为字符串
        char[] chars = {'a','b','c'};
        String s = new String(chars);
        System.out.println(s);
        String s1 = new String(chars,1,2);
        System.out.println(s1);


        String s2 = "hello";
        //获取字符串中的某个单个字符
        System.out.println(s2.charAt(1)); //e
        //将字符串转为字符数组
        char[] chars1 = s2.toCharArray();
        System.out.println(Arrays.toString(chars1)); //hello

        //字节数组转为字符串
        byte[] bytes = {1,2,3,4};
        String s3 = new String(bytes,1,2);
        //字符串转为字节
        String s4 = "qiuruixiang";
        byte[] bytes1 = s4.getBytes();

    }


    @Test
    public void test(){
        //字符串比较大小
        String s1 = "hello";
        String s2 = "hell";
        //比较两个字符串内容是否相等
        System.out.println(s1.equals(s2)); //false
        //忽略大小写比较两个字符串内容是否相等
        System.out.println(s1.equalsIgnoreCase(s2)); //false
        //比较两个字符串的大小
        //compareTo方法:
        // 1.两个字符串长度相等,返回第一个对应位置字符不相同的ASCll码的差值
        // 2.两个字符串长度不相等,首先比较都有字符的位置是否存在差异,存在就返回1的结果,如果都相同
        // 则返回字符串长度的差值
        System.out.println(s1.compareTo(s2)); //1
    }
    @Test
    public void test1(){
        //字符串查找
        String s1 = "hello";
        String s2 ="he";
        //查找s1中是否有子串s2,返回布尔值
        System.out.println(s1.contains(s2)); //true
        //从s1指定位置查找s1中是否有子串s2,存在就返回对应索引值,否则返回-1
        //原理是KMP算法
        System.out.println(s1.indexOf(s2,2)); //false
        //从倒数某个位置开始查找
        System.out.println(s1.lastIndexOf(s2,2)); //true
        //从母串指定位置判断是否以某个子串开始,返回布尔值
        System.out.println(s1.startsWith(s2,1));
        //判断母串是否以某个子串结束,返回布尔值
        System.out.println(s1.endsWith(s2));
    }

    @Test
    public void test2(){
        //字符串替换
        String s1 = "aaabadasd";
        //将原串中的某个字符全部换为另外一个字符
        // 注意!:replace的结果会new一个新的String对象,不会改变原串
        String s2 = s1.replace('a','q'); //qqqbqdqsd
        System.out.println(s1);
        System.out.println(s2);

        //将原串中的某个子串全部替换为另外一个字符串(字符串长度不要求)
        String s3 = s1.replaceAll("ab","qiu"); //aaqiuadasd
        System.out.println(s3);
        //将原串中的第一个确定的子串替换为另外一个字符串(字符串长度不要求)
        String s4 = s1.replaceFirst("aa","qiu"); //aaqiuadasd
        System.out.println(s4);
    }

    @Test
    public void test3(){
        //字符串分割
        String s1 = "qiuruixiang=10";
        String[] s = s1.split("=");
        for(String s2:s) {
            //limit负责控制分割的最多份数
            String[] s3 = s2.split("rui",2);
            for(String s4:s3){
                System.out.println(s4); //qiu  xiang
            }

            System.out.println(s2); // qiuruixiang 10
        }
        //注意:当分割符号为|,*,.时,不能直接使用这些字符,要用转义字符"\\"来修饰
        //注意:用\来分割时,字符串要写成:192\\168\\1\\1,split中要写成("\\\\"),因为\会和"结合

        //如果1个字符串有多个分隔符,要用|连接
        String s2 = "qiu:rui&xiang";
        String[] strings = s2.split("&|:");
        for(String s3:strings){
            System.out.println(s3); //qiu  rui  xiang
        }
    }

    @Test
    public void test4(){
        //字符串的截取

        String s = "hello~world";
        //从s的下标2开始截取子串
        String sub = s.substring(2); //llo~world
        //如果下标为0,不会创建新对象!
        System.out.println(s.equals(s.substring(0))); //hello~world
        //返回s指定的字符串(左闭右开)
        String sub1 = s.substring(2,4); //ll
    }

    @Test
    public void test5(){
        //字符串转换

        //去除一个字符串首尾所有空格,保留中间空格
        String s = "     ab   cd        ";
        String s1 = s.trim(); //ab    cd
        System.out.println(s1);
        System.out.println("==========");

        //把字符串中的小写字母转为大写字母
        String s2 = "abcABC11";
        String s3 = s2.toUpperCase(); //ABCABC11
        System.out.println(s3);

        //把字符串中的大写字母转为小写字母
        String s4 = s2.toLowerCase(); //abcabc11
        System.out.println(s4);


        //字符串拼接,拼接好的字符串不入池,'+'连接的常量字符入池
        String s5 = "hello";
        String s6 = "bit";
        System.out.println(s5.concat(s6)); //hellobit
    }
    @Test
    @SuppressWarnings("all")
    public void test6(){
        String a = new String("hello");
        String b = "hello";
        String c = "he" + "llo";
        String buf = "he";
        String d = buf + "llo";
        String e = "he".concat("llo");
        System.out.println(c == e); //false
        System.out.println(a==b); //false
        System.out.println(a==c);//false
        System.out.println(b==c);//true
        System.out.println(d==c);//false
        System.out.println(d==a);//false
    }
}

StringBuffer和StringBuilder

StringBuffer

  • 基本介绍:java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删,很多方法与String相同,但StringBuffer是可变长度的

  • StringBuffer是一个容器

  • StringBuffer细节

    1. StringBuffer的直接父类是AbstractStringBuffer
    2. StringBuffer实现了Serializable接口,即StringBuffer对象可以串行化
    3. 在它的父类AbstractStringBuffer中有一个char[] value属性(没有final修饰),该value数组存放字符串内容,内容不是在常量池中而是在堆中
    4. StringBuffer是一个final类,不可以被继承
  • StringBuffer常用构造器

    1. StringBuffer() : 创建一个大小为16的char[]用于存放字符内容
    2. StringBuffer(10) : 在默认char[]长度为16的基础上再加上10
  • String和StringBuffer的相互转换

      /*String转换成StringBuffer */
      String str = "hello";
      StringBuffer stringbuffer = new StringBuffer(str); //调用StringBuffer构造器
      new StringBuffer().append(str); //调用append方法
    
      /* StringBuffer转换成String*/
      StringBuffer stringbuffer1 = new StringBuffer("jack");
      String str1 = stringbuffer1.toString(); //调用toString方法
      String str2 = new String(stringbuffer1); //调用String构造器
    
  • StringBuffer的常用方法

    append(String对象) //在原先的基础上在其之后添加新的String构成新的StringBuffer

    stringbuffer.append(“hello”);

    delete(n1,n2) //删除n1~n2的字符[n1,n2);

    replace(n1,n2,str) //将n1~n2的字符修改成str[n1,n2)

    indexOf(str) //查找指定的str在字符串第一次出现的索引,找不到返回-1

    insert(n1,str) //在索引为n1处插入str,原先为n1之后的内容自动后移

    length //返回StringBuffer的长度

StringBuilder

  • 基本介绍:

    • 此类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用。单线程时优先使用该类(而不是StringBuffer)
    • StringBuilder上主要操作是append和insert方法,可重载这些方法以接受任意类型数据
  • 细节

    直接父类与StringBuffer一样是AbstractStringBuilder

    实现了Serializable:可以串行化(可以网络传输和保存到文件)

    StringBuilder类由final关键字修饰,不可被继承

    其字符序列与StringBuffer一样存放在其直接父类AbstractStringBuilder类的char[] value数组中(无final)

    方法没有做互斥处理(synchronized关键字),因此在单线程下使用

String、StringBuffer、StringBuilder的比较

  1. StringBuilder和StringBuffer非常类似,均代表可变字符序列,方法也一样
  2. String:不可变字符序列,效率低但复用性高
  3. StringBuffer:可变字符序列,效率较高,多线程
  4. StringBuilder:可变字符序列,效率最高,单线程
  5. 对String类做大量修改时不要用String类,转成StringBuilder类再转换回String
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

囚蕤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值