搞定Java中的string类

版权声明:转载请注明出处 : https://blog.csdn.net/coder_what/article/details/89400953

Copyright©Stonee

String类在日常的编程工作中所用甚多,这里就string的常用方法和面试题做些记录和说明

1. 概述

看这么一行代码:String str = "abc";

我们可以把abc看成一个字符串对象,栈里面的str引用的是abc的地址

当再次 str = "bcd";

此时,abc在常量池中就变成了垃圾,等待jvm去回收

2. 常用构造方法

打开jdk11的文档: 发现一共15中构造方法,当然我们不用全都记住,列出下列几种:

package scanne;
//string的构造方法
public class Demo3_stringCOn {    
public static void  main(String [] args){   

    String s = new String();        
    System.out.println(s);  //返回空串        
    
    byte [] arr = {97,98,99};        
    System.out.println(new String(arr));    //把字节数组转换为字符串        
    
    byte [] arr2 = {97,64,65,83,52,62,98};       
    System.out.println(new String(arr2,1,3));   //转换一部分        
    
    char [] arr3 = {'s','t','o','n','e'};       
    System.out.println(new String(arr3));   //将字符数组转换成字符串        
    
    String ss1 = new String("stonee");       
    System.out.println(ss1);    
    }
}

3. 从内存图中解析String常用面试题

一共五道题,直接以程序形式呈现出来:

package stringg;
//java只要有+,就会变成字符串
public class Demo3_String {    
    public static void main(String [] args){      
    
    String s1 = "abc";  //s1等这些变量名在在栈中其实就是地址        
    String s2 = "abc";  //abc在常量池中,s1和s2引用的同一个值        
    System.out.println(s1 == s2);       //ture        
    System.out.println(s1.equals(s2));  //ture 
    // 问题1,在上述代码中,为什么结果为true
    
    String s3 = new String("abc"); //此时堆里面会拷贝常量池中的“abc”,所以有两个“abc”
    // 问题2,在上述代码中,内存中一共有几个abc?
    
    System.out.println(s1 == s3);// false 常量池和堆中地址不一样        
    System.out.println(s1.equals(s3));  //ture 值相等        
    // 问题3,在上述代码中,为什么结果为false和true
    
    String s4 = "a"+"b"+"c";        
    System.out.println(s1 == s4);   // true 编译器有常量优化机制,会把s4的值指向s1  
    System.out.println(s1.equals(s4));              //true
    // 问题4,在上述代码中,为什么结果为true
    
    String s5 = "ab" ;        
    String s6 = s5 + "c";       //s5是变量,不存在常量优化机制        
    System.out.println(s6 == s1);        //false
    System.out.println(s1.equals(s6));      //true
    // 问题5,在上述代码中,为什么结果为false和true
    }
}

在上面的代码中,每个问题基本都有详细的解答,这里通过内存图的形式详细解答:

在这里插入图片描述

刚开始会在常量池中建立常量“abc”和“ab”。因为s1-6代表的是对象的地址,所以s1 == s2 == s4。在第二个问题中,因为new是在堆中新建一个String的实例,所以需要把常量池中的“abc”拷贝到堆中去。故而s1和s3的地址不一样。对于第五个问题,在jdk6的文档中可以看到当连个字符串“+” 运算的时候,会先在堆里初始化一个StringBuffer或者StringBuilder实例,通过其中的append方法将两个字符串加起来,形成“abc”,但是要注意,此时还不是字符串,需要用到toString方法变为字符串。

4. String中常用的方法

还是那句话:点击打开jdk11的文档:

package stringg;
public class Demo4_StingMethod {    
    public static void main(String [] args){        
        String s1 = "Stonee";        
        String s2 = "Stonee is so cool";        
        String s3 = "stonee";        
        
        System.out.println(s1.equals(s3));        
        System.out.println(s1.equalsIgnoreCase(s3));        
        System.out.println(s2.contains(s1));    //是否包含s1 
        
        System.out.println(s2.startsWith(s1));  //是否以传入字符串开头   
        System.out.println(s2.endsWith(s1));      
        
        System.out.println("cool".isEmpty());        
        System.out.println("".isEmpty());        //System.out.println(null.isEmpty); null不是空字符串,是一个空常量,不能调用任何方法,否则会出现现空指针异常。null可以给任意引用常量赋值   
        
        
        
        System.out.println("王星星真帅".length());   //5 获得字符个数,不是字节码
        int arr[] = {1,2,3};
        System.out.println(arr.length); //数组的length是属性,不是方法,它没有括号
        
        System.out.println(s1.charAt(2));   //索引越界会抛出异常
        
        System.out.println(s2.indexOf(" "));    //6 如果不存在返回-1
        
        System.out.println(s2.indexOf(" i"));   //indexof可以找字符或者字符串
        
        System.out.println(s2.indexOf('o',5));  //从第五个后面找O
        
        System.out.println(s2.lastIndexOf( '0',5)); //和上个相反
        
        System.out.println(s2.substring(4,9));    //从4位置开始截取到9结束
        
        
        
        byte [] arr2 = s1.getBytes();   //通过码表把字符串转化为byte
        for (int i = 0; i < s1.length(); i++)   
            System.out.print(arr2[i] + " ");
            
        char [] arr3 = s2.toCharArray();    //把字符串转换为char数组
        for (int i = 0; i < arr3.length; i++){    
            System.out.print(arr3[i] + " ");
        }
        
        s3 = String.valueOf(arr3);  //把任意类型转换为字符串
        System.out.println("\n" + s3);  //value底层用的string的构造方法
        //当String.valueof(对象)时,用的是对象从Object类中的toString方法,不包括重写
        
        System.out.println(s1.toUpperCase());   //转换大写
        System.out.println(s1.toUpperCase().toLowerCase());     //转小写
        
        System.out.println(s1.replace('o','6'));    //替换,不存在则不替换
        
        System.out.println(" stonee ".trim());  //去掉两边空格

        System.out.println(" stonee ".trim());  //去掉两边空格
        
        System.out.println(s1.compareTo(s2));   //比较码表值,返回int行码表的差值,不区分大写小,可看源码了解


        }
    }

要注意,如果是字符串常量和变量比较,常写作:"stonee".equals(s); 为了防止空指针异常

  上面这些方法像valueof等之类的许多Java内置类中都有,要在学习中逐步锻炼举一反三的能力

5. 再来一波面试题:

        String str1 = "ab";
        String str2 = "c";
        String str3 = "ab" + "c";
        String str4 = str1 + str2;
        String str5 = "ab" + str2;
        String str6 = "ab" + new String("c");
        String str7 = "ab" + new String("c");
        String str8 = str1 + str2;

        System.out.println(str3 == str4);
        System.out.println(str3 == str5);
        System.out.println(str4 == str5);
        System.out.println(str3 == str6);
        System.out.println(str5 == str6);
        System.out.println(str4 == str8);
        System.out.println(str6 == str7);


        String str9 = "a1";
        String str10 = "a" + 1;
        System.out.println(str9 == str10);

        final String str11 = "c";
        String str12 = "ab" + str11;
        System.out.println(str3 == str12);

自己跑一下吧~

猜你喜欢

转载自blog.csdn.net/coder_what/article/details/89400953