[Articles] eighteen palm ● basic skills first palm: Java equals method of the String

This blog post is beating dragon 18 palms [●] Big Data technologies in which a series of articles, click View catalog: Write pictures described hereBig Data technologies ● beating dragon 18 palms


1, an example of Java
public static void main(String[] arge) {

        //1
        String str1 = new String("1234");
        String str2 = new String("1234");
        System.out.println("new String()==:" + (str1 == str2));
        //String为引用类型,str1和str2为新实例化出来的对象,分别指向不同的内存地址。而==对于引用类型判断,是判断的是引用地址,所以例子1结果为false。

        //2
        String str3 = "1234";
        String str4 = "1234";
        System.out.println("常量字符串==:" + (str3 == str4));
        //对于第二个例子,编译器编译代码时,会将"1234"当做一个常量,并保存在JVM的常量池中,然后编译String str3="1234";时,将常量的指针赋值给str3,在编译String str4="1234";时,编译器查找常量池里有相同的常量,就将存在的常量指针赋给str4,这样结果就是str3和str4都指向了常量池中的常量的地址,所以==比较结果为true;

        //3
        String str5 = "1234";
        String str6 = "12" + "34";
        System.out.println("常量表达式==:" + (str5 == str6));
        //第三个例子,编译时编译器发现能够计算出"12"+"34"的值,它是个常量表达式,就按照第二个例子一样处理,最终str5和str6都指向了同一个内存地址。所以==比较结果为true;

        //4
        String str7 = "1234";
        String str8 = "12" + 34;
        System.out.println("字符串和数字相加的表达式==:" + (str7 == str8));
        //第四个例子、第五个例子和第六个例子,类似第三个例子,编译时编译器发现是常量表达式,能够计算出值,就尽量计算出来,所以==比较结果为true;

        //5
        String str9 = "12true";
        String str10 = "12" + true;
        System.out.println("字符串和Boolen相加表达式==:" + (str9 == str10));

        //6
        final String val = "34";
        String str11 = "1234";
        String str12 = "12" + val;
        System.out.println("字符串和常量相加的表达式==:" + (str11 == str12));

        //7
        String str13 = "1234";
        String str14 = "12" + getVal();
        System.out.println("字符串和函数得来的常量相加表达式==:" + (str13 == str14));
        //第七个例子中,编译器发现str14值是要调用函数才能计算出来的,是要在运行时才能确定结果的,所以编译器就设置为运行时执行到String str14="12" + getVal();时 要重新分配内存空间,导致str13和str1是指向两个不同的内存地址,所以==比较结果为false;
    }
    private static String getVal()
    {
        return "34";
    }

Run output:    

new String () ==: false
constant string ==: true
constant expression ==: true
string and numeric expressions added ==: true
string expression and adding Boolen ==: true
string and adding a constant expression ==: true
string constants and functions obtained by adding the expression ==: false

2, Java equals in summary

(1) String is a reference type; == is the relational operators == when comparing two reference types, according to the judgment is: whether both sides are pointing to the same memory address. == in Java, is a relational operators always abide by the rules of its own, namely: Value Type relatively long time comparison value, the comparison reference type is more memory addresses.

equals (2) String class () method is to rewrite the equals Object class () method, is always the same whether two strings.

(3) when the compiler compiles the code, the specified string is a constant expression, String type is a reference type, the compiler first constant expression memory address assigned to a constant, when the same string after use, first check with the constant value of the existence of the current scope, if you use this constant, leading to point to the same memory address.

3, an example in C #

static void Main(string[] args)
{
    //1
    String str1 = new String(new char[] { '1', '2', '3', '4', });
    String str2 = new String(new char[] { '1', '2', '3', '4', });
    Console.WriteLine("①new String()方式下==:" + (str1 == str2));            
    Console.WriteLine("②new String()方式下equals:" + str1.Equals(str2));
    //C#里重写了==运算符,使得==比较的不再是引用,而是值,所以==和Equals方法是完全一致的了
    //例子1中结果都是True

    //2
    String str3 = "1234";
    String str4 = "1234";
    Console.WriteLine("③赋值常量方式下==:" + (str3 == str4));
    Console.WriteLine("④赋值常量方式下equals:" + str3.Equals(str4));
    //结果也是True

    //3
    String val = "1234";
    String str5 = val;
    String str6 = val;
    Console.WriteLine("⑤赋值变量方式下==:" + (str5 == str6));
    Console.WriteLine("⑥赋值变量方式下equals:" + str5.Equals(str6));
    //结果也是True

    Console.ReadLine();
}

Run output:

Under ①new String () == way: True
Under equals ②new String () mode: True
③ assignment under constant mode ==: True
④ assignment under constant way the equals: True
== under way ⑤ assigned variable: True
under way ⑥ variable assignment equals: True

5, Code Analysis

Equals method implemented (0) String class, whether the character string is to achieve the same comparison.

public override bool Equals(object obj)
{
    if (this == null)
    {
        throw new NullReferenceException();
    }
    string strB = obj as string;
    if (strB == null)
    {
        return false;
    }
    if (this == obj)
    {
        return true;
    }
    if (this.Length != strB.Length)
    {
        return false;
    }
    return EqualsHelper(this, strB);
}

private static unsafe bool EqualsHelper(string strA, string strB)
{
    int length = strA.Length;
    fixed (char* chRef = &strA.m_firstChar)
    {
        fixed (char* chRef2 = &strB.m_firstChar)
        {
            char* chPtr = chRef;
            char* chPtr2 = chRef2;
            while (length >= 10)
            {
                if (*(((int*) chPtr)) != *(((int*) chPtr2)))
                {
                    return false;
                }
                if (*(((int*) (chPtr + 2))) != *(((int*) (chPtr2 + 2))))
                {
                    return false;
                }
                if (*(((int*) (chPtr + 4))) != *(((int*) (chPtr2 + 4))))
                {
                    return false;
                }
                if (*(((int*) (chPtr + 6))) != *(((int*) (chPtr2 + 6))))
                {
                    return false;
                }
                if (*(((int*) (chPtr + 8))) != *(((int*) (chPtr2 + 8))))
                {
                    return false;
                }
                chPtr += 10;
                chPtr2 += 10;
                length -= 10;
            }
            while (length > 0)
            {
                if (*(((int*) chPtr)) != *(((int*) chPtr2)))
                {
                    break;
                }
                chPtr += 2;
                chPtr2 += 2;
                length -= 2;
            }
            return (length <= 0);
        }
    }
}

(1) String class of relational operators == rewritten, but also to achieve the same whether a string comparison.

public static bool operator ==(string a, string b)
{
    return Equals(a, b);
}

public static bool Equals(string a, string b)
{
    if (a == b)
    {
        return true;
    }
    if ((a == null) || (b == null))
    {
        return false;
    }
    if (a.Length != b.Length)
    {
        return false;
    }
    return EqualsHelper(a, b);
}

private static unsafe bool EqualsHelper(string strA, string strB)
{
    int length = strA.Length;
    fixed (char* chRef = &strA.m_firstChar)
    {
        fixed (char* chRef2 = &strB.m_firstChar)
        {
            char* chPtr = chRef;
            char* chPtr2 = chRef2;
            while (length >= 10)
            {
                if (*(((int*) chPtr)) != *(((int*) chPtr2)))
                {
                    return false;
                }
                if (*(((int*) (chPtr + 2))) != *(((int*) (chPtr2 + 2))))
                {
                    return false;
                }
                if (*(((int*) (chPtr + 4))) != *(((int*) (chPtr2 + 4))))
                {
                    return false;
                }
                if (*(((int*) (chPtr + 6))) != *(((int*) (chPtr2 + 6))))
                {
                    return false;
                }
                if (*(((int*) (chPtr + 8))) != *(((int*) (chPtr2 + 8))))
                {
                    return false;
                }
                chPtr += 10;
                chPtr2 += 10;
                length -= 10;
            }
            while (length > 0)
            {
                if (*(((int*) chPtr)) != *(((int*) chPtr2)))
                {
                    break;
                }
                chPtr += 2;
                chPtr2 += 2;
                length -= 2;
            }
            return (length <= 0);
        }
    }
}

(2) C # String class is the reference type, which are ultimately compare strings by EqualsHelper Equals method override method and the relational operators = =, == and Equals therefore substantially the same, no difference.

(3) Based on the above analysis, the returned value is True, both were compared based on whether the strings are the same, there is no reference to the relationship with the object, leading to the result that people feel is a value type String, String fact by Microsoft to transform, make it just like a value type.

6, summed up

(1) C # at String class == it is not a pure relational operator, and its effect is the same whether the two strings, consistent with Equals method.

(2) == Why Microsoft will rewrite, rather than keeping == operator is the essence of a relationship it?

It is on MSDN: "Although string is a reference type, but the definition of the equality operator (== and! =) For comparison string objects (not referenced) to a value which makes testing more intuitive string equality. "

But I think the fundamental reason is due to different ideas. We all know that C # is later learn Java to design, to modify the original design of Java String of == rewritten, the original intention was to make it easier to understand the user, so even a slight breach of some of the language program of unity, complete resistance, all kinds of sexual independence and so on, but also to modify the design, this is a Microsoft product for business philosophy: "user experience" is more important.

Published 74 original articles · won praise 74 · views 50000 +

Guess you like

Origin blog.csdn.net/chybin500/article/details/78931129