βκΌ νμν κ²½μ°κ° μλλ©΄
equals
λ₯Ό μ¬μ μνμ§ λ§μβ
equals
λ©μλλ μ¬μ μνκΈ° μ¬μ 보μ΄μ§λ§ κ³³κ³³μ ν¨μ μ΄ λμ¬λ¦¬κ³ μμObject
μ equals
κ° λΉκ΅μ μ νν μνν΄ μ€equals
κ° λ
Όλ¦¬μ λμΉμ±μ λΉκ΅νλλ‘ μ¬μ μλμ§ μμμ λ.==
μ°μ°μλ‘ νμΈequals
λ©μλλ‘ νμΈInteger
, String
μ²λΌ κ°μ νννλ ν΄λμ€κ° μ΄μ ν΄λΉ ν¨.β equals
λ©μλ μ¬μ μ μ, λ°λμ μλ μΌλ°κ·μ½μ λ°λΌμΌ ν¨.
μ건 | μ€λͺ |
---|---|
λ°μ¬μ±(reflexivity) | nullμ΄ μλ λͺ¨λ μ°Έμ‘° κ° xμ λν΄, x.equals(x)λ trueλ€. |
λμΉμ±(symmetry) | nullμ΄ μλ λͺ¨λ μ°Έμ‘° κ° x, yμ λν΄, x.equals(y)κ° trueλ©΄ y.equals(x)λ trueλ€. |
μΆμ΄μ±(transitivity) | nullμ΄ μλ λͺ¨λ μ°Έμ‘° κ° x, y, zμ λν΄ x.equals(y)κ° trueμ΄κ³ , y.equals(z)κ° trueλ©΄ x.equals(z)λ trueλ€. |
μΌκ΄μ±(consistency) | nullμ΄ μλ λͺ¨λ μ°Έμ‘° κ° x, yμ λν΄ x.equals(y)λ₯Ό λ°λ³΅ν΄μ νΈμΆνλ©΄ νμ trueλ₯Ό λ°ννκ±°λ νμ falseλ₯Ό λ°ννλ€. |
null-μλ | nullμ΄ μλ λͺ¨λ μ°Έμ‘° κ° xμ λν΄, x.equals(null)μ falseλ€. |
equals
λ₯Ό μ¬μ μνλ μΌμ μ§λ£¨νκ³ μ½μ§ μλ€.equals
λ©μλλ₯Ό μμμ μμ±ν΄μ£Όλ©°, μ°λ¦¬κ° μμ±νλ κ²κ³Ό κ·Όλ³Έμ μΌλ‘ λκ°μ μ½λλ₯Ό μμ±ν΄ μ€.β λΆμ£Όμν μ€μλ₯Ό λ°©μ§νκΈ° μν΄ AutoValue νλ μμν¬λ₯Ό μ κ·Ή νμ©νμ.
β
equals
λ₯Ό μ¬μ μν ν΄λμ€ λͺ¨λμμhashCode
λ μ¬μ μν΄μΌ νλ€β
equals
λ₯Ό μ¬μ μν ν΄λμ€μμ hashCode
λ₯Ό μ¬μ μνμ§ μμΌλ©΄, hashCode
μΌλ° κ·μ½μ μ΄κΈ°κ² λμ΄ ν΄λΉ ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό HashMap
μ΄λ HashSet
κ°μ 컬λ μ
μ μμλ‘ μ¬μ©ν λ λ¬Έμ κ° λ¨hashCode
λ₯Ό μ¬μ μ ν μ, λ°λμ μλ μΌλ° κ·μ½μ λ°λΌμΌ ν¨μ€λͺ | |
---|---|
1 | equals λΉκ΅μ μ¬μ©λλ μ λ³΄κ° λ³κ²½λμ§ μμλ€λ©΄, μ ν리μΌμ΄μ
μ΄ μ€νλλ λμ κ·Έ κ°μ²΄μ hashCode λ©μλλ λͺ λ²μ νΈμΆν΄λ μΌκ΄λκ² νμ κ°μ κ°μ λ°νν΄μΌ νλ€. λ¨, μ ν리μΌμ΄μ μ λ€μ μ€ννλ€λ©΄ μ΄ κ°μ΄ λ¬λΌμ Έλ μκ΄μλ€. |
2 | equals(Object)κ° λ κ°μ²΄λ₯Ό κ°λ€κ³ νλ¨νλ€λ©΄, λ κ°μ²΄μ hashCodeλ λκ°μ κ°μ λ°νν΄μΌ νλ€. |
3 | equals(Object)κ° λ κ°μ²΄λ₯Ό λ€λ₯΄λ€κ³ νλ¨νλλΌλ, λ κ°μ²΄μ hashCodeκ° μλ‘ λ€λ₯Έ κ°μ λ°νν νμλ μλ€. λ¨, λ€λ₯Έ κ°μ²΄μ λν΄μλ λ€λ₯Έ κ°μ λ°νν΄μΌ ν΄μν μ΄λΈμ μ±λ₯μ΄ μ’μμ§λ€. |
hashCode
μΌλ° κ·μ½μ μ§ν€λ©° μ¬μ μνλ μΌμ μ΄λ ΅μ§λ μμ§λ§ μ‘°κΈ λ°λΆν μΌβ AutoValue νλ μμν¬λ₯Ό μ¬μ©νλ©΄ λ©μ§ equals
μ hashCode
λ₯Ό μλμΌλ‘ λ§λ€μ΄ μ€! μ κ·Ήνμ©νμ
βλͺ¨λ ꡬ체 ν΄λμ€μμ
Object
μtoString
μ μ¬μ μνμβ
toString
μ κ·μ½ : λͺ¨λ νμ ν΄λμ€μμ μ΄ λ©μλλ₯Ό μ¬μ μνλΌprintln
, printf
, λ¬Έμμ΄ μ°κ²° μ°μ°μ(+
), λλ²κ±°κ° κ°μ²΄λ₯Ό μΆλ ₯ν λβ κ°κ²°νλ©΄μ μ¬λμ΄ μ½κΈ° μ¬μ΄ ννμ μ μ΅ν μ 보λ₯Ό μ 곡νκΈ° μν΄ μ¬μ μνμ
/**
* μ΄ μ νλ²νΈμ λ¬Έμμ΄ ννμ λ°ννλ€.
* μ΄ λ¬Έμμ΄μ "XXX-YYY-ZZZZ" ννμ 12κΈμλ‘ κ΅¬μ±λλ€.
* XXXλ μ§μ μ½λ, YYYλ ν리ν½μ€, ZZZZλ κ°μ
μ λ²νΈλ€.
* κ°κ°μ λλ¬Έμλ 10μ§μ μ«μ νλλ₯Ό λνλΈλ€.
*
* μ νλ²νΈμ κ° λΆλΆμ κ°μ΄ λ무 μμμ μλ¦Ώμλ₯Ό μ±μΈ μ μλ€λ©΄,
* μμμλΆν° 0μΌλ‘ μ±μλκ°λ€. μ컨λ κ°μ
μ λ²νΈκ° 123μ΄λΌλ©΄
* μ νλ²νΈμ λ§μ§λ§ λ€ λ¬Έμλ "0123"μ΄ λλ€.
*/
@Override public String toString() {
return String.format("%03d-%03d-%04d",
areaCode, prefix, lineNum);
}
/**
* μ΄ μ½λ¬Όμ κ΄ν λλ΅μ μΈ μ€λͺ
μ λ°ννλ€.
* λ€μμ μ΄ μ€λͺ
μ μΌλ°μ μΈ ννμ΄λ,
* μμΈνμμ μ ν΄μ§μ§ μμμΌλ©° ν₯ν λ³κ²½λ μ μλ€.
*
* "[μ½λ¬Ό #9: μ ν=μ¬λ, λμ=ν
λ λΉμ , κ²λͺ¨μ΅=λ¨Ήλ¬Ό]"
*/
@Override public String toString() { ... }
toString
μ΄ λ°νν κ°μ ν¬ν¨λ μ 보λ₯Ό μ»μ΄μ¬ μ μλ APIλ₯Ό μ 곡νμ. (getter)toString
λ μμ±ν΄ μ€.toString
μλ μ ν©νμ§ μκ³ , μΌλ°μ μΈ μ 보λ€λ§ 보μ¬μ£Όλ κ²½μ°λΌλ©΄ μ ν©ν¨.β μν©μ λ°λΌ μ μ ν μ¬μ©νμ
β볡μ κΈ°λ₯μ μμ±μμ ν©ν°λ¦¬λ₯Ό μ¬μ©νλ κ² μ΅κ³ β
Cloneable
μΈν°νμ΄μ€Object
μ protected
λ©μλμΈ clone
μ λμ λ°©μμ κ²°μ Object
μ clone
λ©μλCloneable
μ ꡬνν ν΄λμ€μ μΈμ€ν΄μ€μμ clone
μ νΈμΆνλ©΄ κ·Έ κ°μ²΄μ νλλ€μ νλνλ 볡μ¬ν κ°μ²΄λ₯Ό λ°νCloneable
μ κ²½μ°μλ μμ ν΄λμ€μ μ μλ protected
λ©μλμ λμ λ°©μμ λ³κ²½νλ κ²Cloneable
μν€ν
μ²λ βκ°λ³ κ°μ²΄λ₯Ό μ°Έμ‘°νλ νλλ final
λ‘ μ μΈνλΌβλ μΌλ° μ©λ²κ³Ό μΆ©λνλ€.final
νμ μλ₯Ό μ κ±°ν΄μΌ ν μλ μμCloneable
μ ꡬνν ν΄λμ€λ clone
λ©μλλ₯Ό public
μΌλ‘ μ 곡νλ©°, μμ±μλ₯Ό νΈμΆνμ§ μκ³ λ κ°μ²΄λ₯Ό μμ±ν μ μκ² λ¨Object
μ clone
λ©μλλ λκΈ°νλ₯Ό μ κ²½ μ°μ§ μμλ€. κ·Έλ¬λ super.clone
νΈμΆ μΈμ λ€λ₯Έ ν μΌμ΄ μλλΌλ clone
μ μ¬μ μ ν λκΈ°νν΄μ€μΌ ν¨Cloneable
ꡬνpublic
, λ°ν νμ
μ ν΄λμ€ μμ μΌλ‘ λ³κ²½νμ¬ μ¬μ μsuper.clone
μ νΈμΆν ν νμν νλλ₯Ό μ λΆ μ μ ν μμ clone
λ©μλμ μΌλ° κ·μ½)μ κΈ°λμ§ μκ³ , μ μμ μΈ final
νλ μ©λ²κ³Όλ μΆ©λνμ§ μμΌλ©°, λΆνμν κ²μ¬ μμΈλ₯Ό λμ§μ§ μκ³ , νλ³νλ νμνμ§ μμ.// μμ κ³Ό κ°μ ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό μΈμλ‘ λ°λ μμ±μ
public Yum(Yum yum) { ... };
// λ³΅μ¬ μμ±μλ₯Ό λͺ¨λ°©ν μ μ ν©ν°λ¦¬
public static Yum newInstance(Yum yum) { ... };
β μλ‘μ΄ μΈν°νμ΄μ€λ ν΄λμ€λ₯Ό λ§λ€ λ, Cloneable
μ¬μ©μ μ λ μ§μνμ. λμ λ³΅μ¬ μμ±μμ λ³΅μ¬ ν©ν°λ¦¬λ₯Ό μ 곡νμ
βμμλ₯Ό κ³ λ €ν΄μΌ νλ κ° ν΄λμ€λ₯Ό μμ±νλ€λ©΄
Comparable
μ ꡬννμβ
public interface Comparable<T> {
int compareTo(T t);
}
Comparable
μΈν°νμ΄μ€λ₯Ό ꡬννλ€λ κ²μ κ·Έ ν΄λμ€μ μΈμ€ν΄μ€λ€μλ μμ°μ μΈ μμ(natural order)κ° μμμ λ» ν¨Comparable
μΈν°νμ΄μ€λ₯Ό ꡬνν κ°μ²΄ λ€μ λ°°μ΄μ μλ μμμ²λΌ μμ½κ² μ λ ¬ν μ μμ.Arrays.sort(a);
μ건 | μ€λͺ |
---|---|
λμΉμ± | Comparableμ ꡬνν ν΄λμ€λ λͺ¨λ x, yμ λν΄ sgn(x.compartTo(y)) == -sgn.(y.compareTo(x))μ¬μΌ νλ€(λ°λΌμ x.compareTo(y)λ y.compareTo(x)κ° μμΈλ₯Ό λμ§λμ νν΄ μμΈλ₯Ό λμ ΈμΌ νλ€). |
μΆμ΄μ± | Comparableμ ꡬνν ν΄λμ€λ μΆμ΄μ±μ 보μ₯ν΄μΌ νλ€. μ¦, (x.compareTo(y) > 0 && y.compareTo(z) > 0)μ΄λ©΄ x.compareTo(z) > 0μ΄λ€. |
λ°μ¬μ± | Comparableμ ꡬνν ν΄λμ€λ λͺ¨λ zμ λν΄ x.compareTo(y) == 0μ΄λ©΄ sgn(x.compareTo(z)) == sgn(y.compareTo(z))λ€. |
λμΉμ± ν μ€νΈμ κ²°κ³Όκ° equalsμ λμΌνκ° | μ΄λ² κΆκ³ κ° νμλ μλμ§λ§ κΌ μ§ν€λ κ² μ’λ€. (x.compareTo(y) == 0) == (x.equals(y))μ¬μΌ νλ€. Comparableμ ꡬννκ³ μ΄ κΆκ³ λ₯Ό μ§ν€μ§ μλ λͺ¨λ ν΄λμ€λ κ·Έ μ¬μ€μ λͺ
μν΄μΌ νλ€. λ€μκ³Ό κ°μ΄ λͺ
μνλ©΄ μ λΉν κ²μ΄λ€. βμ£Όμ: μ΄ ν΄λμ€μ μμλ equals λ©μλμ μΌκ΄λμ§ μλ€.β |
<
μ°μ°μλ >
λ₯Ό μ¬μ©νλ μ΄μ λ°©μμ κ±°μΆμ₯μ€λ½κ³ μ€λ₯λ₯Ό μ λ°νλ, λΉμΆμ²String.CASE_INSENSITIVE_ORDER
public final class CaseInsensitiveString implements Comparable<CaseInsensitiveString> {
// μλ°κ° μ 곡νλ λΉκ΅μλ₯Ό μ¬μ©ν΄ ν΄λμ€λ₯Ό λΉκ΅νλ€.
public int compareTo(CaseInsensitiveString cis) {
return String.CASE_INSENSITIVE_ORDER.compare(s, cis.s);
}
... // λλ¨Έμ§ μ½λ μλ΅
}
public final class PhoneNumber implements Cloneable, Comparable<PhoneNumber> {
//λΉκ΅μ μμ± λ©μλλ₯Ό νμ©ν λΉκ΅μ
private static final Comparator<PhoneNumber> COMPARATOR =
comparingInt((PhoneNumber pn) -> pn.areaCode)
.thenComparingInt(pn -> pn.prefix)
.thenComparingInt(pn -> pn.lineNum);
public int compareTo(PhoneNumber pn) {
return COMPARATOR.compare(this, pn);
}
... // λλ¨Έμ§ μ½λ μλ΅
}
compare
λ©μλ μ¬μ©// κΈ°λ³Έ νμ
νλκ° μ¬λΏμΌ λμ λΉκ΅μ
public int compareTo(PhoneNumber pn) {
int result = Short.compare(areaCode, pn.areaCode);
if (result == 0) {
result = Short.compare(prefix, pn.prefix);
if (result == 0)
result = Short.compare(lineNum, pn.lineNum);
}
return result;
}