πŸ‘¨πŸ»β€πŸ’» μ΄νŽ™ν‹°λΈŒ μžλ°” - λͺ¨λ“  객체의 곡톡 λ©”μ„œλ“œ

PeterΒ·2022λ…„ 3μ›” 19일
0
post-thumbnail

3μž₯ - λͺ¨λ“  객체의 곡톡 λ©”μ„œλ“œ


πŸ’‘ equalsλŠ” 일반 κ·œμ•½μ„ μ§€μΌœ μž¬μ •μ˜ν•˜λΌ

β€œκΌ­ ν•„μš”ν•œ κ²½μš°κ°€ μ•„λ‹ˆλ©΄ equalsλ₯Ό μž¬μ •μ˜ν•˜μ§€ λ§μžβ€

1. μž¬μ •μ˜λ₯Ό μ΅œλŒ€ν•œ ν”Όν•˜μž

  • equals λ©”μ„œλ“œλŠ” μž¬μ •μ˜ν•˜κΈ° μ‰¬μ›Œ λ³΄μ΄μ§€λ§Œ 곳곳에 함정이 도사리고 있음
  • 문제λ₯Ό νšŒν”Όν•˜λŠ” κ°€μž₯ μ‰¬μš΄ 길은 μ•„μ˜ˆ μž¬μ •μ˜ν•˜μ§€ μ•ŠλŠ” 것
  • λ§Žμ€ κ²½μš°μ— Object의 equalsκ°€ 비ꡐ적 μ •ν™•νžˆ μˆ˜ν–‰ν•΄ 쀌

2. equals μž¬μ •μ˜κ°€ ν•„μš”ν•œ 상황

  • 객체 식별성이 μ•„λ‹ˆλΌ 논리적 λ™μΉ˜μ„±μ„ 확인해야 ν•˜λŠ”λ°, μƒμœ„ 클래슀의 equalsκ°€ 논리적 λ™μΉ˜μ„±μ„ λΉ„κ΅ν•˜λ„λ‘ μž¬μ •μ˜λ˜μ§€ μ•Šμ•˜μ„ λ•Œ.
    • 객체 식별성 : 두 객체가 물리적으둜 같은가(μ£Όμ†Œ), == μ—°μ‚°μžλ‘œ 확인
    • 논리적 λ™μΉ˜μ„± : 값이 같은가?, equals λ©”μ„œλ“œλ‘œ 확인
  • 주둜 Integer, String처럼 값을 ν‘œν˜„ν•˜λŠ” ν΄λž˜μŠ€κ°€ 이에 ν•΄λ‹Ή 함.

3. equals 일반 κ·œμ•½

β†’ 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λ‹€.

4. AutoValue ν”„λ ˆμž„μ›Œν¬

  • equals 일반 κ·œμ•½μ„ μ² μ €νžˆ 지킀며 equalsλ₯Ό μž¬μ •μ˜ν•˜λŠ” 일은 μ§€λ£¨ν•˜κ³  쉽지 μ•Šλ‹€.
  • κ΅¬κΈ€μ˜ AutoValue ν”„λ ˆμž„μ›Œν¬λŠ” 이 μž‘μ—…μ„ λŒ€μ‹ ν•΄ 쀌.
  • ν΄λž˜μŠ€μ— μ–΄λ…Έν…Œμ΄μ…˜ ν•˜λ‚˜λ§Œ μΆ”κ°€ν•˜λ©΄ equals λ©”μ„œλ“œλ₯Ό μ•Œμ•„μ„œ μž‘μ„±ν•΄μ£Όλ©°, μš°λ¦¬κ°€ μž‘μ„±ν•˜λŠ” 것과 근본적으둜 λ˜‘κ°™μ€ μ½”λ“œλ₯Ό 생성해 쀌.

β†’ λΆ€μ£Όμ˜ν•œ μ‹€μˆ˜λ₯Ό λ°©μ§€ν•˜κΈ° μœ„ν•΄ AutoValue ν”„λ ˆμž„μ›Œν¬λ₯Ό 적극 ν™œμš©ν•˜μž.



πŸ’‘ equalsλ₯Ό μž¬μ •μ˜ν•˜λ €κ±°λ“  hashCode도 μž¬μ •μ˜ν•˜λΌ

β€œequalsλ₯Ό μž¬μ •μ˜ν•œ 클래슀 λͺ¨λ‘μ—μ„œ hashCode도 μž¬μ •μ˜ν•΄μ•Ό ν•œλ‹€β€

1. hashCode μž¬μ •μ˜ ν•„μš”μ„±

  • equalsλ₯Ό μž¬μ •μ˜ν•œ ν΄λž˜μŠ€μ—μ„œ hashCodeλ₯Ό μž¬μ •μ˜ν•˜μ§€ μ•ŠμœΌλ©΄, hashCode 일반 κ·œμ•½μ„ μ–΄κΈ°κ²Œ λ˜μ–΄ ν•΄λ‹Ή 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό HashMapμ΄λ‚˜ HashSet 같은 μ»¬λ ‰μ…˜μ˜ μ›μ†Œλ‘œ μ‚¬μš©ν•  λ•Œ λ¬Έμ œκ°€ 됨
  • hashCodeλ₯Ό μž¬μ •μ˜ ν•  μ‹œ, λ°˜λ“œμ‹œ μ•„λž˜ 일반 κ·œμ•½μ„ 따라야 함
μ„€λͺ…
1equals 비ꡐ에 μ‚¬μš©λ˜λŠ” 정보가 λ³€κ²½λ˜μ§€ μ•Šμ•˜λ‹€λ©΄, μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ μ‹€ν–‰λ˜λŠ” λ™μ•ˆ κ·Έ 객체의 hashCode λ©”μ„œλ“œλŠ” λͺ‡ λ²ˆμ„ ν˜ΈμΆœν•΄λ„ μΌκ΄€λ˜κ²Œ 항상 같은 값을 λ°˜ν™˜ν•΄μ•Ό ν•œλ‹€.
단, μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ λ‹€μ‹œ μ‹€ν–‰ν•œλ‹€λ©΄ 이 값이 달라져도 상관없닀.
2equals(Object)κ°€ 두 객체λ₯Ό κ°™λ‹€κ³  νŒλ‹¨ν–ˆλ‹€λ©΄, 두 객체의 hashCodeλŠ” λ˜‘κ°™μ€ 값을 λ°˜ν™˜ν•΄μ•Ό ν•œλ‹€.
3equals(Object)κ°€ 두 객체λ₯Ό λ‹€λ₯΄λ‹€κ³  νŒλ‹¨ν–ˆλ”λΌλ„, 두 객체의 hashCodeκ°€ μ„œλ‘œ λ‹€λ₯Έ 값을 λ°˜ν™˜ν•  ν•„μš”λŠ” μ—†λ‹€. 단, λ‹€λ₯Έ 객체에 λŒ€ν•΄μ„œλŠ” λ‹€λ₯Έ 값을 λ°˜ν™˜ν•΄μ•Ό ν•΄μ‹œν…Œμ΄λΈ”μ˜ μ„±λŠ₯이 쒋아진닀.

2. AutoValue ν”„λ ˆμž„μ›Œν¬

  • hashCode 일반 κ·œμ•½μ„ 지킀며 μž¬μ •μ˜ν•˜λŠ” 일은 μ–΄λ ΅μ§€λŠ” μ•Šμ§€λ§Œ 쑰금 λ”°λΆ„ν•œ 일

β†’ AutoValue ν”„λ ˆμž„μ›Œν¬λ₯Ό μ‚¬μš©ν•˜λ©΄ 멋진 equals와 hashCodeλ₯Ό μžλ™μœΌλ‘œ λ§Œλ“€μ–΄ 쀌! μ κ·Ήν™œμš©ν•˜μž



πŸ’‘ toString을 항상 μž¬μ •μ˜ν•˜λΌ

β€œλͺ¨λ“  ꡬ체 ν΄λž˜μŠ€μ—μ„œ Object의 toString을 μž¬μ •μ˜ν•˜μžβ€

1. Object의 κΈ°λ³Έ toString λ©”μ„œλ“œ

  • λ‹¨μˆœνžˆ ν΄λž˜μŠ€μ΄λ¦„@16μ§„μˆ˜λ‘œν‘œμ‹œν•œ_ν•΄μ‹œμ½”λ“œ λ°˜ν™˜(μœ μ΅ν•˜μ§€ μ•Šμ€ 정보)
  • toString의 κ·œμ•½ : λͺ¨λ“  ν•˜μœ„ ν΄λž˜μŠ€μ—μ„œ 이 λ©”μ„œλ“œλ₯Ό μž¬μ •μ˜ν•˜λΌ
  • μš°λ¦¬κ°€ 직접 ν˜ΈμΆœν•˜μ§€ μ•Šμ•„λ„, λ‹€λ₯Έ μ–΄λ”˜κ°€μ—μ„œ 쓰일 수 있기 λ•Œλ¬Έ
    • ex) println, printf, λ¬Έμžμ—΄ μ—°κ²° μ—°μ‚°μž(+), 디버거가 객체λ₯Ό 좜λ ₯ν•  λ•Œ

β†’ κ°„κ²°ν•˜λ©΄μ„œ μ‚¬λžŒμ΄ 읽기 μ‰¬μš΄ ν˜•νƒœμ˜ μœ μ΅ν•œ 정보λ₯Ό μ œκ³΅ν•˜κΈ° μœ„ν•΄ μž¬μ •μ˜ν•˜μž


2. μž¬μ •μ˜ 방법

  • 객체가 가진 μ£Όμš” 정보 λͺ¨λ‘λ₯Ό λ°˜ν™˜ν•˜λŠ” 게 μ’‹μŒ
  • 포맷을 λͺ…μ‹œν•˜λ“  μ•„λ‹ˆλ“  μ˜λ„λ₯Ό λͺ…ν™•νžˆ 해야함.
  • 포맷을 λͺ…μ‹œν•œ 경우
    • μž₯점 : ν‘œμ€€μ , λͺ…ν™•, μ‚¬λžŒμ΄ 읽을 수 있음
    • 단점 : 평생 κ·Έ 포맷에 μ–½λ§€μž„
    • 포맷을 λͺ…μ‹œν•˜κΈ°λ‘œ ν–ˆλ‹€λ©΄ λͺ…μ‹œν•œ 포맷에 λ§žλŠ” λ¬Έμžμ—΄κ³Ό 객체λ₯Ό μƒν˜Έ μ „ν™˜ν•  수 μžˆλŠ” 정적 νŒ©ν„°λ¦¬λ‚˜ μƒμ„±μžλ₯Ό ν•¨κ»˜ μ œκ³΅ν•΄μ£Όλ©΄ μ’‹μŒ
		/**
     * 이 μ „ν™”λ²ˆν˜Έμ˜ λ¬Έμžμ—΄ ν‘œν˜„μ„ λ°˜ν™˜ν•œλ‹€.
     * 이 λ¬Έμžμ—΄μ€ "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)

3. AutoValue ν”„λ ˆμž„μ›Œν¬

  • AutoValue ν”„λ ˆμž„μ›Œν¬λŠ” toString도 생성해 쀌.
  • AutoValue ν”„λ ˆμž„μ›Œν¬λŠ” 각 ν•„λ“œμ˜ λ‚΄μš©μ„ λ©‹μ§€κ²Œ λ‚˜νƒ€λ‚΄ μ£ΌκΈ°λŠ” ν•˜μ§€λ§Œ 클래슀의 β€˜μ˜λ―Έβ€™κΉŒμ§€ νŒŒμ•…ν•˜μ§€λŠ” λͺ» 함
  • 예λ₯Ό λ“€μ–΄ μ „ν™”λ²ˆν˜Έ 같은 포맷(XXX-YYY-ZZZZ)에 따라 λ°˜ν™˜ν•΄μ•Όν•˜λŠ” toStringμ—λŠ” μ ν•©ν•˜μ§€ μ•Šκ³ , 일반적인 μ •λ³΄λ“€λ§Œ λ³΄μ—¬μ£ΌλŠ” 경우라면 적합함.

β†’ 상황에 따라 적절히 μ‚¬μš©ν•˜μž



πŸ’‘ clone μž¬μ •μ˜λŠ” μ£Όμ˜ν•΄μ„œ μ§„ν–‰ν•˜λΌ

β€œλ³΅μ œ κΈ°λŠ₯은 μƒμ„±μžμ™€ νŒ©ν„°λ¦¬λ₯Ό μ‚¬μš©ν•˜λŠ” 게 μ΅œκ³ β€

1. Cloneable μΈν„°νŽ˜μ΄μŠ€μ™€ clone λ©”μ„œλ“œ

  • Cloneable μΈν„°νŽ˜μ΄μŠ€
    • λ³΅μ œν•΄λ„ λ˜λŠ” ν΄λž˜μŠ€μž„μ„ λͺ…μ‹œν•˜λŠ” μš©λ„μ˜ 믹슀인 μΈν„°νŽ˜μ΄μŠ€(mixin interface)
    • Object의 protected λ©”μ„œλ“œμΈ clone의 λ™μž‘ 방식을 κ²°μ •
  • Object의 clone λ©”μ„œλ“œ
    • Cloneable을 κ΅¬ν˜„ν•œ 클래슀의 μΈμŠ€ν„΄μŠ€μ—μ„œ clone을 ν˜ΈμΆœν•˜λ©΄ κ·Έ 객체의 ν•„λ“œλ“€μ„ ν•˜λ‚˜ν•˜λ‚˜ λ³΅μ‚¬ν•œ 객체λ₯Ό λ°˜ν™˜

2. Cloneable & clone의 문제점

  • μΈν„°νŽ˜μ΄μŠ€ κ΅¬ν˜„λ₯Ό κ΅¬ν˜„ν•œλ‹€λŠ” 것은 일반적으둜 ν•΄λ‹Ή ν΄λž˜μŠ€κ°€ κ·Έ μΈν„°νŽ˜μ΄μŠ€μ—μ„œ μ •μ˜ν•œ κΈ°λŠ₯을 μ œκ³΅ν•œλ‹€κ³  μ„ μ–Έν•˜λŠ” ν–‰μœ„
    • but, Cloneable의 κ²½μš°μ—λŠ” μƒμœ„ ν΄λž˜μŠ€μ— μ •μ˜λœ protected λ©”μ„œλ“œμ˜ λ™μž‘ 방식을 λ³€κ²½ν•˜λŠ” 것
  • Cloneable μ•„ν‚€ν…μ²˜λŠ” β€˜κ°€λ³€ 객체λ₯Ό μ°Έμ‘°ν•˜λŠ” ν•„λ“œλŠ” final둜 μ„ μ–Έν•˜λΌβ€™λŠ” 일반 μš©λ²•κ³Ό μΆ©λŒν•œλ‹€.
    • λ³΅μ œν•  수 μžˆλŠ” 클래슀λ₯Ό λ§Œλ“€κΈ° μœ„ν•΄ 일뢀 ν•„λ“œμ—μ„œ final ν•œμ •μžλ₯Ό μ œκ±°ν•΄μ•Ό ν•  μˆ˜λ„ 있음
  • Cloneable을 κ΅¬ν˜„ν•œ ν΄λž˜μŠ€λŠ” clone λ©”μ„œλ“œλ₯Ό public으둜 μ œκ³΅ν•˜λ©°, μƒμ„±μžλ₯Ό ν˜ΈμΆœν•˜μ§€ μ•Šκ³ λ„ 객체λ₯Ό 생성할 수 있게 됨
  • Object의 clone λ©”μ„œλ“œλŠ” 동기화λ₯Ό μ‹ κ²½ 쓰지 μ•Šμ•˜λ‹€. κ·ΈλŸ¬λ‹ˆ super.clone호좜 외에 λ‹€λ₯Έ ν•  일이 없더라도 clone을 μž¬μ •μ˜ ν›„ λ™κΈ°ν™”ν•΄μ€˜μ•Ό 함

3. clone μž¬μ •μ˜ 방법

  1. Cloneable κ΅¬ν˜„
  2. μ ‘κ·Όμ œν•œμžλŠ” public, λ°˜ν™˜ νƒ€μž…μ€ 클래슀 μžμ‹ μœΌλ‘œ λ³€κ²½ν•˜μ—¬ μž¬μ •μ˜
  3. λ©”μ„œλ“œ λ‚΄λΆ€μ—μ„œλŠ” κ°€μž₯ λ¨Όμ € super.clone을 ν˜ΈμΆœν•œ ν›„ ν•„μš”ν•œ ν•„λ“œλ₯Ό μ „λΆ€ 적절히 μˆ˜μ •

4. 볡사 μƒμ„±μžμ™€ 볡사 νŒ©ν„°λ¦¬

  • 볡사 μƒμ„±μžμ™€ 볡사 νŒ©ν„°λ¦¬λŠ” μ–Έμ–΄ λͺ¨μˆœμ μ΄κ³  μœ„ν—˜μ²œλ§Œν•œ 객체 생성 λ©”μ»€λ‹ˆμ¦˜(μƒμ„±μžλ₯Ό 쓰지 μ•ŠλŠ” 방식)을 μ‚¬μš©ν•˜μ§€ μ•ŠμŒ
  • μ—‰μ„±ν•˜κ²Œ λ¬Έμ„œν™”λœ κ·œμ•½(clone λ©”μ„œλ“œμ˜ 일반 κ·œμ•½)에 κΈ°λŒ€μ§€ μ•Šκ³ , 정상적인 finalν•„λ“œ μš©λ²•κ³Όλ„ μΆ©λŒν•˜μ§€ μ•ŠμœΌλ©°, λΆˆν•„μš”ν•œ 검사 μ˜ˆμ™Έλ₯Ό λ˜μ§€μ§€ μ•Šκ³ , ν˜•λ³€ν™˜λ„ ν•„μš”ν•˜μ§€ μ•ŠμŒ.
  • 볡사 μƒμ„±μž μ˜ˆμ‹œ
// μžμ‹ κ³Ό 같은 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό 인수둜 λ°›λŠ” μƒμ„±μž
public Yum(Yum yum) { ... };
  • 볡사 νŒ©ν„°λ¦¬ μ˜ˆμ‹œ
// 볡사 μƒμ„±μžλ₯Ό λͺ¨λ°©ν•œ 정적 νŒ©ν„°λ¦¬
public static Yum newInstance(Yum yum) { ... };

β†’ μƒˆλ‘œμš΄ μΈν„°νŽ˜μ΄μŠ€λ‚˜ 클래슀λ₯Ό λ§Œλ“€ λ•Œ, Cloneable μ‚¬μš©μ„ μ ˆλŒ€ μ§€μ–‘ν•˜μž. λŒ€μ‹  볡사 μƒμ„±μžμ™€ 볡사 νŒ©ν„°λ¦¬λ₯Ό μ œκ³΅ν•˜μž



πŸ’‘ Comparable을 κ΅¬ν˜„ν• μ§€ κ³ λ €ν•˜λΌ

β€œμˆœμ„œλ₯Ό κ³ λ €ν•΄μ•Ό ν•˜λŠ” κ°’ 클래슀λ₯Ό μž‘μ„±ν•œλ‹€λ©΄ Comparable을 κ΅¬ν˜„ν•˜μžβ€

1. Comparable μΈν„°νŽ˜μ΄μŠ€

public interface Comparable<T> {
		int compareTo(T t);
}
  • Comparable μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν–ˆλ‹€λŠ” 것은 κ·Έ 클래슀의 μΈμŠ€ν„΄μŠ€λ“€μ—λŠ” μžμ—°μ μΈ μˆœμ„œ(natural order)κ°€ μžˆμŒμ„ 뜻 함
  • Comparable μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ 객체 λ“€μ˜ 배열은 μ•„λž˜ μ˜ˆμ‹œμ²˜λŸΌ μ†μ‰½κ²Œ μ •λ ¬ν•  수 있음.
Arrays.sort(a);
  • 검색, 극단값 계산, μžλ™ μ •λ ¬λ˜λŠ” μ»¬λ ‰μ…˜ 관리도 μ—­μ‹œ μ‰½κ²Œ ν•  수 있음.

2. compareTo λ©”μ„œλ“œ 일반 κ·œμ•½

μš”κ±΄μ„€λͺ…
λŒ€μΉ­μ„±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 λ©”μ„œλ“œμ™€ μΌκ΄€λ˜μ§€ μ•Šλ‹€.”

3. λΉ„κ΅μž

  • compareTo λ©”μ„œλ“œμ—μ„œ 관계 μ—°μ‚°μž <μ—°μ‚°μžλ‚˜ >λ₯Ό μ‚¬μš©ν•˜λŠ” 이전 방식은 κ±°μΆ”μž₯슀럽고 였λ₯˜λ₯Ό μœ λ°œν•˜λ‹ˆ, λΉ„μΆ”μ²œ
  • 객체 μ°Έμ‘°λ₯Ό 비ꡐ할 λ•Œ
  1. μžλ°”κ°€ μ œκ³΅ν•˜λŠ” λΉ„κ΅μž μ‚¬μš©, ex. 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);
    }
		... // λ‚˜λ¨Έμ§€ μ½”λ“œ μƒλž΅
}
  1. λΉ„κ΅μž 생성 λ©”μ„œλ“œ μ‚¬μš©
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;
}
profile
https://dev-peter.online/

0개의 λŒ“κΈ€