Java常用类---String类

String类的概述

  • String类:代表字符串,Java程序中所有字符串字面量都作为此类的实例实现

  • String是一个final类,代表不可变的字符序列

  • 字符串是常量,用双引号引起来表示。它们的值在创建后不可修改

  • String对象的字符内容是存储在一个字符数组value[]中的

  • 源码:

    public final class String
        implements java.io.Serializable, Comparable<String>, CharSequence {
        /** The value is used for character storage. */
        private final char value[];
    
        /** Cache the hash code for the string */
        private int hash; // Default to 0
    

理解String的不可变性

在这里插入图片描述

public class StringTest {
    /*
    String:字符串,使用一对""进行表示
    1.String声明为final,不可被继承
    2.String实现了Serializable接口:表示字符串是支持序列化的
    3.String实现了Comparable接口:表示String可以比较大小
    4.String内部定义了final char[] value用来存储字符串数据
    5.String代表一个不可变的字符序列。简称:不可变性。
         体现1:当对字符串重新赋值时,需要重新指定内存区域赋值,不能使用原有的value进行赋值
         体现2:当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值
         体现3:当调用String的replace()方法修改字符或字符串时,也必须重新指定内存区域赋值
    6.通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串值声明在字符串常量池中
    7.字符串常量池中是不会存储相同内容的字符串的
     */
    @Test
    public void test1(){
        String s1 = "abc"; //字面量的定义方式
        String s2 = "abc";
        System.out.println(s1==s2);
        s1 = "hello";
        System.out.println(s1); //hello
        System.out.println(s2); //abc
        System.out.println("-------------");
        String s3 = "abc";
        s3 += "def";
        System.out.println(s3);//abcdef
        System.out.println("-------------");
        String s4 = "abc";
        String s5 = s4.replace('a','m');
        System.out.println(s4);
        System.out.println(s5);
    }
}

String不同实例化方式的对比

在这里插入图片描述

public class StringTest {
    /*
    String的实例化方式
        方式一:字面量定义的方式
        方式二:通过new+构造器的方式
     */
    @Test
    public void test1(){
        //字面量定义方式,此时s1和s2的数据javaEE声明在方法区中的字符串常量池中
        String s1 = "javaEE";
        String s2 = "javaEE";
        //通过new+构造器的方式:此时s3和s4保存的是地址值,是数据在堆空间中开辟空间之后对应的地址值
        //通过该方式,在内存中创建了两个对象(1.堆空间中new创建的对象 2.char[]对应的常量池中的数据
        String s3 = new String("javaEE");
        String s4 = new String("javaEE");
        System.out.println(s1==s2);//true
        System.out.println(s3==s4);//false
        System.out.println(s1==s3);//false
    }
}

String不同拼接操作的对比

在这里插入图片描述

public class StringTest {
    /*
    常量与常量的拼接结果在常量池中,且常量池中不会存在相同的变量
    只要其中有一个是变量,结果就在堆中
    如果拼接的结果调用intern()方法,返回值就在常量池中   
     */
    @Test
    public void test1(){
        String s1="javaEE";
        String s2="hadoop";

        String s3="javaEEhadoop";
        String s4="javaEE"+"hadoop";
        String s5=s1+"hadoop";  //只要有变量名参与的拼接,则都放在堆空间
        String s6="javaEE"+s2;
        String s7=s1+s2;
        String s8=s5.intern();//返回值得到的s8使用的是常量池中已经存在的"javaEEhadoop"
        System.out.println(s3==s4);//true
        System.out.println(s3==s5);//false
        System.out.println(s3==s6);//false
        System.out.println(s3==s7);//false
        System.out.println(s5==s6);//false
        System.out.println(s6==s7);//false
        System.out.println(s3==s8);//true
    }
}

String的一道面试题

public class StringTest {
    String str = new String("good"); //开辟在堆空间
    char[] ch={'t','e','s','t'};

    public void change(String str,char[] ch){
        str = "test ok"; //String不可变性
        ch[0] = 'b';
    }

    public static void main(String[] args) {
        StringTest ex = new StringTest();
        ex.change(ex.str,ex.ch);
        System.out.println(ex.str);//good
        System.out.println(ex.ch);//best
    }
}

JVM中涉及字符串的内存结构

在这里插入图片描述

在这里插入图片描述

String常用方法1

  • 重点要理解String的不变性
public class StringMethodTest {
    @Test
    public void test1(){
        String s1="helloworld";
        System.out.println(s1.length());
        System.out.println(s1.charAt(2));
        System.out.println(s1.charAt(8));
        System.out.println(s1.isEmpty());
        System.out.println(s1.toLowerCase());
        String s2 = s1.toUpperCase();
        System.out.println(s1);  //字符串的不可变性
        System.out.println(s2);
        System.out.println("---------------");
        String s3 = " hello world  ";
        String s4 = s3.trim();
        System.out.println(s4);
    }

    @Test
    public void test2(){
        String s1 = "helloworld";
        String s2 = "Helloworld";
        System.out.println(s1.equals(s2));//false
                   System.out.println(s1.equalsIgnoreCase(s2));//true

        String s3 = "abc";
        String s4 = s3.concat("def");
        System.out.println(s4);

        String s5 = "abc";
        String s6 = "abf";
        System.out.println(s5.compareTo(s6));//-3

        String s7 = "beijingshangguigu";
        String s8 = s7.substring(3);
        System.out.println(s7.substring(0,6)); //左闭右开
        System.out.println(s7);
        System.out.println(s8);
    }
}

String常用方法2

public class StringMethodTest {
    @Test
    public void test1(){
        String str1 = "helloworld";
        boolean b1 = str1.endsWith("d");
        boolean b2 = str1.endsWith("rld");
        System.out.println(b1);
        System.out.println(b2);

        boolean b3 = str1.startsWith("He");
        System.out.println(b3);//false

        boolean b4 = str1.startsWith("ll",2);
        System.out.println(b4);

        System.out.println(str1.contains("world"));
        System.out.println(str1.indexOf("world"));
        System.out.println(str1.indexOf("LOL"));//没找到则返回-1
        System.out.println(str1.indexOf("lo",5));//-1
        String str2 = "hellorworld";
        System.out.println(str2.lastIndexOf("or"));//返回7
        System.out.println(str2.lastIndexOf("or",6));//返回4
    }
}

String常用方法3

public class StringMethodTest {
    @Test
    public void test1(){
        String str1="beijingshangguigu";
        String str2 = str1.replace('b','d');
        String str3 = str1.replace("beijing","shanghai");
        System.out.println(str1);
        System.out.println(str2);
        System.out.println(str3);
    }
}

String与基本数据类型包装类的转换

public class StringTest {
    /*
    String与基本数据类型、包装类之间的转换
    String-->基本数据类型、包装类:调用包装类的静态方法parseXxx(str)
    基本数据类型、包装类-->String:调用String重载的valueOf(xxx)方法
     */
    @Test
    public void test1(){
        String str1 = "123";
        int num = Integer.parseInt(str1);
        System.out.println(num);

        String str2 = String.valueOf(num);
        System.out.println(str2);
        String str3 = str2 + "";
    }
}

String与char[]之间的转换

public class StringTest {
    /*
    String与char[]之间的转换
    String-->char[]:调用String的toCharArray()方法
    char[]-->String:调用String的构造器
     */
    @Test
    public void test1(){
        String str1 = "abc123";
        char[] charArray = str1.toCharArray();
        for (int i = 0; i < charArray.length; i++) {
            System.out.println(charArray[i]);
        }

        char[] arr = new char[]{'h','e','l','l','o'};
        String str2 = new String(arr);
        System.out.println(str2);
    }
}

String与byte[]之间的转换

public class StringTest {
    /*
    String与byte[]之间的转换
    String-->byte[]:调用String的getBytes()方法
    byte[]-->String:调用String的构造器

    编码:字符串-->字节
    解码:字节-->字符串  是编码的逆过程
    解码时使用的字符集必须与编码时使用的字符集一致,否则会乱码
     */
    @Test
    public void test1() throws UnsupportedEncodingException {
        String str1 = "abc123中国";
        byte[] bytes = str1.getBytes(); //默认UTF-8
        byte[] bytes1 = str1.getBytes("gbk");//指定编码集
        System.out.println(Arrays.toString(bytes));
        System.out.println(Arrays.toString(bytes1));

        String str2 = new String(bytes);//默认UTF-8
        System.out.println(str2);
    }
}

StringBuffer和StringBuilder的介绍

public class StringBufferBuilderTest {
    /*
    String、StringBuffer、StringBuilder三者的异同
    String:不可变的字符序列  底层使用final char[]存储
    StringBuffer:可变的字符序列;线程安全的,效率低 底层使用char[]存储
    StringBuilder:可变的字符序列;jdk5.0新增的,线程不安全,效率高 底层使用char[]存储
     */
    @Test
    public void test(){
        StringBuffer sb1 = new StringBuffer("abc");
        sb1.setCharAt(0,'m');
        System.out.println(sb1);
    }
}

StringBuffer的源码分析

public class StringBufferBuilderTest {
    /*
    String、StringBuffer、StringBuilder三者的异同
    String:不可变的字符序列  底层使用final char[]存储
    StringBuffer:可变的字符序列;线程安全的,效率低 底层使用char[]存储
    StringBuilder:可变的字符序列;jdk5.0新增的,线程不安全,效率高 底层使用char[]存储

    源码分析:
    String str = new String();  //new char[0]
    String str1 = new String("abc");  //new char[]{'a','b','c'}

    StringBuffer sb1 = new StringBuffer();//char[] value = new char[16] 底层创建了一个长度是16的字符数组
    sb1.append('a');//value[0]='a';
    sb1.append('b');//value[1]='b';

    StringBuffer sb2 = new StringBuffer("abc");//char[] value = new char["abc".length()+16]

    //问题1:System.out.println(sb2.length());//3
    //问题2:扩容问题:如果要添加的数据 底层数组盛不下了,就需要扩容底层的数组
            默认情况下,扩容为原来的2倍+2,同时将原有数组中的元素复制到新数组中
    开发中建议使用StringBuffer(int capacity)或StringBuilder(int capacity)
     */
    @Test
    public void test(){
        StringBuffer sb1 = new StringBuffer("abc");
        sb1.setCharAt(0,'m');
        System.out.println(sb1);

        StringBuffer sb2 = new StringBuffer();
        System.out.println(sb2.length());//0
    }
}

StringBuffer的常用类

public class StringBufferBuilderTest {
    @Test
    public void test(){
        //CRUD、长度
        StringBuffer sb1 = new StringBuffer("abc");
        sb1.append('d');
        sb1.append('e');
        System.out.println(sb1.charAt(2));
        System.out.println(sb1);
        sb1.delete(2,4);
        System.out.println(sb1);
        sb1.replace(0,2,"hello");
        System.out.println(sb1);
        sb1.insert(2,"www");
        System.out.println(sb1);
        sb1.reverse();
        System.out.println(sb1);
        String s= sb1.substring(1,3);
        System.out.println(s);
    }
}

String、StringBuffer、StringBuilder效率对比

StringBuilder效率最高

StringBuffer其次

String最差

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值