μ¬λλμ κ°μ΄ ννλ‘κ² κ°λ°νλ μ€ κ°μκΈ° equals() μ λν κΆκΈμ¦μ΄ μκ²Όμ΅λλ€.

==μ°μ°μλ λΉκ΅νκ³ μ νλ λκ°μ λμμ μ£Όμκ°μ λΉκ΅νλλ° λ°ν΄ Stringν΄λμ€μequalsλ©μλλ λΉκ΅νκ³ μ νλ λκ°μ λμμ κ° μ체λ₯Ό λΉκ΅νλ€.
μμ κ°μ μ€λͺ
μ μ΅ν μκ³  μλ μ€λͺ
μΌ κ²μ
λλ€. Primitive Typeμ΄ μλ κ²½μ° == λ‘ λ λμμ λΉκ΅νκ² λλ©΄ κ° κ·Έ μ체(λμ²΄λ‘ μ¬λλ€μ΄ λΉκ΅νκΈ° μνλ)λ₯Ό λΉκ΅νμ§ μκ³  λ λμμ μ£Όμκ°μ λΉκ΅νλ€λ κ²μ΄μ£ . κ·Έλμ μΌλ  Stringμ΄λ Wrapper ν΄λμ€λ₯Ό μ΄μ©μ == μ λμ ν΄μ equals() λ©μλλ₯Ό μ¬μ©νμ¬ λΉκ΅ν©λλ€. 
κ·Έλ λ€λ©΄ equals() λ©μλλ μ΄λ€ λ°©μμΌλ‘ λμνλ κ²μΌκΉμ?
equals() λ©μλλ₯Ό κΉλ³΄κΈ° μ μ λ¨Όμ  equals() κ° μ΄λμ λΆν° μλμ§λΆν° μ΄ν΄λ³΄κ³  κ°λ΄
μλ€.
λͺ¨λ  ν΄λμ€μ κ·Όμ(root)μ΄ λλ λ§λ ν΄λμ€μΈ 'Object'μλ μ΄ 11κ°μ λ©μλκ° μ‘΄μ¬νλλ°(waitκ° μ€λ²λ‘λ© λ κ²μ νλλ‘ λ³΄λ©΄ 9κ°) κ·Έ μ€ νλκ° μ΄ equals() λ©μλ μ
λλ€.

Objectμμ equals() λ μμ κ°μ΄ λ± ν μ€μ μ½λλ‘ μ μλμ΄ μλλ°..
	return (this == obj);
κ·Έλ₯ μμ£Ό μ¬ννκ² μ°Έμ‘°κ°(κ°μ²΄μ μ£Όμκ°)μ΄ κ°μμ§, λ€μ λ§ν΄μ λμΌ κ°μ²΄μΈμ§λ§μ νμΈνλ λ©μλμ λλ€.
μ΄ κ·Έλ¬λ©΄ μ²μ equals() λ₯Ό == λμ  μ¬μ©νλ μ΄μ κ° μμλ? λΌκ³  μκ°μ΄ λμ£ .
λ§μ΅λλ€. Object ν΄λμ€μμ equals() λ == μ°μ°μμ μ ν λ€λ₯Ό λ°κ° μμ΅λλ€(μ½λκ° κ°μμμ). κ·Έλμ μ€μ§μ μΈ κ°μ λΉκ΅ν΄μ€μΌ νλ λ€λ₯Έ ν΄λμ€λ€μ equals() λ₯Ό μ€λ²λΌμ΄λ©, μ¦ μ¬μ μνμ¬ μ¬μ©νκ² λ©λλ€.
κ·ΈλΌ μ΄μ  Objectλ₯Ό μμλ°μ λ€λ₯Έ ν΄λμ€λ€μμ equals() λ₯Ό μ΄λ»κ² μ€λ²λΌμ΄λ© νλμ§ μ½λλ₯Ό κΉλ³΄κ² μ΅λλ€.
λ¨Όμ  λνμ μΈ Wrapper ClassμΈ Integerλ₯Ό λ€μ¬λ€ 보면 λ€μκ³Ό κ°μ equals() λ₯Ό λ§λ  μ μμ΅λλ€. 
	/**
     * Compares this object to the specified object.  The result is
     * {@code true} if and only if the argument is not
     * {@code null} and is an {@code Integer} object that
     * contains the same {@code int} value as this object.
     *
     * @param   obj   the object to compare with.
     * @return  {@code true} if the objects are the same;
     *          {@code false} otherwise.
     */
    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }
λ€μ μ½λλ₯Ό 보면 Objectμ equals() μλ μ‘°κΈ λ€λ₯Έ κ²μ νμΈν  μ μμ΅λλ€. λ‘μ§μ νλ¦μ λ€μκ³Ό κ°μ΅λλ€.
if (obj instanceof Integer)
> λ¨Όμ  μ²μ if λ¬ΈμΌλ‘ λΉκ΅νκ³ μ νλ κ°μ²΄κ° Integer ν΄λμ€μΈμ§(μλ μμλ°μ ν΄λμ€μΈμ§) νμΈν©λλ€.
value == ((Integer)obj).intValue()
> λΉκ΅νκ³ μ νλ κ°μ²΄κ° Integer ν΄λμ€λΌλ©΄ κ°μ²΄μ valueκ° κ°μμ§ λΉκ΅ν©λλ€. μ¬κΈ°μ valueλ Integer κ°μ²΄λ₯Ό μμ±ν  λ μμ±μμ λ£λ μ«μκ°(λ¬Έμμ΄λ κ°λ₯νμ§λ§ κ²°κ³Όμ μΌλ‘ λ΄λΆμμ λͺ¨λ μ«μκ°μΌλ‘ λ³κ²½λ©λλ€. μλ―Έλ₯Ό κ°λ κ° κ·Έ μ체λΌκ³  μκ°νλ©΄ λ©λλ€)μ μλ―Έν©λλ€. μ¦, μ£Όμκ°μ΄ μλ κ°μ²΄κ° κ°μ§κ³  μλ μ«μλ₯Ό λΉκ΅ν©λλ€.
		// Integer Classμ μ μλ valueμ intValue()
		...
		private final int value;
        
       	@Deprecated(since="9", forRemoval = true)
    	public Integer(int value) {
        	this.value = value;
    	}
        
        @Deprecated(since="9", forRemoval = true)
    	public Integer(String s) throws NumberFormatException {
        	this.value = parseInt(s, 10);
    	}
        
        @IntrinsicCandidate
   	 	public int intValue() {
       		return value;
    	}
        ...
κ·Έλ λ€λ©΄ String ν΄λμ€μμλ μ΄λ¨κΉμ?
String classμ equals() μ½λλ₯Ό νμΈν΄λ΄
μλ€.
	/**
     * Compares this string to the specified object.  The result is {@code
     * true} if and only if the argument is not {@code null} and is a {@code
     * String} object that represents the same sequence of characters as this
     * object.
     *
     * <p>For finer-grained String comparison, refer to
     * {@link java.text.Collator}.
     *
     * @param  anObject
     *         The object to compare this {@code String} against
     *
     * @return  {@code true} if the given object represents a {@code String}
     *          equivalent to this string, {@code false} otherwise
     *
     * @see  #compareTo(String)
     * @see  #equalsIgnoreCase(String)
     */
    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        return (anObject instanceof String aString)
                && (!COMPACT_STRINGS || this.coder == aString.coder)
                && StringLatin1.equals(value, aString.value);
    }
λ€μμ String Classμμ μ μλ equals() λ©μλμ
λλ€. Integerλ³΄λ€ μ‘°κΈ λ‘μ§μ΄ λ§μμ§ κ²μ νμΈν  μ μλλ° νλ² νλ¦μ νμ
ν΄λ³΄κ² μ΅λλ€.
if (this == anObject)
> λ¨Όμ  λΉκ΅ λμμΈ κ°μ²΄μ λΉκ΅ν  String κ°μ²΄λ₯Ό == μ°μ°μλ‘ λΉκ΅νμ¬ κ°λ€λ©΄ trueλ₯Ό 리ν΄ν©λλ€. 
μ΄ κ·Όλ°.. μ μλ§ μ΄κ±° Objectλ κ°μ μ°μ°μ΄μλ? λΌκ³  μκ°ν  μ μμ΅λλ€.
λ€ λ§μ΅λλ€. Stringμμλ λ¨Όμ  μμ κ°μ κ°μ²΄μΈμ§λ₯Ό νμΈνμ¬ κ°λ€λ©΄ trueλ‘ λ¦¬ν΄ν΄μ€λλ€. κ°μ²΄ μ£Όμκ°(κ°μ²΄ μ체)μ΄ κ°λ€λ©΄ λΉμ°ν λ΄λΆμ λ€μ΄μλ κ°μ²΄ κ° κ·Έ μ체λ κ°κ² μ£ .
κ·Έλ λ€λ©΄ μ Integerμμλ κ°μ²΄ λΉκ΅λ₯Ό λ¨Όμ  μν΄μ£Όκ³ Stringμμλ κ°μ²΄ λΉκ΅λ₯Ό λ¨Όμ  νλκ±ΈκΉ? λΌλ μλ¬Έμ΄ λ€ μ μμ΅λλ€.(μ κ° κ·Έλ¬μ΅λλ€)
μ΄λ κ°μΈμ μΈ μκ°μΌλ‘ String κ°μ²΄μ μ€μ§μ μΈ λΉκ΅μ μμλλ μ½μ€νΈκ° Integerμ λΉν΄ 컀μ, μ μ΄μ κ°μ κ°μ²΄λΌλ©΄ μ½μ€νΈκ° ν° λ‘μ§μ μ€ννμ§ μλλ‘ νκΈ° μν¨μ΄μ§ μμκΉλΌκ³  μκ°ν©λλ€.
Integer.equals() λ ν μ€μ λΉκ΅λ‘ O(1)μ μκ°λ³΅μ‘λλ₯Ό κ°μ§λ λ°μ λΉν΄ String.equals() λ μ΄ν λ‘μ§μΈ StringLatin1.equals() μμ O(N)μ μκ°λ³΅μ‘λλ₯Ό κ°μ§κΈ°μ, Stringμ κ²½μ° μ΄λ―Έ λμΌ κ°μ²΄μμ νμΈ ν λ‘μ§μ μ’
λ£νλ€λ©΄ λ κΈ΄ μκ°λ³΅μ‘λλ₯Ό κ°λ κ²μ λ°©μ§ν  μ μμ κ²μ
λλ€. λν Integerμ κ²½μ° μ΄λ―Έ ν μ€μ μ½λλ‘ κ°μ²΄ μ체 κ°μ λΉκ΅νκ³  μκΈ°μ, λ§μ½ 쑰건문μΌλ‘ λΆκΈ°νμ¬ κ°μ²΄ μ£Όμκ°μ μΆκ°λ‘ λΉκ΅ν  κ²½μ° λ¬΄μλ―Ένκ² μ½λ μκ° λμ± λμ΄λλ κ²°κ³Όλ₯Ό μ΄λν  μ μμ κ²μ
λλ€. 
κ²°λ‘ μ μΌλ‘ String.equals() λ Integer.equals() μ λ€λ₯΄κ² μ²μ κ°μ²΄μ λμΌ μ¬λΆλ₯Ό μ κ²νκ³  λ‘μ§μ μμν©λλ€.
(anObject instanceof String aString) && (!COMPACT_STRINGS || this.coder == aString.coder) && StringLatin1.equals(value, aString.value) 
> κ·Έ λ€μ 3κ°μ 쑰건μ λΉκ΅νλλ°μ.
(anObject instanceof String aString)
> μ²μμΌλ‘ Integer λμ λ§μ°¬κ°μ§λ‘ λΉκ΅νκ³ μ νλ κ°μ²΄κ° String ν΄λμ€μΈμ§(μλ μμλ°μ ν΄λμ€μΈμ§) νμΈνκ³
(!COMPACT_STRINGS || this.coder == aString.coder)
> Stringμ΄ COMPACT_STRINGS μ΄ μλκ±°λ λΉκ΅ λμ String κ°μ²΄μ λΉκ΅ κ°μ²΄μ coder κ° κ°μμ§ λΉκ΅ν©λλ€.
μ¬κΈ°μ COMPACT_STRINGS μ charν λ¬Έμκ° 2byteλ₯Ό μ¬μ©νλλ°μ λΉν΄ μ€μ§μ μΈ LATIN-1 λ¬Έμ ννμ 1byteλ§ μ¬μ©λκΈ°μ λ°μνλ λ©λͺ¨λ¦¬ λλΉλ₯Ό ν΄κ²°νκΈ° μν΄ JDK6 λΆν° λ±μ₯ν μ΅μ ν λ°©μμΈλ° μ¬κΈ°μλ ν΄λΉ λ°©μμ΄ μ°μ΄μ§ μμλμ§λ₯Ό νμΈν©λλ€.  
coder λ κ°μ λ°μ΄νΈλ₯Ό μΈμ½λ©νλ λ° μ¬μ©λλ μΈμ½λ©μ μλ³μλ‘ λ κ°μ²΄μ coder λ₯Ό λΉκ΅νλ νμλ μΈμ½λ© μλ³μκ° κ°μμ§λ₯Ό νμΈνλ λΆλΆμ
λλ€.(coder μ κ²½μ° LATIN1,UTF16μ μ§μν©λλ€)
μ¦, COMPACT_STRINGS μ΄ μ¬μ©λμμΌλ©΄ λ κ°μ²΄μ μΈμ½λ© μλ³μκ° λ¬λΌλ κ°μ κ°μΌλ‘ μΈμνκ³  COMPACT_STRINGS μ΄ μ¬μ©λμ§ μμμΌλ©΄ λ κ°μ²΄μ μΈμ½λ© μλ³μκ° κ°μμΌμ§ κ°μ κ°μΌλ‘ μΈμνλ κ²μ νμΈν  μ μμ΅λλ€.
StringLatin1.equals(value, aString.value)
> λ§μ§λ§μΌλ‘ μμμμ 쑰건λ€μ λͺ¨λ κ²μ¦νκ³  μ¨ κ°μ²΄μ value(byte[] μλ£ν)λ₯Ό κ°μμ§ νμΈν©λλ€. StringLatin1.equals() λ©μλλ₯Ό κΉλ³΄λ©΄ λ€μκ³Ό κ°μ ꡬ쑰λ₯Ό νμΈν  μ μμ΅λλ€.
	@IntrinsicCandidate
    public static boolean equals(byte[] value, byte[] other) {
        if (value.length == other.length) {
            for (int i = 0; i < value.length; i++) {
                if (value[i] != other[i]) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }
μ λ‘μ§μ λ°λΌκ° 보면 λ¨Όμ  value.length == other.lengthμΌλ‘ λ valueμ κΈΈμ΄κ° κ°μμ§ νμΈ ν for loop μ ν΅ν΄ νλνλμ value κ° κ°μ κ°μ κ°μ§κ³  μλμ§ νμΈν©λλ€. μ΄λ λͺ¨λ  κ°μ΄ κ°λ€λ©΄ true λ₯Ό μΆλ ₯νκ² λ©λλ€.  
μ¦ String.equals() μμλ κ° κ·Έ μ체λ₯Ό λΉκ΅ν  μ μλ λ‘μ§μΌλ‘ equals λ©μλλ₯Ό μ€λ²λΌμ΄λ© ν κ²μ νμΈν  μ μμ΅λλ€.
μμ κ°μ΄ equals λ©μλλ κ°κ°μ ν΄λμ€μ μ±μ§μ λ§κ² μ€λ²λΌμ΄λ© λμ΄ μ¬μ©λκ³ μλ€λ μ¬μ€μ νμΈν μ μμμ΅λλ€.