震惊!!学妹因为不理解String,导致刷题一直出错的原因被我几秒钟解决了

Posted Code_BinBin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了震惊!!学妹因为不理解String,导致刷题一直出错的原因被我几秒钟解决了相关的知识,希望对你有一定的参考价值。

今天是星期六,没有课,我在床上睡觉

在这里插入图片描述

十一点多醒来,看了一下我祖传的手机,发现收到了一条qq信息,发的是我们软件工程专业的系花,之前一直苦苦追求我,但是都被我以各种理由婉拒:
“女人只会影响我敲代码的速度”
“女人是我敲代码路上的绊脚石”
“敲代码中,繁忙,闲人勿进”

在这里插入图片描述
我看了一下信息,原来学妹昨天刷一道算法题,做了一天,还是没做对,我看了一下题目,原来是leetcode上面一道字符串类型的题目。
在这里插入图片描述
我和学妹说,把你解题的代码发给我看看,学妹马上就发给我了

class Solution {
    public boolean arrayStringsAreEqual(String[] word1, String[] word2) {
        String sb1=new String();
        String sb2=new String();
        for (int i=0;i<word1.length;i++){
            sb1+=word1[i];
        }
        for (int i=0;i<word2.length;i++){
            sb2+=word2[i];
        }

        return sb1==sb2;
    }
}

学妹说,她每次在编译器上面解题,都是对的,但是一旦提交leetcode,就会显示时间超时,她都气哭了三次。
看到这里,我忍不住笑出了声
在这里插入图片描述
我和学妹说,你显示时间超时,是很正常的,因为你没有了解String的原理,学妹马上问道:“学长,那么原理是什么呢?”
“别急,请听学长慢慢说”,我便开始装起逼来

首先,我们先点进Stirng源码里面看看

 private final char value[];

    /** Cache the hash code for the string */
    private int hash; // Default to 0

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = -6849794470754667710L;

    /**
     * Class String is special cased within the Serialization Stream Protocol.
     *
     * A String instance is written into an ObjectOutputStream according to
     * <a href="{@docRoot}/../platform/serialization/spec/output.html">
     * Object Serialization Specification, Section 6.2, "Stream Elements"</a>
     */
    private static final ObjectStreamField[] serialPersistentFields =
        new ObjectStreamField[0];

    /**
     * Initializes a newly created {@code String} object so that it represents
     * an empty character sequence.  Note that use of this constructor is
     * unnecessary since Strings are immutable.
     */
 public String(StringBuffer buffer) {
        synchronized(buffer) {
            this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
        }
    }
 public boolean contentEquals(CharSequence cs) {
        // Argument is a StringBuffer, StringBuilder
        if (cs instanceof AbstractStringBuilder) {
            if (cs instanceof StringBuffer) {
                synchronized(cs) {
                   return nonSyncContentEquals((AbstractStringBuilder)cs);
                }
            } else {
                return nonSyncContentEquals((AbstractStringBuilder)cs);
            }
        }
        // Argument is a String
        if (cs instanceof String) {
            return equals(cs);
        }
        // Argument is a generic CharSequence
        char v1[] = value;
        int n = v1.length;
        if (n != cs.length()) {
            return false;
        }
        for (int i = 0; i < n; i++) {
            if (v1[i] != cs.charAt(i)) {
                return false;
            }
        }
        return true;
    }

通过这我们可以看到String其实是由char数组组成,并且用synchronized修饰了,这样就确保了线程的安全,但是有一点不好的是,每一次String类型的变量需要改变的时候,都要重新创建一个Stirng,再把新的字符放进去,这样就极大的消耗了性能,所以在做这道题目的时候,学妹提交才会出现时间超时的错误,所以这里我们用StringBuffer会比较好。
学妹听后恍然大悟,说道:“原来如此,学长你好厉害哦,那我去试一下”

过了一分钟后
“呜呜呜学长,又出现问题了”
在这里插入图片描述
“不可能啊?时间超时了?把你代码给我看看”

class Solution {
    public boolean arrayStringsAreEqual(String[] word1, String[] word2) {
        StringBuffer sb1=new StringBuffer();
        StringBuffer sb2=new StringBuffer();
        for (int i=0;i<word1.length;i++){
            sb1.append(word1[i]);
        }
        for (int i=0;i<word2.length;i++){
            sb2.append(word2[i]);
        }

        return sb1==sb2;
    }
}

在这里插入图片描述
学妹说:“这一次直接报错了,两个字符串明明一模一样,但是却返回false,学长你到底行不行啊?”
我去,居然怀疑我行不行,那我可不能忍了,于是我说道:
“这是你自己写错了,你没有理解String还有StringBuffer”
“怎么又怪我了?”学妹委屈的说道

那就听我慢慢的说完吧

  • 首先我们要知道“==”与“equals”是不一样的
  • “==”比较的是两个字符串的地址,不能比较内容
  • String的“equals”重写了,所以可以比较两个字符串的内容
  • StringBuffer因为没重写equals方法,直接继承了Object的equals方法,所以不行

怕学妹到时候又出错,我干脆给她写了一个

class Solution {
    public boolean arrayStringsAreEqual(String[] word1, String[] word2) {
        StringBuffer sb1=new StringBuffer();
        StringBuffer sb2=new StringBuffer();
        for (int i=0;i<word1.length;i++){
            sb1.append(word1[i]);
        }
        for (int i=0;i<word2.length;i++){
            sb2.append(word2[i]);
        }

        return sb1.toString().equals(sb2.toString());
    }
}

果不其然,对了
“哇谢谢学长,学长好厉害啊,对了学长,今天我室友都出去了,我一个人在寝室好无聊,能不能陪我去看看电影啊,记得带一下身份证”
我就知道,她这么不爱学习的人怎么会问我算法题,肯定是另有企图
“对不起哦学妹,我要敲代码,因为…”
在这里插入图片描述
注意:
以上内容纯属扯淡

以上是关于震惊!!学妹因为不理解String,导致刷题一直出错的原因被我几秒钟解决了的主要内容,如果未能解决你的问题,请参考以下文章

震惊,99.9% 的同学没有真正理解字符串的不可变性

震惊,99.9% 的同学没有真正理解字符串的不可变性

哀嚎遍野!学妹跟学弟分手了,因为JavaEE期末课设SSM太难了!呜呼哀哉!

哀嚎遍野!学妹跟学弟分手了,因为JavaEE期末课设SSM太难了!呜呼哀哉!

学妹问我,并发问题的根源到底是什么?

震惊!这样终止线程,竟然会导致服务宕机?