==与equal你能都答对吗?个人笔记一

    public static void main(String[] args) {

        String str = "abc";
        str = "bcd";
        //String是只读字符串,其引用的字符串内容不可变
        //str是一个引用对象,指向字符串对象"abc"
        //str = "bcd";是让str重新指向一个新字符串"bcd"对象
        //而"abc"对象没有被改变,只是变成一个不可及对象了


        //StringBuffer线程安全效率低
        //StringBuilder线程不安全效率高
        String s1 = "hello";
        String s2 = new String("hello");
        String s3 = "he";
        String s4 = "llo";
        String s5 = "he" + "llo";
        String s6 = s3 + s4;
        String s7 ="java";
        String toString = new StringBuilder("tom").append("cat").toString();
        String toString2 = new StringBuilder("ja").append("va").toString();
        System.out.println(s1.equals(s5));//true
        System.out.println(s1 == s5);//true
        System.out.println(s1.equals(s6));//true
        System.out.println(s1 == s6);//false
        System.out.println("------------");
        System.out.println(s1.equals(s6.intern()));//true
        System.out.println(s1 == s6.intern());//true
        System.out.println(s2.equals(s2.intern()));//true
        System.out.println(s2 == s2.intern());//false
        System.out.println(s1 == s1.intern());//true
        System.out.println(s2.intern());
        System.out.println(s7 == s7.intern());//true
        System.out.println(toString == toString.intern());//true
        System.out.println(toString2 == toString2.intern());//false


    /*    一:==与equals()与hashCode
        <<Effective java>>里面是怎么介绍equals():
        自反性:a.equals(b)=true那么b.equals(a)=true
        传递性:a.equals(b)=true,b.equals(c)=true那么a.equals(c)=true
        对称性:a.equals(b)=true那么b.equals(a)=true
        一致性:a.equals(b)=true,当a和b没有被改变时,多次都是true(幂等性)
        非null值的引用x,x.equals(null)必须返回false
        ----------------提高equals的效率-----------------------
        1.用==操作符比较"参数是否为这个对象的引用"
        2.instanceof操作符检查"参数是否为正确类型"
        3.对于类中的管家属性,检查参数传入对象的属性是否与之匹配
        4.编写完equals后检查其是否满足对称性,传递性,一致性
        5.重写equals总要重写hashCode
        6.不用将equals里面的Object对象换为其他类型,重写记得加@Override
        ----------------equals对hashCode的规定----------------
        1.两个对象equasl为true,那么hashCode值一定相同
        2.两个对象的hashCode值相同,equasl不一定相同(通话,重地)
        以上2点可以不遵守,但是效率会下降(set添加元素时哈希碰撞会造成取的效率低下)

*/

    //二+的本质:
        //+的本质是: 每次+都创建一个新的StringBuilder进行append(),
        //s5,s6都是指向堆中StringBuilder,StringBuilder指向字符串常量池的"hello"

        //String的intern()方法返回字符串对象的规范表示。
        //如果s.intern() == t.intern()为true 那么s.equals(t)一定为true 。
        //得到字符串对象在常量池中对应的版本引用
        //如果常量池中有一个字符串与String对象的equals 则返回true
        //如果常量池中没有对应的字符串,则该字符串被添加到常量池中,同时返回该字符串的引用
        //"123".intern()向字符串常量池中添加"123",返回其引用
        //intern()就是看看字符串常量池中有没有这个对象,有就返回没有就创建并返回
        //,s2是堆内存中的引用,s2.intern()是字符串常量池里的字符串对象
        //,他们地址值不同,==为false
        //,他们内容一样,equals()为true
        //,s1堆内存中的引用和字符串常量池里的地址值一样,==为true
        //,在jdk加载sun.misc.Version这个类的时候有一个初始化的java字符串
        //,所以System.out.println(toString2 == toString2.intern());//false

        System.out.println("---------+和StringBuffer/StringBuilder的效率-------------------");

        //三
/*
        什么时候"+"运算符进行字符串连接比调用StringBuffer/StringBuilder
        的append()连接字符串效率高?

        从结果来看:"+"和StringBuffer/StringBuilder完全等效
        因为在java中无论使S用何种方式的字符串连接实际上都是StringBuilder
*/

        String s8 = "abc";
        String s9 = "ok" + s7 + "xyz" + 5;
        System.out.println(s9);
/*
        从运行效率和资源消耗来看:
        连接字符串表达式简单,"+"和StringBuffer/StringBuilder基本一样(如上)
        上面的代码通过反编译后内容:
        String s8=(new StringBuilder("ok")).append(s).append("xyz").append(5).toString();
*/

        String s10 = "";
        Random random = new Random();
        for (int i = 0; i < 10; i++) {
            s10 = s10 + random.nextInt(1000) + " ";
        }
        System.out.println(s9);
        //上面代码反编译后:
        //for(int i = 0; i < 10; i++){
        //s9 = (new StringBuilder(String.valueOf(s9)))
        // .append(rand.nextInt(1000)).append(" ").toString();}
        //创建StringBuilder对象的位置在for内部,每一次循环都会创建一个
        //虽然有垃圾回收器,但是工作时间不定,不断的产生垃圾还是占资源


        String s11 = "";
        Random rand = new Random();
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < 10; i++) {
            result.append(rand.nextInt(1000)).append(" ");
        }
        System.out.println(s11);

        //上面代码反编译后:
        //StringBuilder result = new StringBuilder();
        //for(int i = 0; i < 10; i++){
        //result.append(rand.nextInt(1000)).append(" ");};
        //创建StringBuilder在for语句外,效率更高,资源消耗少


        //注意尽量不用同时使用"+"和StringBuilder否则会重新创建对象


        //四
        //将上面代码在JDK1.4以下编译,必须将StringBuilder改为StringBuffer
        //因为JDK1.4以下没有StringBuilder



        //五String,StringBuffer,StringBuilder区别?
/*
        区别:
        可变不可变
        Strnig:字符串常量,修改也不会改变本身而是创建新字符串对象
        StringBuffer:修改会改变本身
        线程是否安全
        String:被定义后不可变,安全
        StrinBuffer:安全(同步锁),效率低
        StringBuilder:不安全

        共同点:
        StringBuffer和StringBuilder的父类都是AbstractStringBuilder
    他们都会调用父类的append()

*/


        System.out.println("----------Integer-----------------");
        Integer s12 = 100,s13 = 100,s14 = 150,s15 = 150;
        System.out.println(s12==s13);
        System.out.println(s14==s15);
        //如果整型字面量的值在-128 到 127 之间,
        //那么不会 new 新的 Integer 对象,而是直接引用常量池
        //中的 Integer 对象
    }

在这里插入图片描述

在这里插入图片描述
当我们执行System.out.println();
的时候
会加载System这个类
这个类有这个方法:
在这里插入图片描述
这个方法有一行代码是:sun.misc.Version.init();

在这里插入图片描述
初始化sun.misc.Version
进去这个类在这里插入图片描述
就会发现java字符串被定义了

我们自己定义的java在字符串常量池里就是这个java
所以是false

以下是出处::::::::
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值