转载

java常用类——String

java.lang.String

  1. String类型的特点:
    1)String类型是不能被继承的;
    2)String类型的对象是不可变的,也就是说我们每次修改字符串都是产生了新的对象;
    3)由于String类型的对象是不可变的,使得我们把一些字符串存到常量池里,常量池中的对象是可以共享的;
  2. HotSpot虚拟机的常量池在哪里呢?
    JDK 1.6及之前 常量池是在方法区里的;
    JDK 1.7在堆中单独划分了一块用来存储常量;
    JDK 1.8从堆中拿出来放到了元空间Metaspace里,元空间在本地内存里;
  3. String对象的底层存储:
    JDK1.9之前是通过char[]来存储的;
    JDK1.9之后是通过byte[]存储的;
  4. String对象是怎么实现不可变的?
    1)底层char[]是final修饰的,也就控制了该字符串对象长度的不可变;
    2)底层的char[]是私有的,程序员是无法直接操作的,并且String类也没有提供修改方法,String类提供的所有方法都是返回新的对象;
  5. 字符串的比较问题:

    1)== 比较对象的地址:

    //在常量池中相同的字符串常量比较才会返回true:
    public void cmp01(){
        String s1 = "zzn";
        String s2 = "zzn";
        System.out.println(s1==s2);//true
    }
    //在堆中的字符串和在常量池中的字符串==比较是不会相等的:
    public void cmp02(){
        String s1 = new String("zzn");
        String s2 = "zzn";
        System.out.println(s1==s2);//false
    }
    //在堆中的两个字符串==比较也是不会相等的:
    public void cmp03(){
        String s1 = new String("zzn");
        String s2 = new String("zzn");
        System.out.println(s1==s2);//false
    }

    2)equals()方法比较两个对象的内容:只要是内容相同不论是在常量池还是堆都是true;

    public void cmp01(){
     String s1 = "zzn";
     String s2 = "zzn";
     System.out.println(s1.equals(s2));//true
     }
    public void cmp02(){
        String s1 = new String("zzn");
        String s2 = "zzn";
        System.out.println(s1.equals(s2));//true
    }
    public void cmp03(){
        String s1 = new String("zzn");
        String s2 = new String("zzn");
        System.out.println(s1.equals(s2));//true
    }

    3)equalsIgnoreCase()方法,忽略大小写比较内容,不论是在堆还是常量池只要内容上只有大小写差别就会返回true;

    public void cmp01(){
        String s1 = "zzn";
        String s2 = "ZZN";
        System.out.println(s1.equalsIgnoreCase(s2));//true
    }
    public void cmp02(){
         String s1 = new String("zzn");
         String s2 = "ZZN";
         System.out.println(s1.equalsIgnoreCase(s2));//true
     }
    public void cmp03(){
        String s1 = new String("ZZN");
        String s2 = new String("zzn");
        System.out.println(s1.equalsIgnoreCase(s2));//true
    }

    4)字符串比较大小:

    ·自然排序:实现了java.lang.comparable接口:

    //区分大小写,String类实现了java.lang.comparable接口中的public int compareTo(T o);方法;
    
     public void cmp01(){
    
         String s1 = "zzna";
         String s2 = "ZZN";
         if (s1.compareTo(s2) > 0){
             System.out.println(s1 + " > " + s2);
         }else if (s1.compareTo(s2) == 0){
             System.out.println(s1 + " = " + s2);
         }else if (s1.compareTo(s2) < 0){
             System.out.println(s1 + " < " + s2);
         }
     //结果:zzna > ZZN
     }
    //不区分大小写,String类自己提供了public int compareToIgnoreCase(String str)方法;
    public void cmp01(){
    
        String s1 = "zzn";
        String s2 = "ZZN";
        if (s1.compareToIgnoreCase(s2) > 0){
            System.out.println(s1 + " > " + s2);
        }else if (s1.compareToIgnoreCase(s2) == 0){
            System.out.println(s1 + " = " + s2);
        }else if (s1.compareToIgnoreCase(s2) < 0){
            System.out.println(s1 + " < " + s2);
        }
    // 结果:zzn = ZZN
    }

    ·定制排序:Collator做比较器;

    public static void main(String[] args) {
        String[] array = {"周震南","薛之谦","白敬亭"};
        // getInstance();获取当前默认语言环境的Collator。
        // getInstance(Locale.CHINA);指定语言环境为中文获得Collator比较器
        Arrays.sort(array, Collator.getInstance(Locale.CHINA));
        System.out.println(Arrays.toString(array));
    }
  6. 字符串有几个对象问题;
    1)String str = "zzn";只有常量池中的一个字符串对象;
    2)string str = new String("zzn");在堆中有一个new出来的对象,在String pool中有一个字符串常量对象;
    3)String str1 = new String("zzn");
    String str2 = new String("zzn");在堆中有2个new出来的String对象,在String pool中有一个字符串常量对象(共享的);
  7. 关于拼接结果在堆还是在 String pool的问题:

    1)常量 + 常量 在Spring pool中;

    2)常量 + 变量 在堆中;

    3)变量 + 变量 在堆中;

    4)**.intern() 在String pool中;

    public static void main(String[] args) {
         String s1 = "hello";
         String s2 = "world!";
         String s3 = "helloworld!";
    
         // 常量变量拼接结果在堆中;
         String str1 = s1 + "world!";
         // 变量变量拼接结果在堆中;
         String str2 = s1 + s2;
         // 常量常量拼接结果在String pool中;
         String str3 = "hello" + "world!";
    
         System.out.println(s3==str1);//false
         System.out.println(s3==str2);//false
         System.out.println(s3==str3);//true
     }
     ---------------------------------------------------------------------------------
     public void test02() {
         final String s1 = "hello";
         String s2 = "world!";
         String s3 = "helloworld!";
    
         // 被final修饰的s1也是字符串常量,常量常量拼接结果在String pool中;
         String str1 = s1 + "world!";
         // 变量常量拼接结果在堆中;
         String str2 = s1 + s2;
         // 常量常量拼接结果在String pool中;
         String str3 = "hello" + "world!";
    
         System.out.println(s3==str1);//true
         System.out.println(s3==str2);//false
         System.out.println(s3==str3);//true
     }
     ---------------------------------------------------------------------------------
     public void test03() {
         final String s1 = "hello";
         String s2 = "world!";
         String s3 = "helloworld!";
    
         // 被final修饰的s1也是字符串常量,常量常量拼接结果在String pool中;
         String str1 = s1 + "world!";
         // 用intern()方法把拼接的结果放到Spring pool中;
         String str2 = (s1 + s2).intern();
         // 常量常量拼接结果在String pool中;
         String str3 = "hello" + "world!";
    
         System.out.println(s3==str1);//true
         System.out.println(s3==str2);//true
         System.out.println(s3==str3);//true
     }
  8. 关于空字符串的问题:

    1)哪些才是空字符串对象?

    public void nullString01(){
        String s1;//局部变量未初始化
        String s2 = null;//初始化为null,java.lang.NullPointerException
    
        String s3 = "";// String pool中的空字符串常量对象;
        String s4 = new String();//堆中的空字符串对象
        String s5 = new String("");//一共两个对象 堆中的String对象,String pool中的空字符串常量对象;
    
    }

    --------持续更新------------P113-t154----------------

原文  https://segmentfault.com/a/1190000023218680
正文到此结束
Loading...