Java 字符串复习(String)

本文详细探讨了Java字符串(String)的基础特性,包括常量池、内存分配、拼接行为,以及与基本类型、数组、StringBuilder/StringBuffer的转换。重点介绍了字符串的常用方法和 StringBuffer/StringBuilder的区别。
摘要由CSDN通过智能技术生成

目录

一 基础

1.特点

2.JVM字符串常量池存放位置说明

3.内存方面解析

4.字符串拼接

二.String 与其他结构的转化

1.与基本数据类型包装类的转化

2.与char形数组

3.与byte[]之间的转换

4.与StringBuffer StringBuilder转换

三 String的常用方法

1.测试用的代码

2.int length()

3.public int indexOf(String str)

4.public int lastIndexOf(String str)

5. public char charAt(int index)

6.String substring(int beginIndex, int endIndex)

7.boolean startsWith(String prefix)

8.boolean endsWith(String suffix)

9.int compareTo(String anotherString)

10.boolean equals(Object anObject)

11.boolean equalsIgnoreCase(String anotherString)

12.String concat(String str)

13.String toUpperCase()

14.String toLowerCase()

15.String replace(char oldChar, char newChar)

16.String trim()

17.String[] split(String regex, int limit)

四.StringBuffer 和 StringBuilder

1. String StringBuffer StringBuilder 三者对比

2.底层原理

3.常用方法


一 基础

1.特点

1.底层是 final 的char形数组 private final char value[];

2.当字符重新赋值时 会在常量池新建一个(调用replace之后也不是对原来的进行修改)

3.类声明时 public final class String implements java.io.Serializable, Comparable<String>, CharSequence 即不能被继承

2.JVM字符串常量池存放位置说明

1.6 字符串常量池储存在方法区(永久区)

1.7 字符串常量池储存在堆空间

1.8 字符串常量池储存在方法区(元空间)

3.内存方面解析

注 堆:new出来的 常量池:不存在一模一样的字符串

@Test
    public void test(){
        String s1 = "hello";
        String s2 = "hello";
        String s3 = new String("hello");
        System.out.println(s1==s2);//true 地址值相同
//    注意 Person p1 = new Person("Tom",123); 
// Person p2 = new Person("Tom",123); p1.name==p2.name//true
// 这里的Tom相当于字面量创建的
        System.out.println(s1 == s3);//false
        s1 = "hi";
//        当变量修改时 即在变量中新建一个
        System.out.println(s2);//hello

}

       
变量 s1放在栈中 常量池中先找是否有hello 如果没有则创建一个并把首地址值给s1;
变量 s2放在栈中 常量池中先找是否有hello 有则把首地址值给s2不再进行创建
变量 s3放在栈中 new出来(引用数据类型)的放在堆里(存的是地址值指向常量池中的hello(如果没有则创建))
创建s3时创建了2个对象 一个是堆里new的结构 另一个char[]对应的常量池中的数据”hello“;

4.字符串拼接

1.常量与常量的拼接结果在常量池 且常量池不会存在相同内容的常量

2只要其中一个是变量 结果就在堆中

3.如果拼接的结果调用 intern()方法 返回值就在常量池中

  @Test
    public void test1(){
        String s1 = "hello" + "Word";
//        String 通过变量方式进行拼接操作的 是在堆空间中进行(和new的方式相同)
        String s11 = "hello" + "Word";
        String s2 = "hello";
        String s3 = new String("helloWord");
        String s4 = "Word";
        s2 +=s4;
//        public native String intern(); 
//返回值时常量中池中此常量值已经存在的 helloWord
        System.out.println(s2.intern() == s1);//true
        System.out.println(s1 == s11);//true
        System.out.println(s1==s2);//false
        System.out.println(s2 == s3);//false
//        注 final String s = "t" 声明为final的进行拼接操作相当于常量

    }

二.String 与其他结构的转化

1.与基本数据类型包装类的转化

1.String -> 基本数据类型,包装类:调用包装类的静态方法 parseXxx(str)
2.基本数据类型  -> String 调用String重载的valueOf(xxx)


        String s = "1";
        System.out.println(Integer.parseInt(s));//1
        int i = 2;
        System.out.println(String.valueOf(i));//2

2.与char形数组

1.char[] -> String 调用String构造器

2.String -> char[] toCharArray()

        char[] c = new char[]{'s','t','r'};
        String s1 = "str";
        String s3 = new String(c);
        char[] chars = s1.toCharArray();

3.与byte[]之间的转换

1.编码 String ->byte[] getBytes(StandardCharsets.UTF_8) 字符串 ->字节

2.解码 byte[] -> String 调用String构造器 字节 -> 字符串

注:字符编码一致,否则乱码

        String s2 = "s";
        byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
        String s4 = new String(bytes);

4.与StringBuffer StringBuilder转换

1.String -> StringBuffer StringBuilder:调用其构造器

2.StringBuffer StringBuilder -> String 调用其构造器或者 StringBuffer StringBuilder 的toString()方法

        String s5 = "ss";
        StringBuffer stringBuffer = new StringBuffer(s5);
        StringBuilder stringBuilder = new StringBuilder(s5);
        String s6 = stringBuilder.toString();
        String s7 = stringBuffer.toString();
        String s8 = new String(stringBuffer);
        String s9 = new String(stringBuilder);

三 String的常用方法

1.测试用的代码

        String str = "hello,word";
        String str1 = "hello,word1";
        String str2 = "Hello,word";
        String str3 = "  hello,w  ord ";
        String str4 = "h,e,l,l,o,wo,r,d";

2.int length()

//    获取字符串多少个字符
        System.out.println(str.length());//10

3.public int indexOf(String str)

//    从头开始查找str在字符串中第一次出现的位置
        System.out.println(str.indexOf("ll"));//2
//        public int indexOf(String str, int fromIndex) 
//从下标fromIndex处开始开始查找str在字符串中第一次出现的位置
        System.out.println(str.indexOf("o", 5));//7

4.public int lastIndexOf(String str)

//        从尾部开始查找str在字符串中第一次出现的位置
        System.out.println(str.lastIndexOf("o"));//7

5. public char charAt(int index)

//      查找字符串中下标为index位置出现的字符
        System.out.println(str.charAt(2));//l 

6.String substring(int beginIndex, int endIndex)

//        从fromIndex处开始截取到endIndex处结束
//        截取后不会改变str的字符
        System.out.println(str.substring(1,3));//el
//        String substring(int beginIndex) 从beginIndex处开始截取到最后
        System.out.println(str.substring(0));//hello,word

7.boolean startsWith(String prefix)

//        boolean startsWith(String prefix) 验证第一个字符
        System.out.println(str.startsWith("h"));//true
//         public boolean startsWith(String prefix, int toffset) 
//        从指定位置开始 验证第一个
        System.out.println(str.startsWith("e", 1));//true

8.boolean endsWith(String suffix)

//        验证最后一个字符
        System.out.println(str.endsWith("d"));//true

9.int compareTo(String anotherString)

//按字典的顺序比较 从第一个字符开始 如果不同 return str[0]-str[1]
// 相同接着比,比到最短字符串的长度 如果还相同 return str.length-str1.length
        System.out.println(str.compareTo(str1));
//-1 因为都相同 所以return str.length-str1.length

10.boolean equals(Object anObject)

//        比较两个字符串的内容是否一样
//        if是否是原来的 str 然后if anObject 是否是String 
//        然后if 长度是否相同 最后再一个一个比
        System.out.println(str.equals(str1));//false

11.boolean equalsIgnoreCase(String anotherString)

//        忽略大小写进行比较
        System.out.println(str.equalsIgnoreCase(str2));//true

12.String concat(String str)

//        用concat拼接两个字符成为一个新的字符串。
        System.out.println(str.concat(str1));//hello,wordhello,word1

13.String toUpperCase()

//      全部转大写
        System.out.println(str.toUpperCase());//HELLO,WORD

14.String toLowerCase()

//        全部转小写
        System.out.println(str.toLowerCase());//hello,word

15.String replace(char oldChar, char newChar)

//        用新的字符代替原来字符
        System.out.println(str.replace("ll", "gg"));//heggo,word
        System.out.println(str);//hello,word

16.String trim()

//      清除字符串str两侧的空字符串
        System.out.println(str3.trim());//hello,w  ord

17.String[] split(String regex, int limit)

//依据正则表达式分割 这里以","分割 分的组数不超过limit
        String[] split = str4.split(",", 2);
        for (String s:
             split) {
            System.out.println(s);
        }
//        h
//e,l,l,o,wo,r,d
//        String[] split(String regex) 依据正则表达式分割 这里以","分割
        String[] split1 = str4.split(",");
        for (String s:
                split1) {
            System.out.print(s+"!");
        }
//        h!e!l!l!o!wo!r!d!

四.StringBuffer 和 StringBuilder

1. String StringBuffer StringBuilder 三者对比

1.底层 都是char形数组

2.String 不可变 频繁进行修改操作时效率最低

3.StringBuffer 可变 线程安全 效率低于 StringBuilder 继承于AbstractStringBuilder

4.StringBuilder 可变 效率最高 jdk1.5新增 继承于AbstractStringBuilder

2.底层原理

1.

 public StringBuffer() {super(16); }    
StringBuffer(String str) {super(str.length() + 16);

底层创建一个长度是16的数组

2.扩容是时 2倍长度*2 +2 将原来的数组赋值给新创建的数组 int newCapacity = (value.length << 1) + 2;

3.常用方法

    @Test
    public void test9(){
//    初始化
        StringBuffer sb = new StringBuffer("hello,word");
//        增  append(boolean b) append(char c) append(int i) append(char[] str, int offset, int len)
        sb.append(1);
        System.out.println(sb);//hello,word1
//        删 delete(int start, int end)  删除多个字符
        sb.delete(1,3);
        System.out.println(sb);//hlo,word1
//        deleteCharAt(int index) 删除指定位置
        sb.deleteCharAt(2);
//        改  void setCharAt(int index, char ch)  只能是char
        sb.setCharAt(0,'s');
        System.out.println(sb);//sl,word1
//        插
//        insert(int offset, Object obj) 第一个是要插入的下标,第二个也可以是基本数据类型  可以是char形数组
        sb.insert(0,2);
        System.out.println(sb);//2sl,word1
//        遍历
        for (int i = 0; i < sb.length(); i++) {
            System.out.print(sb.charAt(i)+" ");
        }
        //2 s l , w o r d 1
//        其他
//        反转字符串 StringBuffer reverse()
        System.out.println(sb.reverse());//1drow,ls2
//      int indexOf(String str) 查询指定字符串的下标 返回第一个 int indexOf(String str, int fromIndex) 从第几个开始
        System.out.println(sb.indexOf("rd"));//-1 反转之后未找到
//        int lastIndexOf(String str) int indexOf(String str, int fromIndex)
        System.out.println(sb.lastIndexOf("rd", 2));//-1 反转之后未找到
//        截取 String substring(int start, int end) String substring(int start) 返回的是String 左闭右开
        System.out.println(sb.substring(1, 5));//drow
//        替换  StringBuffer replace(int start, int end, String str)
        System.out.println(sb.replace(1, 5, "mm"));//1mm,ls2

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值