• 2020年9月17日 String类的特点、对象的比较、对象个数,拼接结果(变量、常量的存储位置)


    package com.atguigu.test08;
    
    import org.junit.Test;
    
    /*
     * java.lang.String:
     * 1、特点
     * (1)String类型不能被继承,因为String是由final修饰
     * (2)String类型的对象是不可变
     * 换句话说,只要修改字符串,就会产生新对象
     * (3)String对象不可变的特性,使得我们可以把一些字符串存到常量池中,
     * 字符串有常量池。常量池中的是可以共享的。
     * 
     * 字符串常量池在哪里?Oracle官方虚拟机HotSpot
     * (1)JDK1.6以及之前:方法区
     * (2)JDK1.7:挪到堆中,即在堆中单独划分了一块来存字符串常量
     * (3)JDK1.8:从堆中挪出,挪到一个“元空间meta space”,即类似于方法区
     * (4)String对象底层的存储
     * JDK1.9之前:底层是用char[]存储
     * JDK1.9之后:底层选用byte[]存储
     * 
     * (5)String对象怎么就不可变
     * ①底层char[]数组有final修饰,意味着这个数组不能扩容等,来达到存更多的字符
     * ②char[]数组是私有的,我们程序员无法直接操作这个char[]数组,而且String没有提供这样的方法,来修改char[]数组的元素的值。
     * String提供的所有的方法,对字符串的修改都是给你返回一个新的字符串对象。
     */
    public class TestString01 {
        @Test
        public void test02(){
            String s1 = "hello";
            String s2 = "hello";
            System.out.println(s1 == s2);//true,说明是同一个位置,==比较的是地址值、equals比较的是内容。。。
        }
        
        @Test
        public void test01(){
    /*        String s1 = "hello";
            s1 = "world";
            
            s1 = s1 + "java";*/
            
            String s  = "";
            change(s);
            System.out.println(s);//输出空,说明字符串不能被修改
        }
        
        public void change(String str){
            str = "hello";
        }
    }
    package com.atguigu.test08;
    
    import java.text.Collator;
    import java.util.Arrays;
    import java.util.Comparator;
    import java.util.Locale;
    
    import org.junit.Test;
    
    /*
     * 2、字符串的比较
     * (1)==:比较对象的地址
     * 结论:只有两个字符串的常量对象(并且地址相同)比较时才会返回true,其他的都是false(比如常量和变量比较也是false)
     * (2)equals:比较字符串的内容严格区分大小写
     *     因为String类型重写了Object的equals
     * (3)equalsIgnoreCase(String anotherString) :比较字符串内容,不区分大小写
     * (4)大小比较
     * String类型实现了Comparable接口,(说明)重写了compareTo方法,严格区分大小写,s1.compateTo(s2) s1>s2,返回整数,<则返回负数;
     *      依次比较对应位置的字符,以下是比较的顺序:
     *  ①比较最靠前的字母:hello和Hello,先[0]位置的h和H,h>H,就直接认定为hello>Hello
     *  ②比较第一个不一样的之母:hello和hella,先[0][1][2][3]比较,都一样,最后到[4]o>a,认定hello>hella
     *  ③比较长度: hello和helloworld,发现前面都一样,长的大
     *  
     * (5)大小比较:不区分大小写
     *  String类型还提供了一个方法compareToIgnoreCase,可以忽略大小写比较大小
     *  
     *  (6)按照每个国家的语言校对顺序
     *  java.text.Collator:Collator 类执行区分语言环境的 String 比较。使用此类可为自然语言文本构建搜索和排序例程。
     *     Collator实现了Comparator接口 ,
     *     Collator是抽象类,不能直接创建对象,它有一个直接子类RuleBasedCollator
     *     Collator内部提供了一个静态方法,可以获取一个它的子类对象
     * 
     * 自然排序:实现java.lang.Comparable接口,int compareTo(Object obj)
     * 定制排序
     */
    public class TestString02 {
        @Test
        public void test12(){
            String[] arr = {"柴林燕","张三","李四","崔志恒","甄玉禄"};
            //希望按照拼音顺序,字典顺序
            Arrays.sort(arr, Collator.getInstance(Locale.CHINA));//Locale.CHINA指定语言环境
            System.out.println(Arrays.toString(arr));
        }
        
        @Test
        public void test11(){
            String[] arr = {"柴林燕","张三","李四","崔志恒","甄玉禄"};
            //希望按照拼音顺序,字典顺序
            Arrays.sort(arr, Collator.getInstance());//默认语言环境,因为我现在的操作系统的平台是中文win
            System.out.println(Arrays.toString(arr));
        }
        
        
        @Test
        public void test10(){
            String[] arr = {"柴林燕","张三","李四","崔志恒","甄玉禄"};
            Arrays.sort(arr);//按照自然顺序,按照每一个字符的Unicode编码值排序的
            System.out.println(Arrays.toString(arr));
        }
        
        @SuppressWarnings("all")
        @Test
        public void test09(){
            String[] arr = {"hello","chai","Java","Alice","Hi"};
            //排序
            //按照字母的顺序排列,不区分大小写
            Arrays.sort(arr,new Comparator(){
    
                @Override
                public int compare(Object o1, Object o2) {
                    String s1 = (String) o1;
                    String s2 = (String) o2;
                    return s1.compareToIgnoreCase(s2);
                }
                
            });//按照元素的自然顺序排序
            System.out.println(Arrays.toString(arr));
        }
        
        @Test
        public void test08(){
            String[] arr = {"hello","chai","Java","Alice","Hi"};
            //排序
            //按照字母的顺序排列
            Arrays.sort(arr);//按照元素的自然顺序排序
            System.out.println(Arrays.toString(arr));
        }
        
        @Test
        public void test07(){
            String s1 = new String("hello");
            String s2 = new String("Hello");
            
            if(s1.compareToIgnoreCase(s2) > 0){
                System.out.println(s1 + ">" + s2);
            }else if(s1.compareToIgnoreCase(s2) < 0){
                System.out.println(s1 + "<" + s2);
            }else{
                System.out.println(s1 + "=" + s2);
            }
            
        }
        
        @Test
        public void test06(){
            String s1 = new String("hello");
            String s2 = new String("helloworld");
            
        /*    if(s1 > s2){//不能直接使用比较运算符
                
            }*/
            
            if(s1.compareTo(s2) > 0){
                System.out.println(s1 + ">" + s2);
            }else if(s1.compareTo(s2) < 0){
                System.out.println(s1 + "<" + s2);
            }else{
                System.out.println(s1 + "=" + s2);
            }
            
        }
        
        @Test
        public void test05(){
            String s1 = new String("hello");
            String s2 = new String("hello");
            System.out.println(s1.equalsIgnoreCase(s2));//true
            
            String s3 = "hello";
            System.out.println(s3.equalsIgnoreCase(s1));//true
            
            String s4 = "Hello";
            System.out.println(s3.equalsIgnoreCase(s4));//true
        }
        
        @Test
        public void test04(){
            String s1 = new String("hello");
            String s2 = new String("hello");
            System.out.println(s1.equals(s2));//true,变量变量,内容严格一致。。。
            
            String s3 = "hello";
            System.out.println(s3.equals(s1));//true,常量变量,内容严格一致。。。
            
            String s4 = "Hello";
            System.out.println(s3.equals(s4));//false,常量变量,内容不严格一致。。。
        }
        
        @Test
        public void test03(){
            String s1 = new String("hello");
            String s2 = new String("hello");
            System.out.println(s1 == s2);//false,变量变量比较,地址值不一致;
        }
        
        @Test
        public void test02(){
            String s1 = new String("hello");
            String s2 = "hello";
            System.out.println(s1 == s2);//false,变量常量比较,地址不一致;
        }
        
        @Test
        public void test01(){
            String s1 = "hello";
            String s2 = "hello";
            System.out.println(s1 == s2);//true,常量常量比较,并且地址相同;
        }
    }
    package com.atguigu.test08;
    
    import org.junit.Test;
    
    /*
     * 1、面试题
     * (1)String str = new String("hello");几个对象(2个)
     * (2)String str1 = new String("hello");
            String str2 = new String("hello");几个对象(3个)
     *
     * 2、拼接的结果在堆还是在常量池?
     * 因为只有常量池中才是共享,==比较才为true
     *
     * (1)常量 + 常量   在常量池
     * (2)变量 + 常量   在堆
     * (3)变量 + 变量   在堆
     * (4)xx.intern():在常量池
     * 
     * 3、空字符串
     * (1)""
     * (2)new String()
     * (3)new String("")
     * 
     * 四种方式:
     * (1)if(str != null && str.length() == 0)
     * (2)if(str != null && str.equals("")){
     * (3)if("".equals(str))  推荐
     * (4)if(str!=null && str.isEmpty())
     */
    public class TestString03 {
        @Test
        public void test08(){
            String str = null;
            System.out.println(test(str));
            
            String str2 = "";
            System.out.println(test(str2));
        }
        
        //判断str是否是空字符串,是就返回true,不是返回false
        public boolean test(String str){//方法4
            if(str!=null && str.isEmpty()){
                return true;
            }
            return false;
        }
        /*public boolean test(String str){//方法3
            if("".equals(str)){//推荐
                return true;
            }
            return false;
        }*/
        /*public boolean test(String str){//方法2
            if(str != null && str.equals("")){
                return true;
            }
            return false;
        }*/
    /*    public boolean test(String str){//方法1
            if(str != null && str.length() == 0){
                return true;
            }
            return false;
        }*/
        
        @Test
        public void test07(){
            String s1; //局部变量未初始化
            String s2 = null;//初始化null
            String s3 = "";//空字符串常量对象
            String s4 = new String();//空字符串对象
            String s5 = new String("");//两个对象,一个是常量池中的,一个是堆中
            
    //        System.out.println(s1);//无法使用
    //        System.out.println(s2.length());//空指针异常
            
            System.out.println(s3.length());
            System.out.println(s4.length());
            System.out.println(s5.length());
        }
        
        @Test
        public void test06(){
            String s1 = "hello";
            String s2 = "world";
            String s3 = "helloworld";
            
            String s4 = (s1 + "world").intern();//把拼接的结果放到常量池中
            String s5 = (s1 + s2).intern();
            
            System.out.println(s3 == s4);//true
            System.out.println(s3 == s5);//true
        }
        
        @Test
        public void test05(){
            final String s1 = "hello";
            final String s2 = "world";
            String s3 = "helloworld";
            
            String s4 = s1 + "world";//s4字符串内容也helloworld,s1是常量,"world"常量,常量+ 常量 结果在常量池中
            String s5 = s1 + s2;//s5字符串内容也helloworld,s1和s2都是常量,常量+ 常量 结果在常量池中
            String s6 = "hello" + "world";//常量+ 常量 结果在常量池中,因为编译期间就可以确定结果
            
            System.out.println(s3 == s4);//true
            System.out.println(s3 == s5);//true
            System.out.println(s3 == s6);//true
        }
        
        @Test
        public void test04(){
            String s1 = "hello";
            String s2 = "world";
            String s3 = "helloworld";
            
            String s4 = s1 + "world";//s4字符串内容也helloworld,s1是变量,"world"常量,变量 + 常量的结果在堆中
            String s5 = s1 + s2;//s5字符串内容也helloworld,s1和s2都是变量,变量 + 变量的结果在堆中
            String s6 = "hello" + "world";//常量+ 常量 结果在常量池中,因为编译期间就可以确定结果
            
            System.out.println(s3 == s4);//false
            System.out.println(s3 == s5);//false
            System.out.println(s3 == s6);//true
        }
        @Test
        public void test03(){
            String str1 = new String("hello");
            String str2 = new String("hello");
            
            //这两行代码,几个对象?3个
        }
        
        @Test
        public void test02(){
            String str = new String("hello");//两个字符串对象
            //一个在常量池中:hello
            //另一个在堆中,String的对象
            //堆中的这个字符串对象char[]的value数组,指向常量池中"hello"的char[]的value
        }
        
        @Test
        public void test01(){
            String str = "hello";//一个字符串对象
        }
    }
  • 相关阅读:
    JAVA基础语法练习(四)--File 及IO流
    JAVA基础语法练习(三)
    JAVA基础语法练习(二)
    JAVA基础语法练习(一)
    python 面向对象的进阶
    python面向对象基础编程
    Linux远程
    Linux系统的安装、启动及简单的命令使用
    操作系统的结构及发展历史
    操作系统简介
  • 原文地址:https://www.cnblogs.com/douyunpeng/p/13686645.html
Copyright © 2020-2023  润新知