Skip to content

Latest commit

ย 

History

History
1528 lines (1207 loc) ยท 77.1 KB

File metadata and controls

1528 lines (1207 loc) ยท 77.1 KB

๐Ÿ“ƒ ๋ชฉ์ฐจ



๐Ÿ“Œ Item01. ์ƒ์„ฑ์ž ๋Œ€์‹  ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ๊ณ ๋ คํ•˜๋ผ.


โ˜๏ธ ๏ธ์žฅ์  1. ์ด๋ฆ„์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.

:: ์ƒ์„ฑ์ž์— ๋„˜๊ธฐ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์ƒ์„ฑ์ž ์ž์ฒด ๋งŒ์œผ๋กœ๋Š” ๋ฐ˜ํ™˜๋  ๊ฐ์ฒด์— ๋Œ€ํ•œ ํŠน์„ฑ์„ ์ œ๋Œ€๋กœ ์„ค๋ช…ํ•  ์ˆ˜ ์—†๋‹ค.    
ํ•˜์ง€๋งŒ ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์†Œ๋“œ์˜ ์ด๋ฆ„๋งŒ ์ž˜ ์ง“๋Š”๋‹ค๋ฉด ๊ฐ์ฒด์˜ ํŠน์„ฑ์„ ์ž˜ ๋ฌ˜์‚ฌํ•  ์ˆ˜ ์žˆ๋‹ค.
public static People student(String name, String number){
        People people =new People(name);
        people.number = number;
        return people;
    }

ex) BigInteger.probablePrime -> ๊ฐ’์ด ์†Œ์ˆ˜์ธ BIgInteger๋ฅผ ๋ฐ˜ํ™˜.

โ˜๏ธ ์žฅ์  2. ํ˜ธ์ถœ๋  ๋•Œ๋งˆ๋‹ค ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•˜์ง€๋Š” ์•Š์•„๋„ ๋œ๋‹ค.

:: ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด ๋†“์€ ์ธ์Šคํ„ด์Šค๋‚˜ ์ƒˆ๋กœ ์ƒ์„ฑํ•œ ์ธ์Šคํ„ด์Šค๋ฅผ ์บ์‹ฑํ•˜์—ฌ ์žฌํ™œ์šฉ ํ•˜๋Š”์‹์œผ๋กœ ๋ถˆํ•„์š”ํ•œ ๊ฐ์ฒด ์ƒ์„ฑ์„ ํ”ผํ•  ์ˆ˜ ์žˆ๋‹ค.    
:: ๋ฐ˜๋ณต๋˜๋Š” ์š”์ฒญ์— ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์‹์œผ๋กœ ์ธ์Šคํ„ด์Šค๋ฅด ํ†ต์ œ ํ•  ์ˆ˜ ์žˆ๋‹ค -> ์‹ฑ๊ธ€ํ„ด, ์ธ์Šคํ„ด์Šคํ™” ๋ถˆ๊ฐ€๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.
:: ๋ถˆ๋ณ€ ๊ฐ’ ํด๋ž˜์Šค์—์„œ ๋™์น˜์ธ ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•˜๋‚˜์ž„์„ ๋ณด์žฅ. ์ธ์Šคํ„ด์Šค ํ†ต์ œ๋Š” ํ”Œ๋ผ์ด์›จ์ดํŠธ ํŒจํ„ด์˜ ๊ทผ๊ฐ„์ด ๋œ๋‹ค.
private static final People staticPeople = new People("kim");

public static People getStaticPeople(){
        return staticPeople;
}

โ˜๏ธ ์žฅ์ 3. ๋ฐ˜ํ™˜ ํƒ€์ž…์˜ ํ•˜์œ„ ํƒ€์ž… ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™œํ•  ์ˆ˜ ์žˆ๋Š” ๋Šฅ๋ ฅ์ด ์žˆ๋‹ค.

:: ์œ ์—ฐ์„ฑ์ด ์ƒ๊ธด๋‹ค. API๋ฅผ ๋งŒ๋“ค ๋•Œ ์ด๋Ÿฌํ•œ ์œ ์—ฐ์„ฑ์„ ์‘์šฉํ•˜๋ฉด ๊ตฌํ˜„ ํด๋ž˜์Šค๋ฅผ ๊ณต๊ฐœํ•˜์ง€ ์•Š๊ณ ๋„ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์–ด API๋ฅผ ์ž‘๊ฒŒ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.
public interface PeopleInterface {
    public static People getPeople(){
        return new People();
    }
}

:: java 8๋ถ€ํ„ฐ interface์—์„œ์˜ public static method ์„ ์–ธ์„ , java 9๋ถ€ํ„ฐ private static method์„ ์–ธ์„ ํ—ˆ์šฉํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ •์  ํ•„๋“œ์™€ ์ •์  ๋ฉค๋ฒ„ ํด๋ž˜์Šค๋Š” public์ด์–ด์•ผ ํ•œ๋‹ค.
:: ๊ตฌํ˜„ ํด๋ž˜์Šค๋ฅผ ์ˆจ๊ธฐ๋Š” ๊ฒƒ ๊ฐœ๋…์  ๋ฌด๊ฒŒ ์ฆ‰, ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ด๋ฅผ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•œ ๊ฐœ๋…์˜ ์ˆ˜์™€ ๋‚œ์ด๋„๋ฅผ ๋‚ฎ์ถฐ์ค€๋‹ค.

โ˜๏ธ ์žฅ์  4. ์ž…๋ ฅ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋”ฐ๋ผ ๋งค๋ฒˆ ๋‹ค๋ฅธ ํด๋ž˜์Šค์˜ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

:: ๋ฐ˜ํ™˜ ํƒ€์ž…์˜ ํ•˜์œ„ ํƒ€์ž…์ด๊ธฐ๋งŒ ํ•˜๋ฉด ์–ด๋–ค ํด๋ž˜์Šค ๊ฐ์ฒด๋“  ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค.    
:: Man ๊ณผ Girl class๊ฐ€ People class ๋ฅผ ์ƒ์†ํ• ๋•Œ. ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐ˜ํ™˜์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
public static People isMan(Boolean flag){
        return flag ? new Man(): new Girl();
    }

:: ex) Enumset ํด๋ž˜์Šค์—์„œ๋Š” ์›์†Œ๊ฐ€ 64๊ฐœ ์ดํ•˜๋ฉด RegularEnumSet์„ ,๊ทธ๋ณด๋‹ค ๋งŽ๋‹ค๋ฉด JumboEnumSet์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

โ˜๏ธ ์žฅ์  5. ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์‹œ์ ์—๋Š” ๋ฐ˜ํ™˜ํ•  ๊ฐ์ฒด์˜ ํด๋ž˜์Šค๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

:: ์ด๋Ÿฌํ•œ ์œ ์—ฐ์„ฑ์€ ์„œ๋น„์Šค ์ œ๊ณต์ž ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋งŒ๋“œ๋Š” ๊ทผ๊ฐ„์ด๋‹ค.    
:: ์„œ๋น„์Šค ์ œ๊ณต์ž ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ๊ตฌํ˜„์ฒด์˜ ๋™์ž‘์„ ์ •์˜ํ•˜๋Š” ์„œ๋น„์Šค ์ธํ„ฐํŽ˜์ด์Šค, ๊ตฌํ˜„์ฒด๋ฅผ ๋“ฑ๋กํ• ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์ œ๊ณต์ž ๋“ฑ๋ก API, ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋น„์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์–ป์„ ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์„œ๋น„์Šค ์ ‘๊ทผ API๊ฐ€ ์žˆ๋‹ค.   

ex) JDBC์—์„œ๋Š” Connection์ด ์„œ๋น„์Šค ์ธํ„ฐํŽ˜์ด์Šค, registerDirver๊ฐ€ ์ œ๊ณต์ž ๋“ฑ๋ก API, getConnection์ด ์„œ๋น„์Šค ์ ‘๊ทผ API์—ญํ• ์„ ํ•œ๋‹ค.

public static People getPeople(){
        People people = new People();
        // TODO people = ํ’€ ํŒจํ‚ค์ง€ ๊ฒฝ๋กœ๋กœ๋ถ€ํ„ฐ ํ˜„ ํด๋ž˜์Šค์˜ ํ•˜์œ„ํด๋ž˜์Šค๋ฅผ ์ฝ์–ด์˜ด.
        return people;
    }

:: ํด๋ผ์ด์–ธํŠธ๋Š” ์„œ๋น„์Šค ์ ‘๊ทผ API๋ฅผ ์‚ฌ์šฉํ•  ๋–„ ์›ํ•˜๋Š” ๊ตฌํ˜„์ฒด์˜ ์กฐ๊ฑด์„ ๋ช…์‹œํ•  ์ˆ˜ ์žˆ๋‹ค.
์˜ˆ๋ฅผ๋“ค์–ด JDBCํ”„๋ ˆ์ž„ ์›Œํฌ์—์„œ DriverManager.getConnection์„ ์ˆ˜ํ–‰ํ•  ๋•Œ Mysql ๋“ฑ ๋‹ค์–‘ํ•œ driver๋งˆ๋‹ค ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค.

๐Ÿ‘Ž ๋‹จ์  1. ์ƒ์†์„ ํ•˜๋ ค๋ฉด public์ด๋‚˜ protected ์ƒ์„ฑ์ž ์—†์ด, ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์†Œ๋“œ๋งŒ ์ œ๊ณตํ•˜๋ฉด ํ•˜์œ„ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์—†๋‹ค.

:: ๊ทธ๋Ÿฌ๋‚˜ ์ƒ์†๋ณด๋‹ค ์ปดํฌ์ง€์…˜(item18)์„ ์‚ฌ์šฉํ•˜๋„๋ก ์œ ๋„ํ•˜๊ณ  ๋ถˆ๋ณ€ ํƒ€์ž…(item17)์œผ๋กœ ๋งŒ๋“ค๋ ค๋ฉด ์ด ์ œ์•ฝ์„ ์ง€์ผœํ•˜ ํ•œ๋‹ค๋Š” ์ ์—์„œ ๋‹จ์ ์ด๋ผ๊ณ  ๋ณด๊ธฐ์—” ์–ด๋ ต๋‹ค.

๐Ÿ‘Ž ๋‹จ์  2. ์ •์  ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ฐพ๊ธฐ ์–ด๋ ต๋‹ค.

:: ์ƒ์„ฑ์ž์ฒ˜๋Ÿผ API์„ค๋ช…์— ๋ช…ํ™•์ด ๋“œ๋Ÿฌ๋‚˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋ฌธ์„œ์˜ ์ƒ๋‹จ์— ์ž˜ ์จ๋†“๊ฑฐ๋‚˜ ๋ฉ”์„œ๋“œ์˜ ์ด๋ฆ„์„ ๋„๋ฆฌ ์•Œ๋ ค์ง„ ๊ทœ์•ฝ์— ๋”ฐ๋ผ ์ง€์–ด ๋ฌธ์ œ๋ฅผ ์™„ํ™”ํ•ด์ค˜์•ผ ํ•œ๋‹ค.
  • from : ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ๋ฐ›์•„ ํ•ด๋‹น ํƒ€์ž…์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ˜•๋ณ€ํ™˜ ๋ฉ”์†Œ๋“œ
  • of : ์—ฌ๋Ÿฌ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›์•„ ์ ํ•ฉํ•œ ํƒ€์ž…์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜.
  • instance, getInstance : ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ช…์‹œํ•œ ์ธ์Šคํ„ด์Šค ๋ฐ˜ํ™˜, ๊ฐ™์€ ์ธ์Šคํ„ด์Šค์ž„์„ ๋ณด์žฅํ•˜์ง„ ์•Š์Œ.
  • creat, newInstance : ๋งค๋ฒˆ ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค ์ƒ์ƒ ๋ณด์žฅ.
  • getType : ์ƒ์„ฑํ•  ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ํด๋ž˜์Šค์— ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜. Type์€ ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•  ๊ฐ์ฒด์˜ ํƒ€์ž….



๐Ÿ“Œ Item02. ์ƒ์„ฑ์ž์— ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋งŽ๋‹ค๋ฉด ๋นŒ๋”๋ฅผ ๊ณ ๋ คํ•˜๋ผ.


โœ๏ธ ์ •์  ํŒฉํ„ฐ๋ฆฌ์™€ ์ƒ์„ฑ์ž์˜ ์ œ์•ฝ

์„ ํƒ์  ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋งŽ์„ ๋•Œ ์ ์ ˆํžˆ ๋Œ€์‘ํ•˜๊ธฐ ์–ด๋ ต๋‹ค.

โ˜๏ธ ํ•ด๊ฒฐ1: ์ ์ธต์  ์ƒ์„ฑ์ž


:: ์ ์ธต์  ์ƒ์„ฑ์ž๋ฅผ ์ด์šฉํ•˜์—ฌ ์„ ํƒ์  ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›๋Š” ์ƒ์„ฑ์ž๋ฅผ ์ ์  ๋Š˜๋ ค๊ฐ€๋ฉฐ ์ƒ์„ฑ์ž๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ , ์›ํ•˜๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋ชจ๋‘ ํฌํ•จ๋œ ์ƒ์„ฑ์ž์ค‘ ๊ฐ€์žฅ ์ž‘์€๊ฒƒ์„ ๊ณจ๋ผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋œ๋‹ค.
ex)A,B,C,D์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์กด์žฌํ•  ๋•Œ A,B๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ, A,C๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ, A,D๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋“ฑ...

- ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋งŽ์•„์ง€๋ฉด ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์–ด๋ ค์›Œ์ง€๊ณ , ์ฝ๊ธฐ๋„ ํž˜๋“ค์–ด์ง„๋‹ค. ๊ฐ’์˜ ์˜๋ฏธ์™€, ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๊ฐฏ์ˆ˜์— ์ฃผ์˜๋ฅผ ๊ธฐ์šธ์—ฌ์•ผ ํ•˜๋ฉฐ,
๋งค๊ฐœ ๋ณ€์ˆ˜ ๊ฐ’์„ ์ž˜๋ชป ๋„˜๊ฒจ์ฃผ์–ด๋„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค. 

โ˜๏ธ ํ•ด๊ฒฐ2: JavaBeans Pattern


:: ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ์—†๋Š” ์ƒ์„ฑ์ž๋ฅผ ๋งŒ๋“ค๊ณ , Setter ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์›ํ•˜๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๊ฐ’์„ ์„ค์ •ํ•œ๋‹ค.

- ์ฝ”๋“œ๋Š” ๊ธธ์–ด์ง€์ง€๋งŒ ์ธ์Šคํ„ด์Šค์˜ ์ƒ์„ฑ์ด ์‰ฝ๊ณ , ๋” ์ฝ๊ธฐ ์‰ฌ์šด ์ฝ”๋“œ๊ฐ€ ๋งŒ๋“ค์–ด์ง„๋‹ค.
- ํ•˜์ง€๋งŒ ๊ฐ์ฒด ํ•˜๋‚˜๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ๋งŽ์€ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์•ผํ•˜๊ณ , ๊ฐ์ฒด๊ฐ€ ์™„์ „ํžˆ ์ƒ์„ฑ๋˜๊ธฐ ์ „๊นŒ์ง€ ์ผ๊ด€์„ฑ์ด ๋ฌด๋„ˆ์ง„ ์ƒํƒœ์— ๋†“์ธ๋‹ค.(์ค‘๊ฐ„์— ํ˜ธ์ถœ๋  ๊ฒฝ์šฐ ์ž˜๋ชป ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Œ.)
- Setter๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ถˆ๋ณ€ ํด๋ž˜์Šค๋กœ ๋งŒ๋“ค ์ˆ˜ ์—†๊ณ , ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ณ€๊ฒฝ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์“ฐ๋ ˆ๋“œ ์•ˆ์ •์„ฑ์„ ์–ป์œผ๋ ค๋ฉด ์ถ”๊ฐ€ ์ž‘์—…์ด ํ•„์š”ํ•˜๋‹ค(lock)

โ˜๏ธ ํ•ด๊ฒฐ3 : ๋นŒ๋” ํŒจํ„ด


:: ์ ์ธต์  ์ƒ์„ฑ์ž ํŒจํ„ด์˜ ์•ˆ์ •์„ฑ๊ณผ ์ž๋ฐ” ๋นˆ์ฆˆ ํŒจํ„ด์˜ ๊ฐ€๋…์„ฑ์„ ๊ฒธ๋น„.
:: ํ•„์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋งŒ์œผ๋กœ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•ด ๋นŒ๋” ๊ฐ์ฒด๋ฅผ ์–ป๊ณ , ๋นŒ๋” ๊ฐ์ฒด๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์„ธํ„ฐ ๋ฉ”์„œ๋“œ๋“ค๋กœ ์„ ํƒ ๋งค๊ฐœ๋ณ€์ˆ˜๋“ค์˜ ๊ฐ’์„ ์„ค์ •ํ•œ๋‹ค.
๋งˆ์ง€๋ง‰์œผ๋กœ build()๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํ•„์š”ํ•œ ๊ฐ์ฒด๋ฅผ ์–ป๋Š”๋‹ค. ๋นŒ๋”๋Š” ์ƒ์„ฑํ•  ํด๋ž˜์Šค ์•ˆ์— ์ •์  ๋ฉค๋ฒ„ํด๋ž˜์Šค๋กœ ๋งŒ๋“ค์–ด ๋‘๋Š”๊ฒƒ์ด ์ผ๋ฐ˜์ ์ด๋‹ค.

public class NutritionFacts {
    private final int servings;
    private final int servingSize;
    private final int sodium;
    private final int fat;
    private final int carbohydrate;

    public static class Builder {
        private final int servings;
        private final int servingSize;

        private int sodium = 0;
        private int fat = 0;
        private int carbohydrate = 0;

        public Builder(int servings, int servingSize) {
            this.servings = servings;
            this.servingSize = servingSize;
        }

        public Builder sodium(int val) {
            sodium = val;
            return this;
        }

        public Builder fat(int val) {
            sodium = val;
            return this;
        }

        public Builder carbohydrate(int val) {
            sodium = val;
            return this;
        }

        public NutritionFacts build() {
            return new NutritionFacts(this);
        }

    }

    public NutritionFacts(Builder builder) {
        servingSize = builder.servingSize;
        servings = builder.servings;
        fat = builder.fat;
        sodium = builder.sodium;
        carbohydrate = builder.carbohydrate;
    }
}
public static void main(String[] args) {
        NutritionFacts nutritionFacts = new Builder(10,100)
                .fat(200)
                .carbohydrate(300)
                .sodium(150)
                .build();
    }

:: ๊ฐ ๋ฉ”์†Œ๋“œ์—์„œ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•  ์ˆ˜ ์žˆ๋‹ค.
:: ์—ฌ๋Ÿฌ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํ˜ผํ•ฉํ•˜์—ฌ ๊ฒ€์‚ฌํ•ด์•ผํ•  ๊ฒฝ์šฐ build ๋ฉ”์„œ๋“œ์—์„œ ํ˜ธ์ถœํ•˜๋Š” ์ƒ์„ฑ์ž์—์„œ ์ด๋ฅผ ๊ฒ€์‚ฌํ•  ์ˆ˜ ์žˆ๋‹ค.
:: ์„ธํ„ฐ ๋ฉ”์„œ๋“œ๋Š” ๋นŒ๋” ์ž์‹ ์„ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์—ฐ์‡„์ ์œผ๋กœ ํ˜ธ์ถœ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ์ฝ”๋“œ๋ฅผ ์“ฐ๊ณ  ์ฝ๊ธฐ ์‰ฝ๋‹ค.


๐Ÿ– ๊ณ„์ธต์ ์œผ๋กœ ์„ค๊ณ„๋œ ํด๋ž˜์Šค์—์„œ์˜ ๋นŒ๋” ํŒจํ„ด

:: ๊ฐ ๊ณ„์ธต์˜ ํด๋ž˜์Šค์— ๊ด€๋ จ ๋นŒ๋”๋ฅผ ๋ฉค๋ฒ„๋กœ ์ •์˜, ์ถ”์ƒ ํด๋ž˜์Šค๋Š” ์ถ”์ƒ ๋นŒ๋”๋ฅผ, ๊ตฌ์ฒด ํด๋ž˜์Šค๋Š” ๊ตฌ์ฒด ๋นŒ๋”๋ฅผ ๊ฐ–๊ฒŒ ํ•œ๋‹ค.

public class Pizza {
    public enum Topping {HAM, MUSHROOM, ONION;}
    final Set<Topping> toppings;

    abstract static class Builder<T extends Builder<T>>{
        EnumSet<Topping> toppings = EnumSet.noneOf(Topping.class);

        public T addTopping(Topping topping){
            toppings.add(Objects.requireNonNull(topping));
            return self();
        }
        abstract Pizza build();
        protected  abstract T self();
    }
    Pizza(Builder<?> builder) {
        toppings = builder.toppings.clone();
    }
}
import java.util.Objects;

public class Calzone extends Pizza {
    private final boolean sauceInside;

    public static class Builder extends Pizza.Builder<Builder> {
        private boolean sauceInside = false;

        public Builder sauceInside() {
            sauceInside = true;
            return this;
        }

        @Override
        public Calzone build() {
            return new Calzone(this);
        }

        @Override
        protected Builder self() {
            return this;
        }
    }

    private Calzone(Builder builder) {
        super(builder);
        sauceInside = builder.sauceInside;
    }
}
- Objects.requireNonNull(obj) : obj๊ฐ€ null์ธ์ง€ ํ™•์ธ. ๋‘๋ฒˆ์งธ ์ธ์ž๋กœ ๋ฉ”์„ธ์ง€๋ฅผ ์„ค์ •ํ•  ์ˆ˜๋„ ์žˆ์Œ.
- Objects.requireNonNullElse(obj, obj2) : obj๊ฐ€ null์ด๋ผ๋ฉด obj2๋กœ ๋Œ€์ฒด ๊ฐ€๋Šฅ.

:: ์ถ”์ƒ ๋ฉ”์„œ๋“œ self๋ฅผ ์ด์šฉํ•˜์—ฌ ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ํ˜•๋ณ€ํ™˜์„ ๊ฑฐ์น˜์น˜ ์•Š๊ณ ๋„ ๋ฉ”์„œ๋“œ ์—ฐ์‡„๋ฅผ ์ง€์›ํ•  ์ˆ˜ ์žˆ๋‹ค.(simulated self-type) :: ํ•˜์œ„ ํด๋ž˜์Šค์˜ ๋นŒ๋”๊ฐ€ ์ •์˜ํ•œ build() ๋ฉ”์„œ๋“œ๋Š” ํ•ด๋‹นํ•˜๋Š” ๊ตฌ์ฒด ํ•˜์œ„ํด๋ž˜์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋•Œ๋ฌธ์— ํด๋ผ์ด์–ธํŠธ๋Š” ํ˜•๋ณ€ํ™˜์„ ์‹ ๊ฒฝ์“ฐ์ง€ ์•Š๊ณ  ๋นŒ๋”๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค (๊ณต๋ณ€๋ฐ˜ํ™˜ ํƒ€์ดํ•‘)

๐Ÿ‘Ž ๋นŒ๋” ํŒจํ„ด์˜ ๋‹จ์ 

์ ์ธต์  ์ƒ์„ฑ์ž ํŒจํ„ด๋ณด๋‹ค๋Š” ์ฝ”๋“œ๊ฐ€ ์žฅํ™”ํ•ด ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ 4๊ฐœ ์ด์ƒ์€ ๋˜์–ด์•ผ ๊ฐ’์–ด์น˜๋ฅผ ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ API๋Š” ์‹œ๊ฐ„์ด ์ง€๋‚  ์ˆ˜๋ก ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋งŽ์•„์ง€๋Š” ๊ฒฝํ–ฅ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์• ์ดˆ์— ๋นŒ๋”๋กœ ์‹œ์ž‘ํ•˜๋Š” ํŽธ์ด ๋‚˜์„๋•Œ๊ฐ€ ๋งŽ๋‹ค.



๐Ÿ“Œ Item03. private ์ƒ์„ฑ์ž๊ฑฐ๋‚˜ ์—ด๊ฑฐ ํƒ€์ž…์œผ๋กœ ์‹ฑ๊ธ€ํ„ด์ž„์„ ๋ณด์ฆํ•˜๋ผ.


์‹ฑ๊ธ€ํ„ด(singleton) : ์ธ์Šคํ„ด์Šค๋ฅผ ์˜ค์ง ํ•˜๋‚˜๋งŒ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ํด๋ž˜์Šค. ํ•จ์ˆ˜์™€ ๊ฐ™์€ ๋ฌด์ƒํƒœ ๊ฐ์ฒด๋‚˜ ์„ค๊ณ„์ƒ ์œ ์ผํ•ด์•ผ ํ•˜๋Š” ์‹œ์Šคํ…œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊ทธ ์˜ˆ์ด๋‹ค.

์‹ฑ๊ธ€ํ„ด ํด๋ž˜์Šค๋Š” ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํด๋ผ์ด์–ธํŠธ๋ฅผ ํ…Œ์ŠคํŠธํ•˜๊ธฐ๊ฐ€ ์–ด๋ ค์›Œ์งˆ ์ˆ˜ ์žˆ๋‹ค.
ํƒ€์ž…์„ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ •์˜ํ•œ ๋‹ค์Œ ์ด๋ฅผ ๊ตฌํ˜„ํ•ด์„œ ๋งŒ๋“  ์‹ฑ๊ธ€ํ„ด์ด ์•„๋‹ˆ๋ผ๋ฉด ์‹ฑ๊ธ€ํ„ด ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€์งœ(mock) ๊ตฌํ˜„์œผ๋กœ ๋Œ€์ฒดํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

โ˜๏ธ ๋ฐฉ๋ฒ• 1. public static final ํ•„๋“œ ์‹ฑ๊ธ€ํ„ด

public class Singleton1 {
    public static final Singleton1 INSTANCE = new Singleton1();
    
    private Singleton1(){}
}
//์ƒ์„ฑ ๋ถˆ๊ฐ€๋Šฅ
Singleton1 singleton1 = new Singleton1();  (x)
//์ธ์Šคํ„ด์Šค ๊ฐ€์ ธ์˜ด.
Singleton1 singleton1 = Singleton1.INSTANCE;

:: ์ƒ์„ฑ์ž๊ฐ€ private๋กœ ์„ ์–ธ๋˜๊ธฐ ๋•Œ๋ฌธ์— ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์—†๋‹ค, ๋”ฐ๋ผ์„œ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ „์ฒด ์‹œ์Šคํ…œ์—์„œ ํ•˜๋‚˜๋ฟ์ž„์ด ๋ณด์žฅ๋œ๋‹ค.
:: ์ž‘์„ฑ์ด ๊ฐ„๊ฒฐํ•˜๊ณ , ์‹ฑ๊ธ€ํ„ด์ž„์ด ๋ช…๋ฐฑํ•˜๊ฒŒ ๋“œ๋Ÿฌ๋‚œ๋‹ค.

:: ํ•˜์ง€๋งŒ ์˜ˆ์™ธ๋กœ ๋ฆฌํ”Œ๋ ‰์…˜ API์˜ AccessibleObject.setAccesible(true)๋ฅผ ์‚ฌ์šฉํ•ด private ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋  ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์Œ๊ณผ๊ฐ™์€ ์ž‘์„ฑ์ด ํ•„์š”ํ•˜๋‹ค.

int count =0;

private Singleton1() {
        count++;
        if(count != 1){
            throw new IllegalStateException("this Object should be Singleton");
        }
}

โ˜๏ธ ๋ฐฉ๋ฒ• 2. ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฐฉ์‹์˜ ์‹ฑ๊ธ€ํ„ด

public class Singleton2 {
    private static final Singleton2 INSTANCE = new Singleton2();
    
    private Singleton2(){};
    
    public static Singleton2 getInstance(){
        return INSTANCE;
    }
}
Singleton2 singleton2 = Singleton2.getInstance();

:: INSTANCE ํ•„๋“œ๋„ private๋กœ ์ฒ˜๋ฆฌํ•˜๊ณ  ์ธ์Šคํ„ด์Šค๋ฅผ ์–ป๊ธฐ์œ„ํ•œ ์ •์  ๋ฉ”์†Œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์ด๋ฅผ ํ†ตํ•ด ์ธ์Šคํ„ด์Šค๋ฅผ ์–ป๋Š”๋‹ค.

  • ์žฅ์ 

      1. API๋ฅผ ๋ฐ”๊พธ์ง€ ์•Š๊ณ ๋„ ์‹ฑ๊ธ€ํ„ด์ด ์•„๋‹ˆ๊ฒŒ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.(๋ฉ”์†Œ๋“œ์—์„œ new๋กœ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ด์„œ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋œ๋‹ค.)
      2. ์ •์  ํŒฉํ„ฐ๋ฆฌ๋ฅผ ์ œ๋„ค๋ฆญ ์‹ฑ๊ธ€ํ„ด ํŒฉํ„ฐ๋ฆฌ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.(์•„์ดํ…œ 30)
      3. ์ •์  ํŒฉํ„ฐ๋ฆฌ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์ฐธ์กฐ๋ฅผ ๊ณต๊ธ‰์ž(supplier)๋กœ ํ•  ์ˆ˜ ์žˆ๋‹ค.
    
Supplier<Singleton2> singleton2Supplier= Singleton2::getInstance;

๐Ÿ–๏ธ ๋ฐฉ๋ฒ• 1๊ณผ 2์˜ ์ง๋ ฌํ™” ๋ฌธ์ œ.

๋‘ ๋ฐฉ๋ฒ•์œผ๋กœ ๊ตฌํ˜„๋œ ์‹ฑ๊ธ€ํ„ด ํด๋ž˜์Šค๋Š” ์ง๋ ฌํ™”, ์—ญ ์ง๋ ฌํ™” ๊ณผ์ •์—์„œ ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋˜๊ฒŒ ๋œ๋‹ค.
์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‘ ๊ฐ€์ง€ ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

1. ๋ชจ๋“  ์ธ์Šคํ„ด์Šค ํ•„๋“œ์˜ transient ์„ ์–ธ.
2. readResolve ๋ฉ”์„œ๋“œ์˜ ์ œ๊ณต.
  • ๋ฐฉ๋ฒ• 2์—์„œ์˜ ๋ณ€๊ฒฝ.(Serializable)
private static final transient Singleton2 INSTANCE = new Singleton2();

private Object readResolve(){
        return INSTANCE;
}

โ˜๏ธ ๋ฐฉ๋ฒ•3. enum ํƒ€์ž… ๋ฐฉ์‹์˜ ์‹ฑ๊ธ€ํ„ด

public enum Singleton3 implements Serializable {
    INSTANCE;
}
Singleton3 singleton3 =Singleton3.INSTANCE;

:: ๋ฐฉ๋ฒ•1๊ณผ ์œ ์‚ฌํ•˜์ง€๋งŒ ๊ฐ„๊ฒฐํ•˜๊ณ , ๋ฆฌํ”Œ๋ž™์…˜์˜ ๋ฐฉ์–ด์™€ ์ง๋ ฌํ™”ํ•˜๋Š”๋ฐ ์žˆ์–ด ์ถ”๊ฐ€์ ์ธ ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค.
:: ๊ทธ๋Ÿฌ๋‚˜ ์‹ฑ๊ธ€ํ„ด ํด๋ž˜์Šค๊ฐ€ ํด๋ž˜์Šค๋ฅผ ์ƒ์†ํ•ด์•ผ ํ•œ๋‹ค๋ฉด ์ด ๋ฐฉ๋ฒ•์€ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค. (์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„๋งŒ ๊ฐ€๋Šฅ.)



๐Ÿ“Œ Item04. ์ธ์Šคํ„ด์Šคํ™”๋ฅผ ๋ง‰์œผ๋ ค๊ฑฐ๋“  private ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋ผ.


Utility ํด๋ž˜์Šค๋“ค๊ณผ ๊ฐ™์ด ์ •์  ๋ฉ”์„œ๋“œ์™€ ์ •์  ํ•„๋“œ๋งŒ์„ ๋‹ด์€ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋„๋ก ์„ค๊ณ„ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋ ‡๋‹ค๊ณ  ์ƒ์„ฑ์ž๋ฅผ ์ž‘์„ฑํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ํ•ด๋„, ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ž๋™์œผ๋กœ ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค.

โ˜๏ธ ๋ฐฉ๋ฒ•1. Abstract Class

public abstract class UtilityClass {
    public static String getName(){
        return "kim";
    }

    public static void main(String[] args) {
        UtilityClass.getName();

//         ์ถ”์ƒ ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ๋ถˆ๊ฐ€๋Šฅ
        UtilityClass utilityClass = new UtilityClass(); (x)

    }
}

:: abstract Class ๋กœ ๋งŒ๋“ค๋ฉด ํ•ด๋‹น ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

public class AnotherClass extends UtilityClass{
    public static void main(String[] args) {
        AnotherClass anotherClass = new AnotherClass();
//        ๋ฉ”์†Œ๋“œ ์‚ฌ์šฉ ๋ถˆ๊ฐ€๋Šฅ.
//        anotherClass.getName() (x);
    }
}

:: ํ•˜์ง€๋งŒ ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์€ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋Š” ์ƒ์„ฑ๋ ์ˆ˜ ์žˆ๋‹ค, ๊ทธ๋Ÿฌ๋‚˜ ๋ฉ”์†Œ๋“œ์˜ ์‚ฌ์šฉ์ด ๋ถˆ๊ฐ€๋Šฅํ•œ ์•„๋ฌด์˜๋ฏธ ์—†๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ๋œ๋‹ค.
:: ๋•Œ๋ฌธ์— ๋ฐฉ๋ฒ• 2๋ฅผ ์ œ์•ˆํ•œ๋‹ค.

โ˜๏ธ ๋ฐฉ๋ฒ•2. private ์ƒ์„ฑ์ž

public class UtilityClass {
    public static String getName(){
        return "kim";
    }
    //์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ๋ฐฉ์ง€.
    private UtilityClass(){
        throw new AssertionError();
    }
}

:: ์ƒ์„ฑ์ž๋ฅผ private๋กœ ์ƒ์„ฑํ•˜๊ฒŒ ๋˜๋ฉด ์™ธ๋ถ€์—์„œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ• ์ˆ˜๋„ ์—†๊ณ , ์ปดํŒŒ์ผ๋Ÿฌ ๋˜ํ•œ public ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๋Š”๋‹ค.
:: ์ƒ์† ๋˜ํ•œ private ์ƒ์„ฑ์ž์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ถˆ๊ฐ€๋Šฅํ•˜๋””.
:: ์ƒ์„ฑ์ž๊ฐ€ ์กด์žฌํ•˜๋Š”๋ฐ ํ˜ธ์ถœ์„ ํ• ์ˆ˜ ์—†์–ด ์ง๊ด€์ ์ด์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ ์ ˆํ•œ ์ฃผ์„์ด ํ•„์š”ํ•˜๋‹ค.



๐Ÿ“Œ Item05. ์ž์›์„ ์ง์ ‘ ๋ช…์‹œํ•˜์ง€ ๋ง๊ณ  ์˜์กด๊ฐ์ฒด ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜๋ผ.


๋งŽ์€ ํด๋ž˜์Šค๊ฐ€ ํ•˜๋‚˜ ์ด์ƒ์˜ ์ž์›์— ์˜์กดํ•จ. ์˜ˆ๋ฅผ ๋“ค์–ด ๋งž์ถค๋ฒ• ๊ฒ€์‚ฌ๊ธฐ๋Š” ์‚ฌ์ „์— ์˜์กดํ•˜๊ฒŒ ๋˜๊ณ  ์ด๋Ÿฐ ํด๋ž˜์Šค๋ฅผ ์ž˜๋ชป๋œ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•œ ๊ฒƒ์„ ํ”ํžˆ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ‘Ž ์ž˜๋ชป๋œ ๊ตฌํ˜„


โ˜๏ธ ์ •์  ์œ ํ‹ธ๋ฆฌํ‹ฐ ํด๋ž˜์Šค(์•„์ดํ…œ4)

public class SpellChecker1 {
    private static final Lexicon dictionary = new KoreanDictionary();

    //๊ฐ์ฒด ์ƒ์„ฑ ๋ฐฉ์ง€
    private SpellChecker1() {
    }

    public static boolean isValid(String word) {
        // check
        return true;
    }
}

:: ์œ ์—ฐํ•˜์ง€ ๋ชปํ•˜๋‹ค. ์‚ฌ์ „์˜ ๊ต์ฒด๊ฐ€ ์–ด๋ ค์›€.

โ˜๏ธ ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ๊ตฌํ˜„(์•„์ดํ…œ3)

public class SpellChecker2 {
    private final Lexicon dictionary =new KoreanDictionary();
    
    private SpellChecker2(){}

    public static final SpellChecker2 INSTANCE = new SpellChecker2();

    public boolean isValid(String word){
        // check
        return true;
    }

}

:: ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์œ ์—ฐํ•˜์ง€ ๋ชปํ•˜๊ณ , ์‚ฌ์ „์˜ ๊ต์ฒด๊ฐ€ ์–ด๋ ต๋‹ค.

-์œ„์˜ ๋‘๊ฐ€์ง€ ๋ฐฉ์‹์—์„œ๋Š” ์ƒˆ๋กœ์šด ์‚ฌ์ „์˜๋กœ ๊ต์ฑ„ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์€ ์˜ค๋ฅ˜๋ฅผ ๋‚ด๊ธฐ ์‰ฌ์šฐ๋ฉฐ,     
๋ฉ€ํ‹ฐ ์“ฐ๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ์— ์ ํ•ฉํ•˜์ง€์•Š๋‹ค.

๐Ÿ‘ ์ ์ ˆํ•œ ๊ตฌํ˜„


public class SpellChecker3 {
    private final Lexicon dictionary;
    
    public SpellChecker3(Lexicon dictionary) {
        this.dictionary =  Objects.requireNonNull(dictionary);
    }
    public boolean isValid(String word){
        //check
        return true;
    }
}

:: ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์ƒ์„ฑ์ž์— ํ•„์š”ํ•œ ์ž์›(์‚ฌ์ „์„ ๋„˜๊ฒจ์ค€๋‹ค.) ์ด๋Š” ์˜์กด ๊ฐ์ฒด ์ฃผ์ž…์˜ ํ•œ ํ˜•ํƒœ์ด๋‹ค.
:: ์ •์  ํŒฉํ„ฐ๋ฆฌ, ๋นŒ๋”์—๋„ ์ ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.

โ˜๏ธ ๋ณ€ํ˜• : ์ž์›์ด ์•„๋‹Œ ์ž์› ํŒฉํ„ฐ๋ฆฌ ๋„˜๊ฒจ์ฃผ๊ธฐ.

public class SpellChecker4 {
    private final Lexicon dictionary;

    public SpellChecker4(Supplier<Lexicon> dictionary) {
        this.dictionary =  Objects.requireNonNull(dictionary.get());
    }
    public boolean isValid(String word){
        //check
        return true;
    }
}
Lexicon lexicon = new KoreanDictionary();
SpellChecker4 spellChecker4 = new SpellChecker4(new Supplier<Lexicon>() {
    @Override
    public Lexicon get() {
        return lexicon;
    }
});

๐Ÿ”‘ ํ•ต์‹ฌ

  • ํด๋ž˜์Šค๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ํ•˜๋‚˜ ์ด์ƒ์˜ ์ž์›์— ์˜์กดํ•˜๊ณ , ๊ทธ ์ž์›์ด ํด๋ž˜์Šค ๋™์ž‘์— ์˜ํ–ฅ์„ ์ค€๋‹ค๋ฉด ํ•ด๋‹น ์ž์›๋“ค์„ ํด๋ž˜์Šค๊ฐ€ ์ง์ ‘ ๋งŒ๋“ค๊ฒŒ ํ•ด์„œ๋Š” ์•ˆ๋œ๋‹ค.
  • ๋Œ€์‹  ํ•„์š”ํ•œ ์ž์›(๋˜๋Š” ํŒฉํ„ฐ๋ฆฌ)์„ ์ƒ์„ฑ์ž(๋˜๋Š” ์ •์  ํŒฉํ„ฐ๋ฆฌ, ๋นŒ๋”)์— ๋„˜๊ฒจ์ค€๋‹ค.
  • ์ด๋Ÿฐ ์˜์กด๊ฐ์ฒด ์ฃผ์ž…์€ ํด๋ž˜์Šค์˜ ์œ ์—ฐ์„ฑ, ์žฌ์‚ฌ์šฉ์„ฑ, ํ…Œ์ŠคํŠธ ์šฉ์ด์„ฑ์„ ๊ฐœ์„ ํ•ด์ค€๋‹ค



๐Ÿ“Œ Item06. ๋ถˆํ•„์š”ํ•œ ๊ฐ์ฒด ์ƒ์„ฑ์„ ํ”ผํ•˜๋ผ


๋˜‘๊ฐ™์€ ๊ธฐ๋Šฅ์˜ ๊ฐ์ฒด๋ฅผ ๋งค๋ฒˆ ์ƒ์„ฑํ•˜๊ธฐ ๋ณด๋‹ค๋Š” ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋Š” ํŽธ์ด ๋‚˜์„๋•Œ๊ฐ€ ๋งŽ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์•„๋ž˜์™€ ๊ฐ™์€ ์ƒํ™ฉ์ด๋‹ค.

โ˜๏ธ ๋ฌธ์ž์—ด ๊ฐ์ฒด ์ƒ์„ฑ.

String s = new String("test");

String s = "test";

:: ์ƒ์„ฑ์ž์— ๋„˜๊ฒจ์ง„ "test"์ž์ฒด๊ฐ€ ์ƒ์„ฑ์ž๋กœ ๋งŒ๋“ค์–ด ๋‚ด๋Š” ๊ฐ์ฒด์˜ ์—ญํ• ๊ณผ ์™„์ „ํžˆ ๋™์ผํ•˜๋‹ค.
:: 1๋ฒˆ์˜ ์ฝ”๋“œ์—์„œ๋Š” ๋งค๋ฒˆ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์ง€๋งŒ 2๋ฒˆ์—์„œ๋Š” ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋ฅผ ์žฌ์‚ฌ์šฉํ•˜์—ฌ ๋ถˆํ•„์š”ํ•œ ์ƒ์„ฑ์„ ํ•˜์ง€ ์•Š๋Š”๋‹ค.

String s1 = new String("test");
String s2 = new String("test");

System.out.println(s1 == s2 );  //false

โ˜๏ธ ์ •์  ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ์˜ ์‚ฌ์šฉ.

boolean b1 = Boolean.valueOf("true");
boolean b2 = Boolean.valueOf("true");

System.out.println(b1 == b2);   //true
System.out.println(b1 == Boolean.TRUE); //true

:: Boolean(String) ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋ณด๋‹ค๋Š” ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ๋™์ผํ•œ ๊ฐ์ฒด๊ฐ€ ๋ฐ˜ํ™˜๋จ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฐ˜ํ™˜๋˜๋Š” ๊ฐ์ฒด๋Š” static field์ธ Boolean.TRUE์ด๋‹ค.

โ˜๏ธ ์ƒ์‚ฐ ๋น„์šฉ์ด ๋น„์‹ผ ๊ฐ์ฒด.

:: ๋น„์‹ผ ๊ฐ์ฒด๊ฐ€ ๋ฐ˜๋ณตํ•ด์„œ ํ•„์š”ํ•˜๋‹ค๋ฉด ์บ์‹ฑํ•˜์—ฌ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋œ๋‹ค.
๋‹ค์Œ์€ ๋ฌธ์ž์—ด์ด ์œ ํšจํ•œ ๋กœ๋งˆ์ˆซ์ž์ธ์ง€ ํ™•์ธํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค

static boolean isRomanNumeral(String s){
    return s.matches("^(?=.)M*(C[MD]|D?C{0,3})" + "(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
}

:: ๋ฉ”์„œ๋“œ์˜ ๋‚ด๋ถ€์—์„œ ์ƒ์„ฑ๋˜๋Š” ์ •๊ทœํ‘œํ˜„์‹์šฉ Pattern ์ธ์Šคํ„ด์Šค๋Š” ํ•œ๋ฒˆ ์‚ฌ์šฉํ•˜๊ณ  ๋ฒ„๋ ค์ง€๋Š”๋ฐ, Pattern์€ ์ž…๋ ฅ๋ฐ›์€ ์ •๊ทœํ‘œํ˜„์‹์— ํ•ด๋‹นํ•˜๋Š” ์œ ํ•œ ์ƒํƒœ ๋จธ์‹ ์„ ๊ทธ๋ฆฌ๊ธฐ ๋งŒ๋“ค๊ธฐ ๋•Œ๋ฌธ์— ์ƒ์„ฑ ๋น„์šฉ์ด ๋†’๋‹ค. :: ๋•Œ๋ฌธ์— ํด๋ž˜์Šค๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๊ณผ์ •์—์„œ ์ง์ ‘ ์ƒ์„ฑํ•ด ์บ์‹ฑํ•ด๋‘๊ณ  ํ˜ธ์ถœ๋  ๋•Œ ํ•ด๋‹น ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ด ํšจ์œจ์ ์ด๋‹ค.

static boolean isRomanNumeral(String s){
    return ROMAN.matcher(s).matches();
}

:: ์„ฑ๋Šฅ์˜ ๊ฐœ์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ฝ”๋“œ์˜ ์˜๋ฏธ๋˜ํ•œ ๋ช…ํ™•ํ•ด์กŒ๋‹ค. (Pattern ์ธ์Šคํ„ด์Šค๊ฐ€ ๋“œ๋Ÿฌ๋‚จ.)

โ˜๏ธ ์–ด๋Œ‘ํ„ฐ

:: ๊ฐ์ฒด๊ฐ€ ๋ถˆ๋ณ€์ด๋ผ๋ฉด ์žฌ์‚ฌ์šฉํ•ด๋„ ์•ˆ์ „ํ•จ์ด ๋ช…๋ฐฑํ•˜๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋œ ๋ช…ํ™•ํ•˜๊ฑฐ๋‚˜, ์‹ฌ์ง€์–ด ์ง๊ด€์— ๋ฐ˜๋Œ€๋˜๋Š” ์ƒํ™ฉ๋„ ์žˆ๋‹ค.
:: ์–ด๋Œ‘ํ„ฐ๋Š” ์‹ค์ œ ์ž‘์—…์€ ๋’ท๋‹จ ๊ฐ์ฒด์— ์œ„์ž„ํ•˜๊ณ  ์ž์‹ ์€ ์ธํ„ฐํŽ˜์ด์Šค์˜ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ๋•Œ๋ฌธ์— ๋’ท๋‹จ ๊ฐ์ฒด ํ•˜๋‚˜๋‹น ํ•˜๋‚˜์˜ ์–ด๋Œ‘ํ„ฐ๋งŒ ์ƒ์„ฑํ•˜๋ฉด ์ถฉ๋ถ„ํ•˜๋‹ค.

Map<String, Integer> students = new HashMap<>();

students.put("kim",23);
students.put("park",25);

Set<String> names = students.keySet();
Set<String> names2 = students.keySet();

names.remove("kim");

System.out.println(names.size());   // 1
System.out.println(names2.size());  // 1

:: Map ์˜ keySet()๋ฉ”์„œ๋“œ๋Š” ํ‚ค๋ฅผ ๋‹ด์€ Set์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์ด๋“ค์€ ๋ชจ๋‘ ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ํ•˜๋‚˜์˜ ๋‚ด์šฉ์ด ๋ณ€ํ•˜๋ฉด ๋ชจ๋“  Set๊ณผ Map์ด ๋ณ€๊ฒฝ๋œ๋‹ค.

โ˜๏ธ ์˜คํ† ๋ฐ•์‹ฑ

Long sum =0l;
for(long i =0l; i<Integer.MAX_VALUE; i++)
    sum+= i;

:: sum ๋ณ€์ˆ˜๋Š” Long์œผ๋กœ ์„ ์–ธ๋˜์–ด ์žˆ๊ณ , ์—ฌ๊ธฐ์— long ํƒ€์ž…์˜ i ๋ฅผ ๋”ํ•œ๋‹ค. ์ด๋•Œ i๊ฐ€ sum์— ๋”ํ•ด์งˆ๋•Œ ๋งˆ๋‹ค Long ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ฒŒ ๋˜๊ณ ,
์—ฌ๊ธฐ์„œ๋Š” ์•ฝ 2^31๊ฐœ์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค. :: Long ํƒ€์ž…์— long์„ ๋”ํ• ๋•Œ ๊ฑธ๋ฆฐ ์‹œ๊ฐ„์€ 3229ms ์˜€๊ณ , longํƒ€์ž…์— longํƒ€์ž…์„ ๋”ํ•  ๋•Œ ๊ฑธ๋ฆฐ ์‹œ๊ฐ„์€ 729ms๋กœ ์•ฝ 4๋ฐฐ ์ด์ƒ์˜ ์„ฑ๋Šฅ์ฐจ์ด๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.

๐Ÿ”‘ ํ•ต์‹ฌ

  • ๋ถˆํ•„์š”ํ•œ ๊ฐ์ฒด์˜ ์ƒ์„ฑ์„ ํ”ผํ•˜์ž (์žฌ์‚ฌ์šฉ)
  • "๊ฐ์ฒด์˜ ์ƒ์„ฑ์€ ๋น„์‹ธ๋‹ˆ ํ”ผํ•˜์ž" ๋ผ๋Š” ๋ง์ด ์•„๋‹ˆ๋‹ค. ๋น„์‹ธ๊ณ , ์žฌ์‚ฌ์šฉ์ด ์•ˆ์ „ํ•œ ๊ฐ์ฒด์˜ ์ƒ์„ฑ์„ ์ค„์ด์ž๋Š” ๊ฒƒ์ด๋‹ค.
  • ๋ฌด๋ถ„๋ณ„ํ•œ ๊ฐ์ฒด ์žฌ์‚ฌ์šฉ์€ ์˜คํžˆ๋ ค ๋ฒ„๊ทธ์™€ ๋ณด์•ˆ์ƒ์˜ ๋ฌธ์ œ๋กœ ์ด์–ด์ง„๋‹ค.



๐Ÿ“Œ Item07. ๋‹ค ์“ด ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ํ•ด์ œํ•˜๋ผ.


์ž๋ฐ”์˜ GC๊ฐ€ ๋ชจ๋“ ๊ฒƒ์„ ํ•ด๊ฒฐํ•ด์ฃผ์ง€๋Š” ์•Š๋Š”๋‹ค.

โ˜๏ธ ์Šคํƒ


public class Stack {
    private Object[] elements;
    private int size = 0;
    private static final int DEFAULT_INTTIAL_CAPACITY = 16;

    public Stack(){
        elements = new Object[DEFAULT_INTTIAL_CAPACITY];
    }
    
    public void push(Object e){
        ensureCapacity();
        elements[size++] = e;
    }
    
    public Object pop(){
        if(size == 0)
            throw new EmptyStackException();
        return elements[--size];
    }
    
    public void ensureCapacity(){
        if(elements.length ==size)
            elements = Arrays.copyOf(elements, size*2 +1);
    }
    

}

:: ์Šคํƒ์ด ์ปค์กŒ๋‹ค ์ž‘์•„์งˆ ๋•Œ, ์Šคํƒ์—์„œ ๊บผ๋‚ด์ง„ ๊ฐ์ฒด๋“ค์„ GC๊ฐ€ ํšŒ์ˆ˜ํ•˜์ง€ ์•Š๊ธฐ๋•Œ๋ฌธ์— ๋ฉ”๋ชจ๋ฆฌ์˜ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. :: ๊ฐ์ฒด ์ฐธ์กฐ ํ•˜๋‚˜๋ฅผ ์‚ด๋ ค๋‘๋ฉด GC๋Š” ๊ทธ ๊ฐ์ฒด๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๊ทธ ๊ฐ์ฒด๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ๊ฐ์ฒด, ๊ทธ ๊ฐ์ฒด๊ฐ€ ๋˜ ์ฐธ์กฐํ•˜๋Š” ๊ฐ์ฒด.. ๋ชจ๋‘ ํšŒ์ˆ˜ํ•  ์ˆ˜ ์—†๋‹ค.

 public Object pop(){
        if(size == 0)
            throw new EmptyStackException();
        Object result = elements[--size];
        elements[size] =null;
        return result;
    }

:: ๋ฉ”๋ชจ๋ฆฌ์˜ ๋ˆ„์ˆ˜๋Š” pop๋ฉ”์†Œ๋“œ์—์„œ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋” ์ด์ƒ ํ•„์š”์—†์–ด์ง„ ์›์†Œ์˜ ์ฐธ์กฐ๋ฅผ null์ฒ˜๋ฆฌํ•œ๋‹ค. ์ž˜๋ชป๋œ ์ฐธ์กฐ์—์„œ ์˜ค๋Š” ์˜ค๋ฅ˜๋˜ํ•œ ๋ค์œผ๋กœ ์žก์•„์ค€๋‹ค.
:: ๊ทธ๋Ÿฌ๋‚˜ ๋ชจ๋“  ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•œ ํ›„ null์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฐ”๋žŒ์งํ•˜์ง€ ์•Š๋‹ค. ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ๋ณ€์ˆ˜์˜ ๋ฒ”์œ„๋ฅผ ์ตœ์†Œ๊ฐ€ ๋˜๊ฒŒ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

:: Stack ํด๋ž˜์Šค๋Š” ์ž๊ธฐ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ง์ ‘ ๊ด€๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฌํ•œ null์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค. GC์˜ ์ž…์žฅ์—์„œ๋Š” ๋˜‘๊ฐ™์ด ์œ ํšจํ•œ ๊ฐ์ฒด์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

โ˜๏ธ ์บ์‹œ


:: ์บ์‹œ ์—ญ์‹œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ์ผ์œผํ‚ค๋Š” ์ฃผ๋ฒ”์ด๋‹ค. :: ์บ์‹œ ์™ธ๋ถ€์—์„œ ํ‚ค๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋™์•ˆ๋งŒ ์—”ํŠธ๋ฆฌ๊ฐ€ ์‚ด์•„์žˆ๋Š” ์บ์‹œ๊ฐ€ ํ•„์š”ํ•œ ์ƒํ™ฉ์ด๋ผ๋ฉด WeakHashMap์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

String key = "key1";
Object value = new Object();

Map<String, Object> cache = new WeakHashMap<>();
cache.put(key,value);

:: StrongReference์ธ key๊ฐ€ ํ•„์š” ์—†์–ด์ง€๋ฉด ํ•ด๋‹น ์—”ํŠธ๋ฆฌ๋ฅผ ํ•ด์‹œ์—์„œ๋„ ์ž๋™์œผ๋กœ ๋น„์›Œ์ค€๋‹ค. ์ฆ‰ StrongReference์ธ key๊ฐ€ GC์˜ ๋Œ€์ƒ์ด ๋˜๋ฉด ์ด๋ฅผ ์ฐธ์กฐํ•˜๋Š” WeakReference์ธ ๊ฐ์ฒด ๋˜ํ•œ GC์˜ ๋Œ€์ƒ์ด ๋  ์ˆ˜ ์žˆ๋‹ค.
:: ๋ณดํ†ต์€ ์บ์‹œ์˜ ์œ ํšจ๊ธฐ๊ฐ„์„ ์ •ํ™•ํžˆ ์ •์˜ํ•˜๊ธฐ ์–ด๋ ต๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ • ์‹œ๊ฐ„๋งˆ๋‹ค ๋น„์›Œ์ค€๋‹ค.

โ˜๏ธ ์ฝœ๋ฐฑ


:: ์ฝœ๋ฐฑ๋„ ์บ์‹œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ฝœ๋ฐฑ์„ ์ง€์šธ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๊ณ„์† ์Œ“์ด๊ธฐ๋งŒ ํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
:: ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ WeakHashMap์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๊ฒฐ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ”‘ ํ•ต์‹ฌ

  • ํด๋ž˜์Šค ์ž์‹ ์ด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ง์ ‘ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฐ์ฒด๋ฅผ null ์ฒ˜๋ฆฌํ•ด์ฃผ๋Š” ๊ฒƒ์ด ํ•„์š”ํ•˜๋‹ค.
  • WeakReference๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค.



๐Ÿ“Œ Item09. try-finally๋ณด๋‹ค๋Š” rty-with-resources๋ฅผ ์‚ฌ์šฉํ•˜๋ผ.


  • ์ž๋ฐ” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—๋Š” colse ๋ฉ”์„œ๋“œ๋กœ ์ง์ ‘ ๋‹ซ์•„์ค˜์•ผํ•˜๋Š” ์ž์›์ด ๋งŽ๋‹ค.
  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋†“์นœ ์ž์› ๋‹ซ๊ธฐ๋Š” ์˜ˆ์ธกํ•  ์ˆ˜ ์—†๋Š” ์„ฑ๋Šฅ ๋ฌธ์ œ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค.

โ˜๏ธ ์ „ํ†ต์ ์ธ ๋ฐฉ๋ฒ• try-finally

public void doSomething(){
        System.out.println("Do something");
        throw new FirstException();
    }

    @Override
    public void close() {
        throw new SecondException();
    }

:: ๊ฐ ๋ฉ”์†Œ๋“œ์—์„œ ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๋„๋ก ์ž‘์„ฑํ•œ๋‹ค.

MyResource myResource1 = new MyResource();
        MyResource myResource2 = null;
        try{
            myResource1.doSomething();
            try {
                myResource2 = new MyResource();
                myResource2.doSomething();
            }finally {
                myResource2.close();
            }
        }finally {
            myResource1.close();
        }

:: ์ค‘์ฒฉ์ด ์ƒ๊ธฐ๋ฉด ์ฝ”๋“œ๊ฐ€ ๋ณต์žกํ•ด์ง„๋‹ค. img.png
:: doSomething์—์„œ FirstException์ด ๋ฐœ์ƒํ•˜์ง€๋งŒ ๋‹ค์Œ์— ๋ฐœ์ƒํ•˜๋Š” SecondException์— ๊ฐ€๋ ค์ง€๊ฒŒ ๋œ๋‹ค.

โ˜๏ธ try-with-resources


try (MyResource myResource1 = new MyResource();
        MyResource myResource2 = new MyResource()) {
        myResource1.doSomething();
        myResource2.doSomething();
        }

img_1.png
:: FirstException ๋˜ํ•œ ์ž˜ ๋ณผ ์ˆ˜ ์žˆ๊ณ , myResource2์˜ close๋˜ํ•œ ์ž˜ ์‹คํ–‰๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ”‘ ํ•ต์‹ฌ

  • try-with-Resources๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด์ „ ์˜ˆ์™ธ๊ฐ€ ๊ฐ€๋ ค์ง€์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋””๋ฒ„๊น…์—์„œ ํฐ ์žฅ์ ์„ ๊ฐ€์ง„๋‹ค.
  • ์ฝ”๋“œ๊ฐ€ ๋” ์งง๊ณ  ๋ถ„๋ช…ํ•ด์ง€๊ณ  ์ •ํ™•ํ•˜๊ณ  ์‰ฝ๊ฒŒ ์ž์›์„ ํšŒ์ˆ˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“Œ Item10. equals๋Š” ์ผ๋ฐ˜ ๊ทœ์•ฝ์„ ์ง€์ผœ ์žฌ์ •์˜ํ•˜๋ผ.


โ˜๏ธ ์žฌ์ •์˜ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹์„ ๋•Œ.

equals๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์žฌ์ •์˜ ํ•˜์ง€ ์•Š์œผ๋ฉด ๊ทธ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋Š” ์˜ค์ง ์ž๊ธฐ ์ž์‹ ๊ณผ๋งŒ ๊ฐ™๋‹ค.

  • 1. ๊ฐ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ณธ์งˆ์ ์œผ๋กœ ๊ณ ์œ ํ•˜๋‹ค.

      - ๊ฐ’์„ ํ‘œํ˜„ํ•˜๋А ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋™์ž‘ํ•˜๋Š” ๊ฐœ์ฒด๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ํด๋ž˜์Šค ex)Thread
    
  • 2. ์ธ์Šคํ„ด์Šค์˜ '๋…ผ๋ฆฌ์  ๋™์น˜์„ฑ'์„ ๊ฒ€์‚ฌํ•  ์ผ์ด ์—†๋‹ค.

      - java.util.regex.Pattern ์—์„œ equals๋ฅผ ์žฌ์ •์˜ ํ•˜์—ฌ ์ •๊ทœ์‹์ด ๊ฐ™์€์ง€ ๋…ผ๋ฆฌ์  ๋™์น˜์„ฑ์„ ๊ฒ€์‚ฌํ•  ์ˆ˜ ์žˆ๋‹ค.     
      ํ•˜์ง€๋งŒ ์ด๋Ÿฌํ•œ ๊ฒ€์‚ฌ๊ฐ€ ํ•„์š”์—†๋‹ค๊ณ  ํŒ๋‹จ๋˜๋ฉด ๊ธฐ๋ณธ equals๋งŒ์œผ๋กœ ์ถฉ๋ถ„ํ•˜๋‹ค.
    
  • 3. ์ƒ์œ„ ํด๋ž˜์Šค์—์„œ ์žฌ์ •์˜ํ•œ equals๊ฐ€ ํ•˜์œ„ ํด๋ž˜์Šค์—๋„ ๋”ฑ ๋“ค์–ด๋งž๋Š”๋‹ค.

      - Set,List, Map ๊ตฌํ˜„์ฒด๋“ค์€ Abstํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ ๊ตฌํ˜„ํ•œ equals๋ฅผ ์ƒ์†๋ฐ›์•„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•œ๋‹ค.
    
    public boolean equals(Object o) {
            if (o == this)
                return true;
    
            if (!(o instanceof Map))
                return false;
            Map<?,?> m = (Map<?,?>) o;
            if (m.size() != size())
                return false;
    
            try {
                for (Entry<K, V> e : entrySet()) {
                    K key = e.getKey();
                    V value = e.getValue();
                    if (value == null) {
                        if (!(m.get(key) == null && m.containsKey(key)))
                            return false;
                    } else {
                        if (!value.equals(m.get(key)))
                            return false;
                    }
                }
            } catch (ClassCastException unused) {
                return false;
            } catch (NullPointerException unused) {
                return false;
            }
    
            return true;
        }

    :: AbstractMap์—์„œ ๊ตฌํ–”ํ•œ equals, ๊ฐ™์€ ๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ๋”๋ผ๋„ <key,value> ์Œ์ด ๋ชจ๋‘ ๋™์ผํ•˜๋‹ค๋ฉด ture,
    ๊ตฌํ˜„์ฒด์ธ HashMap๋“ฑ์—์„œ๋„ ๋™์ผํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์žฌ์ •์˜ํ•˜์ง€ ์•Š๋Š”๋‹ค.

  • 4. ํด๋ž˜์Šค๊ฐ€ private์ด๊ฑฐ๋‚˜ package-private์ด๊ณ  equals ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ผ์ด ์—†๋‹ค.

      - ํ˜ธ์ถœํ•  ์ผ์ด ์—†์œผ๋ฉด ๋‹น์—ฐํžˆ ์žฌ์ •์˜ํ•  ํ•„์š”๋„ ์—†๋‹ค. ํ˜น์‹œ equals๊ฐ€ ์‹ค์ˆ˜๋กœ๋ผ๋„ ํ˜ธ์ถœ๋˜๋Š”๊ฑธ ๋ง‰๊ณ  ์‹ถ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌํ˜„ํ•ด๋‘”๋‹ค.
    
    @Override
    public boolean equals(Object o ){
        throw new AssertionError();
    }

โ˜๏ธ equlas๋ฅผ ์žฌ์ •์˜ ํ•ด์•ผํ•  ๋•Œ.

๊ฐ์ฒด ์‹๋ณ„์„ฑ(๋‘ ๊ฐ์ฒด๊ฐ€ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๊ฐ™์€๊ฐ€)์ด ์•„๋‹ˆ๋ผ ๋…ผ๋ฆฌ์  ๋™์น˜์„ฑ์„ ํ™•์ธํ•ด์•ผ ํ•˜๊ณ , ์ƒ์œ„ํด๋ž˜์Šค์—์„œ ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ํ•˜๋„๋ก ์žฌ์ •์˜๋˜์ง€ ์•Š์•˜์„ ๋•Œ. (์ฃผ๋กœ ๊ฐ’ ํด๋ž˜์Šค)

  • ๊ทธ๋Ÿฌ๋‚˜ ๊ฐ’์ด ๊ฐ™์€ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋‘˜ ์ด์ƒ ๋งŒ๋“ค์–ด์ง€์ง€ ์•Š์Œ์„ ๋ณด์žฅํ•˜๋Š” ํด๋ž˜์Šค๋ผ๋ฉด equlas๋ฅผ ์žฌ์ •์˜ ํ•˜์ง€ ์•Š์•„๋„ ๋…ผ๋ฆฌ์  ๋™์น˜์„ฑ๊ณผ ๊ฐ์ฒด ์‹๋ณ„์„ฑ์ด ์‚ฌ์‹ค์ƒ ๊ฐ™์€ ์˜๋ฏธ๋ฅผ ๊ฐ€์ง„๋‹ค.

equlas ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ ํ•  ๋•Œ์˜ ์ผ๋ฐ˜ ๊ทœ์•ฝ.(Object ๋ช…์„ธ์— ์ ํžŒ ๊ทœ์•ฝ)

- ์•„๋ž˜ ๊ทœ์•ฝ์€ ๋ชจ๋‘ ์ฐธ์กฐ ๊ฐ’์ด null์ด ์•„๋‹˜์„ ์ „์ œ๋กœ ํ•œ๋‹ค.
- ๋ฐ˜์‚ฌ์„ฑ(reflexivity): x.equals(x)๋Š” true.
- ๋Œ€์นญ์„ฑ(symmentry) : x.equals(y) ์™€ y.equals(x)์˜ ๊ฒฐ๊ณผ๋Š” ๊ฐ™๋‹ค.
- ์ถ”์ด์„ฑ(transitivity) : x.equals(y) =true, y.equals(z) =true์ด๋ฉด, x.equals(z) =true.
- ์ผ๊ด€์„ฑ(consistency) : x.equals(y)๋ฅผ ๋ฐ˜๋ณตํ•ด์„œ ํ˜ธ์ถœํ•ด๋„ ํ•ญ์ƒ ๊ฐ™์€ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
- null-์•„๋‹˜ : x.equals(null)์€ false์ด๋‹ค.

โœ๏ธ equals ๋ฉ”์„œ๋“œ ๊ตฌํ˜„.

  • 1. == ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด ์ž…๋ ฅ์ด ์ž๊ธฐ ์ž์‹ ์˜ ์ฐธ์กฐ์ธ์ง€ ํ™•์ธํ•œ๋‹ค.

      - ์ž๊ธฐ ์ž์‹ ์ด๋ผ๋ฉด true๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
    
    if (o == this)
        return true;
  • 2. instanceof ์—ฐ์‚ฐ์ž๋กœ ์ž…๋ ฅ์ด ์˜ฌ๋ฐ”๋ฅธ ํƒ€์ž…์ธ์ง€ ํ™•์ธํ•œ๋‹ค.

      - ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด false๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋ณดํ†ต equasl๊ฐ€ ์ •์˜๋œ ํด๋ž˜์Šค ํƒ€์ž…์ธ์ง€ ํ™•์ธํ•˜์ง€๋งŒ ๊ฐ€๋”์€ ๊ทธ ํด๋ž˜์Šค๊ฐ€ ๊ตฌํ˜„ํ•œ ํŠน์ • ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋  ์ˆ˜๋„ ์žˆ๋‹ค.
      - ์ž์‹ ์„ ๊ตฌํ˜„ํ•œ ์„œ๋กœ๋‹ค๋ฅธ ํด๋ž˜์Šค ๋ผ๋ฆฌ๋„ ๋น„๊ตํ•  ์ˆ˜ ์žˆ๋„๋ก ์ˆ˜์ •ํ•˜๊ธฐ๋„ ํ•œ๋‹ค. (Set, List, Map ...) 
    
    if (!(o instanceof Map))
        return false;
  • 3. ์ž…๋ ฅ์„ ์˜ฌ๋ฐ”๋ฅธ ํƒ€์ž…์œผ๋กœ ํ˜•๋ณ€ํ™˜ ํ•œ๋‹ค.

      - ์•ž์„œ instanceof๋กœ ๊ฒ€์‚ฌ๋ฅผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.
    
    Map<?,?> m = (Map<?,?>) o;
  • 4. ์ž…๋ ฅ ๊ฐ์ฒด์™€ ์ž๊ธฐ ์ž์‹ ์ด ๋Œ€์‘๋˜๋Š” 'ํ•ต์‹ฌ'ํ•„๋“œ๋“ค์ด ๋ชจ๋‘ ์ผ์น˜ํ•˜๋Š”์ง€ ํ•˜๋‚˜์”ฉ ๊ฒ€์‚ฌํ•œ๋‹ค.

      - ํ•˜๋‚˜๋ผ๋„ ๋‹ค๋ฅด๋‹ค๋ฉด false๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. 2๋‹จ๊ณ„์—์„œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด ํ•„๋“œ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ๋•Œ๋„ ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
    
    try {
        for (Entry<K, V> e : entrySet()) {
            K key = e.getKey();
            V value = e.getValue();
            if (value == null) {
                if (!(m.get(key) == null && m.containsKey(key)))
                    return false;
            } else {
                if (!value.equals(m.get(key)))
                    return false;
            }
    }
    • float ,double์„ ์ œ์™ธํ•œ ๊ธฐ๋ณธ ํƒ€์ž… ํ•„๋“œ๋Š” '==' ์—ฐ์‚ฐ์ž๋กœ ๋น„๊ต.
    • ์ฐธ์กฐ ํƒ€์ž… ํ•„๋“œ๋Š” equals ๋ฉ”์„œ๋“œ๋กœ.
    • float์™€ double์€ ๊ฐ๊ฐ ์ •์  ๋ฉ”์„œ๋“œ์ธ Float.compare, Double.compare๋กœ ๋น„๊ตํ•œ๋‹ค. (ํŠน์ˆ˜ํ•œ ๋ถ€๋™ ์†Œ์ˆ˜๊ฐ’ ๋“ฑ์„ ๋‹ค๋ค„์•ผ ํ•จ.)equals๋„ ๊ฐ€๋Šฅํ•˜๋‚˜ ์˜คํ†  ๋ฐ•์‹ฑ์„ ์ˆ˜๋ฐ˜ํ•  ์ˆ˜ ์žˆ์–ด ์„ฑ๋Šฅ์ด ์ข‹์ง€์•Š๋‹ค.
    • null ๊ฐ’์„ ์ •์ƒ ๊ฐ’์œผ๋กœ ์ทจ๊ธ‰ํ•˜๋Š” ์ฐธ์กฐ ํƒ€์ž… ํ•„๋“œ๋Š” Object.equlas(Object, Object)์ •์  ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ž.(NullPointException ๋ฐœ์ƒ ๋ฐฉ์ง€.)

๐Ÿค” ์ฃผ์˜ ์‚ฌํ•ญ

- equals๋ฅผ ์žฌ์ •์˜ ํ•  ๋• hashCode๋„ ๋ฐ˜๋“œ์‹œ ์žฌ์ •์˜ ํ•˜์ž.(์•„์ดํ…œ 11)
- ๋„ˆ๋ฌด ๋ณต์žกํ•˜๊ฒŒ ํ•ด๊ฒฐํ•˜๋ ค ํ•˜์ง€ ๋ง์ž, ํ•„๋“œ์˜ ๋™์น˜์„ฑ๋งŒ ๊ฒ€์‚ฌํ•ด๋„ ๊ทœ์•ฝ์„ ์–ด๋ ต์ง€ ์•Š๊ฒŒ ์ง€ํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.
- Objectํƒ€์ž… ์ด์™ธ์˜ ํƒ€์ž…์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›๋Š” equals ๋ฉ”์„œ๋“œ๋Š” ์„ ์–ธํ•˜์ง€ ๋ง์ž ->์˜ค๋ฒ„๋ผ์ด๋”ฉ์ด ์•„๋‹Œ ์˜ค๋ฒ„๋กœ๋”ฉ.

๐Ÿ”‘ ํ•ต์‹ฌ

  • ๊ผญ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ฉด equals๋ฅผ ์žฌ์ •์˜ ํ•˜์ง€ ์•Š์•„๋„ ์›ํ•˜๋Š” ๋น„๊ต๋ฅผ ์ •ํ™•ํžˆ ์ˆ˜ํ–‰ํ•œ๋‹ค.
  • ์žฌ์ •์˜ํ•ด์•ผ ํ•  ๋•Œ๋Š” ํ•ด๋‹น ํด๋ž˜์Šค์˜ ํ•ต์‹ฌ ํ•„๋“œ๋ฅผ ๋ชจ๋‘ ๋น ์ง์—†์ด ๊ทœ์•ฝ์„ ์ง€์ผœ๊ฐ€๋ฉฐ ๋น„๊ตํ•œ๋‹ค.

๐Ÿ“Œ Item17. ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ์„ฑ์„ ์ตœ์†Œํ™”ํ•˜๋ผ

๋ณ€๊ฒฝ ๊ฐ€๋Šฅ์„ฑ์„ ์ตœ์†Œํ™” ํ•˜๋ผ๋Š” ๊ฒƒ์€ ๋‹ค์‹œ ๋งํ•ด ๋ถˆ๋ณ€ ๊ฐ์ฒด๋กœ ์„ค๊ณ„ํ•˜๋ผ๋Š” ๊ฒƒ์ด๋‹ค. ์ธ์Šคํ„ด์Šค ๋‚ด๋ถ€์˜ ๊ฐ’์„ ์ˆ˜์ •ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ํ•˜๊ณ  ํด๋ž˜์Šค์˜ ์ƒ์†์„ ๋ง‰์•„ ๊ฐ์ฒด๊ฐ€ ์†Œ๋ฉธ๋˜๋Š” ์ˆœ๊ฐ„๊นŒ์ง€ ์ฒ˜์Œ๊ณผ ๋™์ผํ•œ ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ์Œ์„ ๋ณด์žฅํ•œ๋‹ค.
์ด๋Ÿฌํ•œ ๋ถˆ๋ณ€ ๊ฐ์ฒด๋Š” ์‚ฌ์šฉ์„ ์‰ฝ๊ฒŒํ•˜๊ณ , ์˜ค๋ฅ˜ ๋ฐœ์ƒ์˜ ์—ฌ์ง€๋ฅผ ์ค„์—ฌ์ค€๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ๋ถˆ๋ณ€ ๊ฐ์ฒด๋Š” ์–ด๋–ป๊ฒŒ ๋งŒ๋“ค์–ด์•ผ ํ• ๊นŒ?

  • ๐Ÿ‘† ๋ถˆ๋ณ€ ๊ฐ์ฒด์˜ ์„ค๊ณ„

    1. ๊ฐ์ฒด์˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋‹ค.

    ๊ฐ์ฒด ๋‚ด๋ถ€์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋„๋ก ํ•œ๋‹ค.

    2. ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•  ์ˆ˜ ์—†๋„๋ก ํ•œ๋‹ค.

    • ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ๊ฐ์ฒด์˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•œ๋‹ค.
    • final ํด๋ž˜์Šค๋กœ ๋งŒ๋“ค์–ด ์ƒ์†์„ ๋ฐฉ์ง€ํ•œ๋‹ค.
    • ๋ชจ๋“  ์ƒ์„ฑ์ž๋ฅผ private ๋˜๋Š” package-private(default)๋กœ ๋งŒ๋“ค๊ณ  ์ •์  ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

    3. ๋ชจ๋“  ํ•„๋“œ๋ฅผ final ๋กœ ์„ ์–ธํ•œ๋‹ค.

    final ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฒ˜์Œ ์ดˆ๊ธฐํ™” ๋œ ํ›„ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์ง€ ๋ชปํ•˜๋„๋ก ์‹œ์Šคํ…œ์ ์œผ๋กœ ๋ง‰๋Š”๋‹ค.

    4. ๋ชจ๋“  ํ•„๋“œ๋ฅผ private ๋กœ ์„ ์–ธํ•œ๋‹ค.

    ํด๋ผ์ด์–ธํŠธ์—์„œ ์ง์ ‘ ์ ‘๊ทผํ•ด ์ˆ˜์ •ํ•˜๋Š” ์ผ์„ ๋ฐฉ์ง€ํ•œ๋‹ค.

    5. ์ž์‹  ์™ธ์—๋Š” ๋‚ด๋ถ€์˜ ๊ฐ€๋ณ€ ์ปดํฌ๋„ŒํŠธ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋„๋ก ํ•œ๋‹ค.

    • ํด๋ผ์ด์–ธํŠธ์—์„œ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์˜ ์ฐธ์กฐ๋ฅผ ์–ป์–ด์„œ๋„ ์•ˆ๋˜๊ณ , ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ œ๊ณตํ•œ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฅดํ‚ค๋„๋ก ํ•ด๋„ ์•ˆ๋œ๋‹ค.
    • ํ•„๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•  ๋•Œ๋„ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ๋ฐฉ์–ด์  ๋ณต์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค
  • ๐Ÿ‘† ๊ฐ’์˜ ๋ณ€๊ฒฝ

    ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๊ฐ’์˜ ๋ณ€ํ™”๋ฅผ ์–ด๋–ค์‹์œผ๋กœ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋Š”์ง€ ๊ถ๊ธˆ์ ์ด ์ƒ๊ธธ๊ฒƒ์ด๋‹ค. ์•„๋ž˜๋Š” ์˜ˆ์‹œ ์ฝ”๋“œ์ด๋‹ค.

    public final class Point {
        private final int x;
        private final int y;
        
        public Point(final int x, final int y){
            this.x = x;
            this.y = y;
        }
        
        public Point move(final int x, final int y){
            return new Point(this.x + x, this.y + y);
        }
    }  

    ๊ฐ’์˜ ๋ณ€ํ™”๋Š” ๊ณง ์ƒˆ๋กœ์šด ๊ฐ์ฒด์˜ ๋ฐ˜ํ™˜์„ ์˜๋ฏธํ•œ๋‹ค. ๊ธฐ๋ณธ ํƒ€์ž…์˜ Wrapper ํด๋ž˜์Šค์ธ BigInteger ๋“ฑ์ด ์ด์™€ ๊ฐ™์ด ๊ตฌํ˜„๋˜์–ด ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŒจํ„ด์„ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด๋ผ๊ณ  ํ•œ๋‹ค. ์ž์‹ ์˜ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํ•ญ์ƒ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ์‹œ์—์„œ๋Š” ๋™์‚ฌ๋ฅผ ์‚ฌ์šฉํ•˜์˜€์ง€๋งŒ, ๋™์‚ฌ ๋Œ€์‹  ์ „์น˜์‚ฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ช…๋ช… ๊ทœ์น™์„ ๋”ฐ๋ฅด๋Š” ๊ฒƒ์ด ์ข‹๋‹ค(add ๋Œ€์‹  plus์™€ ๊ฐ™์ด)

  • ๐Ÿ‘† ๋ถˆ๋ณ€ ๊ฐ์ฒด์˜ ์žฅ์ 

    • ๋ถˆ๋ณ€ ๊ฐ์ฒด๋Š” ๊ทผ๋ณธ์ ์œผ๋กœ ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•˜๋‹ค.

      ๊ฐ’์ด ํ•ญ์ƒ ๋™์ผํ•˜๊ณ , ๋ณ€๊ฒฝ๊ฐ€๋Šฅ์„ฑ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋™์‹œ์— ์ ‘๊ทผ์ด ์ด๋ฃจ์–ด์ง€๋”๋ผ๋„ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ์ง€ ์•Š๋Š”๋‹ค

    • Map์˜ ํ‚ค๋‚˜ Set๊ณผ ๊ฐ™์€ ์œ ์ผ์„ฑ์„ ๊ฐ€์ง„ ์›์†Œ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ์— ์ข‹๋‹ค.

      ๋ถˆ๋ณ€์„ฑ์ด ํ—ˆ๋ฌผ์–ด์งˆ ๊ฑฑ์ •์„ ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

    • ์ž์ฒด๋กœ ์‹คํŒจ ์›์ž์„ฑ์„ ๊ฐ€์ง„๋‹ค

      ์ƒํƒœ๊ฐ€ ์ ˆ๋Œ€ ๋ณ€ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ถˆ์ผ์น˜ ์ƒํƒœ์— ๋น ์งˆ ์ผ์ด ์—†๋‹ค.

  • ๐Ÿ‘† ๋ถˆ๋ณ€ ๊ฐ์ฒด์˜ ๋‹จ์ 

    • ๊ฐ์ฒด์˜ ์ƒ์„ฑ ๋น„์šฉ.

      • ์ƒ์„ฑ๋น„์šฉ์ด ๊ต‰์žฅํžˆ ํฐ ๊ฐ์ฒด๋ผ๋ฉด ๋งค๋ฒˆ ๋ณ€๊ฒฝ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์ฃผ์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํฐ ๋น„์šฉ์„ ์น˜๋Ÿฌ์•ผํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๐Ÿ”‘ ํ•ต์‹ฌ

    - ํด๋ž˜์Šค๋Š” ๋˜๋„๋ก ๋ถˆ๋ณ€์œผ๋กœ ์„ค๊ณ„ํ•œ๋‹ค.
    - ๋ชจ๋“  ๊ฐ์ฒด๋ฅผ ๋ถˆ๋ณ€์œผ๋กœ ๋งŒ๋“ค ์ˆ˜๋Š” ์—†๋‹ค. ๋ถˆ๋ณ€์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์—†๋Š” ๊ฐ์ฒด๋ผ๋ฉด ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์„ ์ตœ์†Œํ™”ํ•œ๋‹ค.
    - ํ•ฉ๋‹นํ•œ ์ด์œ ๊ฐ€ ์—†๋‹ค๋ฉด ๋ชจ๋“  ํ•„๋“œ๋Š” private final ์ด๋‹ค.
    

๐Ÿ“Œ Item18. ์ƒ์†๋ณด๋‹ค๋Š” ์ปดํฌ์ง€์…˜์„ ์‚ฌ์šฉํ•˜๋ผ

์ƒ์†์€ ๊ฐ์ฒด ์ง€ํ–ฅ์—์„œ ๊ต‰์žฅํžˆ ์ค‘์š”ํ•œ ๊ฐœ๋…์ด์ง€๋งŒ ์ž˜๋ชป ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๋งŽ์€ ๋ถ€์ž‘์šฉ(์บก์Аํ™” ํŒŒ๊ดด ๋“ฑ)์„ ์•ˆ๊ฒจ์ค„ ์ˆ˜ ์žˆ๋‹ค. ์ƒ์†์€ ์™„๋ฒฝํ•œ IS-A ๊ด€๊ณ„์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.(IS-A ๊ด€๊ณ„๋ผ๋„ ์„œ๋กœ ๋‹ค๋ฅธ ํŒจํ‚ค์ง€์—์„œ์˜ ์ƒ์†์€ ํ”ผํ•˜์ž)

  • ๐Ÿ‘† ์ƒ์†์˜ ๋‹จ์ 

    • ์ƒ์œ„ ํด๋ž˜์Šค์— ๋”ฐ๋ผ ํ•˜์œ„ ํด๋ž˜์Šค์˜ ๋™์ž‘ ์ด์ƒ์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค.

      • ์ƒ์œ„ ํด๋ž˜์Šค์˜ ๊ตฌํ˜„์— ๋”ฐ๋ผ ํ•˜์œ„ ํด๋ž˜์Šค์˜ ๋™์ž‘์— ์ด์ƒ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.(์‚ฌ์šฉ์ž๊ฐ€ ์ƒ๊ฐํ•˜์ง€ ๋ชปํ•œ ์ƒ์œ„ ํด๋ž˜์Šค์˜ ์‚ฌ์šฉ ๋ฐฉ์‹)
      • HashSet์„ ์˜ˆ์‹œ๋กœ ๋“ค์–ด๋ณด์ž. ๋‹ค์Œ์€ ์ดˆ๊ธฐ ์ƒ์„ฑ ์ดํ›„์— ๋ช‡๊ฐœ์˜ ์›์†Œ๊ฐ€ ๋”ํ•ด์กŒ๋Š”์ง€ ๊ตฌํ•˜๋Š” myHashSet์˜ ์˜ˆ์‹œ์ด๋‹ค.
        public class myHashSet<E> implements HashSet<E> {
        
                ...
          
          @Override
          public boolean add(E e){
                addCount ++;
                return super.add(e);
          }
        
          @Override
          public boolean addAll(Collection<? extends E> c) {
                addCount += c.size();
                return super.addAll(c);
          }
        }
        ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๋ฉด์„œ addAll๋กœ 3๊ฐœ์˜ ์›์†Œ๋ฅผ ๋”ํ•˜๋ฉด addCount๋Š” 3์ด ๋  ๊ฒƒ์ด๋ผ๊ณ  ๊ธฐ๋Œ€ํ•˜๋ฉด์„œ ๊ตฌํ˜„ํ•˜์˜€์„ ๊ฒƒ์ด๋‹ค.
        ํ•˜์ง€๋งŒ ํ•ด๋‹น ์ฝ”๋“œ์˜ ๊ฒฐ๊ณผ๋Š” 6์ด ๋‚˜์˜จ๋‹ค(3 + 1 + 1 + 1) HashSet์˜ addAll์€ ๋‚ด๋ถ€์ ์œผ๋กœ add๋ฅผ ํ˜ธ์ถœํ•˜๋„๋ก ๊ตฌํ˜„๋˜์–ด ์žˆ๋‹ค.
        ๋•Œ๋ฌธ์— size์ธ 3์„ ๋”ํ•˜๊ณ  add ๋ฉ”์„œ๋“œ์—์„œ ๊ฐ๊ฐ 1์”ฉ 3๋ฒˆ์„ ๋”ํ•ด addCount์˜ ๊ฐ’์€ 6์ด ๋œ๋‹ค.

        ์ƒ์†์˜ ์‚ฌ์šฉ์€ ์ƒ์œ„ ํด๋ž˜์Šค์˜ ์˜ํ–ฅ์„ ๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— ์ƒ๊ฐ์ง€ ๋ชปํ•œ ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

    • ์ƒ์†์„ ์ด์šฉํ•œ ๋ฐฉ๋ฒ•์—์„œ๋Š” ๋ณด์•ˆ์˜ ์ทจ์•ฝ์ ์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜๋„ ์žˆ๋‹ค.

      • ์ปฌ๋ ‰์…˜์— ๋ณด์•ˆ์„ ์œ„ํ•ด ์กฐ๊ฑด์„ ๊ฒ€์‚ฌํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. ์šฐ๋ฆฌ๋Š” ์ปฌ๋ ‰์…˜์„ ์ƒ์†๋ฐ›์•„ ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ๋ฉ”์„œ๋“œ๋ฅผ ๋ชจ๋‘ ์žฌ์ •์˜ํ•ด ์กฐ๊ฑด์„ ๊ฒ€์‚ฌํ•˜๋Š” ๋กœ์ง์„ ์ถ”๊ฐ€ํ•  ๊ฒƒ์ด๋‹ค.
      • ํ•˜์ง€๋งŒ ์ƒ์œ„ ํด๋ž˜์Šค(์ปฌ๋ ‰์…˜)์— ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ๊ฐ€ ์ถ”๊ฐ€ ๋˜์—ˆ์„ ๋•Œ, ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ์ด๋ฅผ ์žฌ์ •์˜ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, ๋ณด์•ˆ์— ์ทจ์•ฝ์ ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.
      • ๐Ÿค” ์žฌ์ •์˜ ๋ง๊ณ  ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ์•ˆ๋˜๋‚˜์š”?

        ๋ณด๋‹ค ์•ˆ์ „ํ•˜์ง€๋งŒ ์šฐ์—ฐํžˆ ์ƒ์œ„ ํด๋ž˜์Šค์— ๋‚ด๊ฐ€ ์ •์˜ํ•œ ๋ฉ”์„œ๋“œ์™€ ์ผ์น˜ํ•˜๋Š” ์‹œ๊ทธ๋‹ˆ์ฒ˜์˜ ๋‹ค๋ฅธ ๋ฐ˜ํ™˜ํƒ€์ž… ๋ฉ”์„œ๋“œ๊ฐ€ ์ถ”๊ฐ€๋œ๋‹ค๋ฉด? ์ž˜ ๋Œ์•„๊ฐ€๋˜ ํ”„๋กœ๊ทธ๋žจ์— ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒƒ์ด๋‹ค.

  • ๐Ÿค” ๊ทธ๋ž˜์„œ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•˜๋‚˜์š”?

    ์ด๋Ÿฌํ•œ ๋ฌธ์ œ์ ๋“ค์„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ์„ค๊ณ„๊ฐ€ ์ปดํฌ์ง€์…˜(composition) ์ด๋‹ค. ์ปดํฌ์ง€์…˜ ์—์„œ๋Š” ๊ธฐ์กด ํด๋ž˜์Šค๊ฐ€ ์ƒˆ๋กœ์šด ํด๋ž˜์Šค์˜ ๊ตฌ์„ฑ์š”์†Œ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.
    ์ƒˆ๋กœ์šด ์ปดํฌ์ง€์…˜ ํด๋ž˜์Šค๋Š” ๊ธฐ์กด์˜ ํด๋ž˜์Šค(์œ„ ์˜ˆ์‹œ์—์„œ์˜ HashSet๊ณผ ๊ฐ™์€)์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค.
    ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์ „๋‹ฌ ๋ฉ”์„œ๋“œ(Forwarding method) ๋ผ๊ณ  ํ•œ๋‹ค.

  • ์ „๋‹ฌ ํด๋ž˜์Šค(Composition)

    public class ForwardingSet<E> implements Set<E> {
        private final Set<E> set;
        
        // Set์˜ ๋ฉ”์„œ๋“œ๋“ค ๊ตฌํ˜„, set ์ธ์Šคํ„ด์Šค ์—๊ฒŒ ์œ„์ž„ํ•œ๋‹ค. ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๋“ค๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ตฌํ˜„๋œ๋‹ค.
        public boolean add(E e){
            return s.add(e);
        }
    }
  • Wrapper ํด๋ž˜์Šค

    public class mySet<E> implements ForwardingSet<E> {
      
      public mySet(Set<E> e){
          super(e);
      }
      
      @Override
      public boolean add(E e){
            addCount ++;
            return super.add(e);
      }
    
      @Override
      public boolean addAll(Collection<? extends E> c) {
            addCount += c.size();
            return super.addAll(c);
      }
    }

    ์œ„์™€ ๊ฐ™์€ ๊ตฌํ˜„์—์„œ๋Š” mySet์˜ ์ƒ์œ„ ํด๋ž˜์Šค์ธ ForwardingSet์˜ addAll์„ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๊ณ , ForwardingSet์˜ addAll์€ ์ž์‹ ์ด ์ธ์Šคํ„ด์Šค๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” set์˜ addAll์„ ํ˜ธ์ถœํ•˜๊ธฐ ๋•Œ๋ฌธ์— mySet์˜ addCount์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š”๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ƒ์œ„ ํด๋ž˜์Šค์—์„œ ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ๊ฐ€ ์ƒ์„ฑ๋˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝ๋˜์–ด๋„ ์˜ํ–ฅ์„ ๋ฐ›์ง€๋„ ์•Š๋Š”๋‹ค.
    ๋˜ํ•œ, Set ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ๋•Œ๋ฌธ์— HashSet, TreeSet ๋“ฑ ๋‹ค์–‘ํ•œ ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.
    ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„๋œ ํด๋ž˜์Šค๋ฅผ ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ์‹ธ๊ณ  ์žˆ๋‹ค๊ณ  ํ•˜์—ฌ ๋ž˜ํผ ํด๋ž˜์Šค ๋ผ๊ณ  ํ•˜๊ณ , ๊ธฐ์กด ํด๋ž˜์Šค์— ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ๋ง ๋ถ™์ธ๋‹ค๊ณ  ํ•˜์—ฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด ์ด๋ผ๊ณ  ํ•œ๋‹ค.

๐Ÿ™‹โ€โ™‚๏ธWrapper ํด๋ž˜์Šค์—๋Š” ๋‹จ์ ์ด ์—†๋‚˜์š”?

Wrapper ํด๋ž˜์Šค๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ฝœ๋ฐฑ ํ”„๋ ˆ์ž„ ์›Œํฌ์™€ ์ž˜ ๋งž์ง€ ์•Š๋Š”๋‹ค. ์ž์‹ ์˜ ์ฐธ์กฐ๋ฅผ ๋‹ค๋ฅธ ๊ฐ์ฒด์—๊ฒŒ ๋„˜๊ฒจ์ฃผ์–ด ์‚ฌ์šฉํ•˜๋„๋ก ํ•˜๋Š”๋ฐ, ๋‚ด๋ถ€์—์„œ๋Š” ์ด๋ฅผ ๊ฐ์‹ธ๊ณ  ์žˆ๋Š” Wrapper ํด๋ž˜์Šค์˜ ์กด์žฌ๋ฅผ ๋ชจ๋ฅด๋‹ˆ ์ž์‹ ์˜ ์ฐธ์กฐ๋ฅผ ๋„˜๊ธฐ๊ฒŒ ๋  ์ˆ˜ ์žˆ๋‹ค.

์ปดํฌ์ง€์…˜ ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ ์ปดํฌ์ง€์…˜ ํด๋ž˜์Šค๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์‚ฌ์šฉํ•  ์ธ์Šคํ„ด์Šค ๊ฐ์ฒด๋ฅผ ๋„˜๊ธฐ๋Š” ๊ฒฝ์šฐ. ๋ž˜ํผ๊ฐ€ ์•„๋‹Œ ๋‚ด๋ถ€ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค.

๐Ÿ“Œ Item28. ๋ฐฐ์—ด๋ณด๋‹ค๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ผ

๐Ÿ‘† ํ•˜์œ„ํด๋ž˜์Šค ๋ฐฐ์—ด์€ ์ƒ์œ„ํด๋ž˜์Šค ๋ฐฐ์—ด๊ณผ๋„ ์ƒ,ํ•˜์œ„ ๊ด€๊ณ„๋ฅผ ๊ฐ€์ง„๋‹ค.(๊ณต๋ณ€) ๊ทธ๋Ÿฌ๋‚˜ ๋ฆฌ์ŠคํŠธ๋Š” ์ƒ์œ„, ํ•˜์œ„ ํƒ€์ž…์˜ ๊ด€๊ณ„๊ฐ€ ์•„๋‹ˆ๋‹ค(๋ถˆ๊ณต๋ณ€).
๋ถˆ๊ณต๋ณ€์ด ์™œ ์žฅ์ ์ธ์ง€ ์•Œ์•„๋ณด์ž.

์˜ˆ๋ฅผ ๋“ค์–ด Object[] ์™€ Long[] ์ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์žˆ๋‹ค.

Object[] objectArray = new Long[1]; // Long์€ Object์˜ ํ•˜์œ„ํƒ€์ž… ์ด๋ฏ€๋กœ ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.

objectArray[0] = "String~" // Long[] ์—๋Š” String ์„ ๋„ฃ์„ ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ArrayStoreException์ด ๋ฐœ์ƒํ•œ๋‹ค.

์œ„์˜ ์ƒํ™ฉ์—์„œ์˜ ๋ฌธ์ œ์ ์€ ์ปดํŒŒ์ผ ํƒ€์ž„์ด ์•„๋‹Œ ๋Ÿฐํƒ€์ž„ ์‹œ์ ์— ์—๋Ÿฌ๋ฅผ ๋ฐœ๊ฒฌํ•˜๊ฒŒ ๋œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

๋‹ค์Œ์œผ๋กœ List๋ฅผ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ์˜ ์ƒํ™ฉ์„ ์‚ดํŽด๋ณด์ž.

List<Object> objects = new ArrayList<Long>(); // ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

๋ฆฌ์ŠคํŠธ์—์„œ๋Š” ๋ฐฐ์—ด๊ณผ ๋‹ฌ๋ฆฌ ์›์†Œ๋ฅผ ๋„ฃ์„ ๋•Œ(๋Ÿฐํƒ€์ž„)๊ฐ€ ์•„๋‹Œ ์ปดํŒŒ์ผ ์‹œ์ ์— ์—๋Ÿฌ๋ฅผ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ๋‹ค.
๋‹น์—ฐํžˆ ์ปดํŒŒ์ผ ์‹œ์ ์— ์ด๋ฅผ ์•Œ์•„์ฑŒ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์€ ํฐ ์ด์ ์„ ๊ฐ€์ง„๋‹ค.


๐Ÿ‘† ๋‘ ๋ฒˆ์จฐ๋กœ ๋ฐฐ์—ด์€ ์‹ค์ฒดํ™”(reify) ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ œ๋„ค๋ฆญ๊ณผ ์ž˜ ์–ด์šฐ๋Ÿฌ์ง€์ง€ ๋ชปํ•œ๋‹ค.
์‹ค์ฒดํ™” ๋œ๋‹ค๋Š” ๊ฒƒ์€ ๋Ÿฐํƒ€์ž„ ์‹œ์ ์—๋„ ์ž์‹ ์ด ๋‹ด๊ธฐ๋กœ ํ•œ ์›์†Œ์˜ ํƒ€์ž…์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.(Long[] ์—์„œ Long์ด๋ผ๋Š” ํƒ€์ž…์„ ๋ฐ›์„ ๊ฒƒ์„ ๋Ÿฐํƒ€์ž„์—๋„ ์•Œ๊ณ  ์žˆ์Œ)
๊ทธ๋Ÿฌ๋‚˜, ์ œ๋„ค๋ฆญ์€ ์ปดํŒŒ์ผ ์‹œ์ ์— ํƒ€์ž…์„ ๊ฒ€์‚ฌํ•˜๊ณ , ๋Ÿฐํƒ€์ž„์—๋Š” ์ด๋ฅผ ์†Œ๊ฑฐํ•˜์—ฌ ์•Œ ์ˆ˜ ์—†๊ฒŒ ๋œ๋‹ค. ์ด๋Ÿฌํ•œ ํŠน์ง• ๋•Œ๋ฌธ์— ๋ฐฐ์—ด๊ณผ ์ œ๋„ค๋ฆญ์€ ์ž˜ ๋งž์ง€ ์•Š๋Š”๋‹ค.

๋ฐฐ์—ด์€ new List[], new List[], new E[] ์™€ ๊ฐ™์€ ์‹์˜ ์ƒ์„ฑ์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.(์ปดํŒŒ์ผ ์—๋Ÿฌ) ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•œ ํ˜•๋ณ€ํ™˜ ์ฝ”๋“œ์—์„œ ClassCastException์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.(ํƒ€์ž… ์„ธ์ดํ”„ ํ•˜์ง€ ์•Š๋‹ค)

์•„๋ž˜ ์ฝ”๋“œ๋Š” ์ œ๋„ค๋ฆญ ๋ฐฐ์—ด์˜ ์ƒ์„ฑ์ด ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ์ž‘์„ฑํ•œ ์ฝ”๋“œ์ด๋‹ค.

List<String>[] strings = new List<String>[1];
List<Integer> ints = List.of(10);
Object[] objects = strings // ๋ฐฐ์—ด์€ ๊ณต๋ณ€์ด๊ณ , String์€ Object์˜ ํ•˜์œ„ ํด๋ž˜์Šค์ด๋ฏ€๋กœ ๊ฐ€๋Šฅํ•˜๋‹ค.
Object[0] = ints // ์ œ๋„ค๋ฆญ์€ ํƒ€์ž…์ด ์†Œ๊ฑฐ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋Šฅํ•˜๋‹ค.
String s = strings[0].get(0) // ClassCastException ๋ฐœ์ƒ

strings[0] ์—๋Š” 4๋ฒˆ์งธ ์ค„์— ์˜ํ•ด Integer ํƒ€์ž…์˜ ๊ฐ’์ด ์ €์žฅ๋˜์–ด ์žˆ๋Š” ์ƒํƒœ๋‹ค. ๋•Œ๋ฌธ์— ๊ฐ’์„ ๊บผ๋‚ด String ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ ํ•  ๋•Œ ClassCastException์ด ๋ฐœ์ƒํ•œ๋‹ค.
์ด๋Ÿฌํ•œ ์ƒํ™ฉ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ œ๋„ค๋ฆญ ๋ฐฐ์—ด์ด ์ƒ์„ฑ๋˜์ง€ ๋ชปํ•˜๋„๋ก ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๊ฒƒ์ด๋‹ค.

E[] ๋ฐฐ์—ด๋กœ ํ˜•๋ณ€ํ™˜ํ•  ๋•Œ ์ œ๋„ค๋ฆญ ๋ฐฐ์—ด ์ƒ์„ฑ ์˜ค๋ฅ˜๋‚˜ ๋น„๊ฒ€์‚ฌ ํ˜•๋ณ€ํ™˜ ๊ฒฝ๊ณ ๊ฐ€ ๋œจ๋Š” ๊ฒฝ์šฐ๋Š” List๋กœ ๋ณ€๊ฒฝํ•ด์ฃผ๋ฉด ํ•ด๊ฒฐ๋œ๋‹ค.
๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ์—์„œ๋Š” ๋น„๊ฒ€์‚ฌ ํ˜•๋ณ€ํ™˜ ๊ฒฝ๊ณ ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.(@SafeVarargs๋กœ ๊ฒฝ๊ณ ๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค.)

public class Chooser<T> {
    private final T[] choices;
    
    public Chooser(Collection<T> choices) {
        this.choices = (T[]) choices.toArray(); // Object[]์ด๊ธฐ ๋•Œ๋ฌธ์— T[]๋กœ ํ˜•๋ณ€ํ™˜์„ ํ•ด์ฃผ์–ด์•ผํ•œ๋‹ค. 
    }
    
        ...
}

์œ„์˜ ์ฝ”๋“œ์—์„œ๋Š” Object[] -> T[] ๋กœ์˜ ํ˜•๋ณ€ํ™˜์ด ์ด๋ฃจ์–ด์ง€๊ฒŒ ๋˜๊ณ , T๊ฐ€ ๋ฌด์Šจํƒ€์ž…์ธ์ง€ ์•Œ ์ˆ˜ ์—†๊ธฐ ๋–„๋ฌธ์— ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋Ÿฐํ„ฐ์ž„์—์„œ ์•ˆ์ „์„ ๋ณด์žฅํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.
(warning: [unchecked] unchecked cast ...)
๊ฒฝ๊ณ ์˜ ์›์ธ์„ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” T[]๋ฅผ List๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด ๋œ๋‹ค. ์„ฑ๋Šฅ์—์„œ๋Š” ์กฐ๊ธˆ ๋” ๋А๋ฆด ์ˆ˜ ์žˆ์ง€๋งŒ ๋Ÿฐํƒ€์ž„์—์„œ ClassCastException์ด ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ถฉ๋ถ„ํ•œ ์ด์ ์„ ๊ฐ€์ง„๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“Œ Item32. ์ œ๋„ค๋ฆญ๊ณผ ๊ฐ€๋ณ€์ธ์ˆ˜๋ฅผ ํ•จ๊ป˜ ์“ธ ๋•Œ๋Š” ์‹ ์ค‘ํ•˜๋ผ

๊ฐ€๋ณ€์ธ์ˆ˜๋Š” ๋ฉ”์„œ๋“œ์˜ ์ธ์ˆ˜์˜ ๊ฐœ์ˆ˜๋ฅผ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค. ํ•˜์ง€๋งŒ ์ธ์ˆ˜๋“ค์„ ๋‹ด๊ธฐ ์œ„ํ•ด ๋ฐฐ์—ด์ด ๋งŒ๋“ค์–ด์ง€๊ณ , ์ด ๋•Œ๋ฌธ์— ํ—ˆ์ ์ด ์ƒ๊ธฐ๊ฒŒ ๋œ๋‹ค.
varargs ๋งค๊ฐœ๋ณ€์ˆ˜์— ์ œ๋„ค๋ฆญ์ด๋‚˜, ๋งค๊ฐœ ๋ณ€์ˆ˜ํ™” ํƒ€์ž…(List๊ณผ ๊ฐ™์€)์ด ํฌํ•จ๋˜๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ด๋ฅผ ํŒŒ์•…ํ•˜๊ธฐ๋Š” ์‰ฝ์ง€ ์•Š๋‹ค.

๋จผ์ € ๋ฐฐ์—ด์— ์กฐ์ž‘์„ ๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ์ด๋‹ค.

void method(List<String>... stringLists) {
    Object[] objects = stringLists
    List<Integer> intList = List.of(10);
    objects[0] = intList;
    String s = stringLists[0].get(0) // ClassCastException ๋ฐœ์ƒ.
}

์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ž๋™์œผ๋กœ ํ˜•๋ณ€ํ™˜์„ ์‹œ๋„ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋œ๋‹ค.
์ด์ฒ˜๋Ÿผ ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ๋ณด์žฅํ•  ์ˆ˜ ์—†์Œ์—๋„ ๊ฐ€๋ณ€์ธ์ˆ˜์—์„œ ์ œ๋„ค๋ฆญ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ฒŒ ํ—ˆ์šฉํ•œ ์ด์œ ๋Š” ์‹ค๋ฌด์—์„œ ์œ ์šฉํ•˜๊ฒŒ ์“ธ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
Arrays.asList(T... a), Collections.addAll() ๋“ฑ์˜ ๋ฉ”์„œ๋“œ๋“ค์ด ์ž๋ฐ” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋ฉ”์„œ๋“œ๋“ค์ด ์ด์— ํ•ด๋‹นํ•œ๋‹ค.

์ œ๋„ค๋ฆญ ๊ฐ€๋ณ€์ธ์ˆ˜๋Š” ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ๋ณด์žฅํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๊ฒฝ๊ณ ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด๋ฅผ ์ˆจ๊ธธ ์ˆ˜ ์žˆ๋„๋ก Java7 ์—์„œ๋ถ€ํ„ฐ๋Š” @SafeVarargs๋ผ๋Š”
์• ๋…ธํ…Œ์ด์…˜์„ ์ง€์›ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ํ•ด๋‹น ์• ๋…ธํ…Œ์ด์…˜์€ ๋ฉ”์„œ๋“œ๊ฐ€ ์•ˆ์ „ํ•˜๋‹ค๋Š” ๊ฒƒ์ด ํ™•์‹คํ•  ๋•Œ๋งŒ ์„ ์–ธํ•ด์•ผํ•œ๋‹ค.

๋ฉ”์„œ๋“œ๊ฐ€ ์•ˆ์ „ํ•œ์ง€ ์–ด๋–ป๊ฒŒ ํ™•์ธํ•ด๋ณผ ์ˆ˜ ์žˆ์„๊นŒ?
๊ฐ€๋ณ€์ธ์ˆ˜๋ฅผ ๋‹ด์€ ๋ฐฐ์—ด์ด ๋งŒ๋“ค์–ด์ง€๊ณ , ํ•ด๋‹น ๋ฐฐ์—ด์— ์•„๋ฌด๊ฒƒ๋„ ์ €์žฅํ•˜์ง€ ์•Š๊ณ , ๋ฐฐ์—ด์˜ ์ฐธ์กฐ๊ฐ€ ๋ฐ–์œผ๋กœ ๋…ธ์ถœ๋˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์•ˆ์ „ํ•˜๋‹ค๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.
์ฆ‰ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์›๋ž˜์˜ ๋ชฉ์ ๋Œ€๋กœ ์ธ์ˆ˜๋“ค์„ ์ „๋‹ฌํ•˜๋Š” ์—ญํ• ๋งŒ ํ•œ๋‹ค๋Š” ์ด์•ผ๊ธฐ์ด๋‹ค.

์˜ˆ๋ฅผ ์ด์ „์— ๋“ค์—ˆ๋˜ ์˜ˆ์‹œ์— ๋”ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ ๋˜ํ•œ ์•ˆ์ „ํ•˜์ง€ ์•Š๋‹ค.

static <T> T[] convertToArray(T a, T b) {
    return toArray(a, b);
    }

static <T> T[] toArray(T... args) {
    return args;
}

๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ์—์„œ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” toArray์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋“ค์„ ๋‹ด์„ ๋ฐฐ์—ด์„ Object[]๋กœ ์ƒ์„ฑํ•œ๋‹ค. ๋ชจ๋“  ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ์ตœ์†Œํ•œ์˜ ํƒ€์ž…์ด Object ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
๋•Œ๋ฌธ์—, ์ด๋ฅผ ์‚ฌ์šฉํ• ๋•Œ String ์ด ๋ฐ˜ํ™˜๋  ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ•˜๊ณ  String[] strs = convertToArray("aaa", "bbb")์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ClassCastException ์ด ๋ฐœ์ƒํ•œ๋‹ค.

์œ„์˜ ์˜ˆ์‹œ๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฐฐ์—ด์„ ์กฐ์ž‘ํ•˜์ง€ ์•Š์•˜์ง€๋งŒ, ํ•ด๋‹น ๋ฐฐ์—ด์˜ ์ฐธ์กฐ๊ฐ€ ๋…ธ์ถœ๋˜์–ด ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๊ฐ€ ์ด๋ฅผ ์ ‘๊ทผํ•˜๋„๋ก ํ—ˆ์šฉํ•˜์—ฌ ๋ฐœ์ƒํ•œ ๋ฌธ์ œ์ ์ด๋‹ค.
์ด๋Ÿฌํ•œ ๋ฐฐ์—ด์˜ ์ฐธ์กฐ์—์„œ @SafeVarargs๋กœ ์•ˆ์ „์„ฑ์ด ๋ณด์žฅ๋œ ๋ฉ”์„œ๋“œ๋‚˜, ๋ฐฐ์—ด์— ์กฐ์ž‘์„ ๊ฐ€ํ•˜์ง€ ์•Š๋Š” ์ผ๋ฐ˜ ๋ฉ”์„œ๋“œ์— ๋„˜๊ธฐ๋Š” ๊ฒƒ์€ ์•ˆ์ „ํ•˜๋‹ค.(varargs๋ฅผ ๋ฐ›์ง€ ์•Š๋Š”)

๋ฉ”์„œ๋“œ์˜ ์•ˆ์ „์„ฑ์„ ๋ณด์žฅํ•˜๋Š” ๋ฐฉ๋ฒ• ์ด์™ธ์˜ ๋ฐฉ๋ฒ•์ด ํ•œ๊ฐ€์ง€ ๋” ์žˆ๋‹ค.
Varargs๋ฅผ List๋กœ ๋Œ€์ฒดํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

static <T> List<T> flatten(List<List<? extends T>> lists) {
    List<T> result = new ArrayList<>();
    
    for(List<? extends T> list : lists){
        result.addAll(list);
    }
    return result;
}

๋งค๊ฐœ๋ณ€์ˆ˜ํ™” ํƒ€์ž…๋„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋„๋ก List<List<>> ๋กœ ์ธ์ˆ˜๋ฅผ ๋ฐ›๋Š”๋‹ค. ์ฝ”๋“œ๋Š” ์กฐ๊ธˆ ์ง€์ €๋ถ„ํ•ด์ง€์ง€๋งŒ @SafeVarargs ์—†์ด๋„ ํƒ€์ž… ์•ˆ์ „ํ•œ ๋ฉ”์„œ๋“œ๊ฐ€ ๋œ๋‹ค. ์ด์ „์— ๋ณด์•˜๋˜ toArray() ๋ฉ”์„œ๋“œ ๋˜ํ•œ List ์—์„œ ์ œ๊ณตํ•˜๋Š” ์ •์  ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ์ธ List.of()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํƒ€์ž… ์–ธ์ „ํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.(@SafeVarargs ๋ฉ”์„œ๋“œ์ด๋‹ค)

๐Ÿ“Œ Item44. ํ‘œ์ค€ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ผ

์ž๋ฐ”์—์„œ ๋žŒ๋‹ค๋ฅผ ์ง€์›ํ•˜๊ธฐ ์ „์—๋Š” ๊ธฐ๋ณธ ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•ด ์›ํ•˜๋Š” ๋™์ž‘์œผ๋กœ ์žฌ๊ตฌ์„ฑํ•˜๋Š” ํ…œํ”Œ๋ฆฟ ๋ฉ”์„œ๋“œ ํŒจํ„ด์ด ๋งŽ์ด ์‚ฌ์šฉ๋˜์—ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด LinkedHashMap์˜ removeEldestEntry๋ฅผ ์ƒ๊ฐํ•ด๋ณด์ž.
LinkedHashMap์€ LRU ์บ์‹œ์—๋„ ์‚ฌ์šฉ๋˜๋Š” ์ž๋ฃŒ ๊ตฌ์กฐ๋กœ, removeEledestEntry ๋ฅผ ์žฌ์ •์˜ํ•˜์—ฌ ์ตœ๋Œ€ ์ €์žฅํ•  ์ˆ˜๋ฅผ ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

protected boolean removeEldestEntry(Map.Entry<K,V> eldest){
    return size() > 100; 
}

ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋Š” ์›๋ž˜๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ false๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ์ •์˜๋˜์–ด ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ์žฌ์ •์˜ํ•˜์—ฌ ์ž์‹ ์˜ ์ƒํ™ฉ์— ๋งž๊ฒŒ ๋ฐ˜ํ™˜๊ฐ’์„ ์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค. true๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋˜๋ฉด
๊ฐ€์žฅ ์˜ค๋ž˜๋œ ๋ฐ์ดํ„ฐ(HEAD)๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค.(put ๋ฉ”์„œ๋“œ์—์„œ ์ด๋ฅผ ํ˜ธ์ถœํ•จ)

์œ„์˜ ๊ธฐ๋Šฅ์„ ํ˜„๋Œ€์ ์œผ๋กœ ํ’€์–ด๋‚ด๋ฉด ๋™์ผํ•œ ํšจ๊ณผ์˜ ํ•จ์ˆ˜ ๊ฐ์ฒด๋ฅผ ๋ฐ›๋Š” ์ •์  ํŒฉํ„ฐ๋ฆฌ๋‚˜, ์ƒ์„ฑ์ž๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ฐฉ๋ฒ•์ผ ๊ฒƒ์ด๋‹ค.
๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๋žŒ๋‹ค๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ •์˜ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

@FunctionalInterface
public interface EldestEntryRemovalFunction<K,V> {
    boolean remove(Map<K,V> map, Map.Entry<K,V> eldest);
}

ํ•ด๋‹น ํ•จ์ˆ˜ํ˜• ๊ฐ์ฒด๋ฅผ LinkedHashMap์˜ ์ƒ์„ฑ์ž๋‚˜, ์ •์  ํŒฉํ„ฐ๋ฆฌ๋ฅผ ์ด์šฉํ•ด์„œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ดํŽด๋ณด๋ฉด, boolean ํƒ€์ž…์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ Map<K,V>, Map.Entry<K,V>๋ฅผ ๋ฐ›๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค.
์ž๋ฐ”์—์„œ๋Š” ํ•ด๋‹น ํ˜•์‹์˜ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์ด๋ฏธ ์ค€๋น„๋˜์–ด ์žˆ๋‹ค.(BiPredicate<Map<K,V>,Map.Entry<K,V>>)
์ด๋ ‡๋“ฏ ์ž๋ฐ”์—๋Š” ๋Œ€๋ถ€๋ถ„์˜ ํ‘œ์ค€ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์ด๋ฏธ ๋งŒ๋“ค์–ด์ ธ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์›ฌ๋งŒํ•œ ๋žŒ๋‹ค์‹์€ ์ง์ ‘ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

java.util.function ํŒจํ‚ค์ง€์— ์žˆ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ด 43๊ฐœ์ด๋‹ค. ํ•˜์ง€๋งŒ ์ด๋ฅผ ๋ชจ๋‘ ์™ธ์šธ ํ•„์š”๋Š” ํž˜๋“ค๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๋ณธ ์ธํ„ฐํŽ˜์ด์Šค์ธ
๋ช‡๊ฐ€์ง€๋งŒ์„ ๊ธฐ์–ตํ•˜๋ฉด, ๋‚˜๋จธ์ง€๋Š” ์ด๋กœ๋ถ€ํ„ฐ ํŒŒ์ƒ๋˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋“ค์ด๋‹ค.

์ธํ„ฐํŽ˜์ด์Šค ์‹œ๊ทธ๋‹ˆ์ฒ˜ ์˜ˆ์‹œ ์„ค๋ช…
UnaryOperator<T> T apply(T t) String::toLowerCase ์ธ์ˆ˜ 1๊ฐœ๋ฅผ ๋ฐ›์•„ ๋™์ผ ํƒ€์ž…์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
BinaryOperator<T> T apply(T t) BigInteger::add ๋™์ผ ํƒ€์ž…์˜ ์ธ์ˆ˜ 2๊ฐœ๋ฅผ ๋ฐ›์•„ ๋™์ผ ํƒ€์ž…์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
Predicate<T> boolean test(T t) Collection::isEmpty ์ธ์ˆ˜ 1๊ฐœ๋ฅผ ๋ฐ›์•„ boolean ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
Function<T,R> R apply(T t) Array::asList ์ธ์ˆ˜ 1๊ฐœ(T)๋ฅผ ๋ฐ›์•„ ๋‹ค๋ฅธ ํƒ€์ž…(R)์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
Supplier<T> T get() Instant::now ์ธ์ˆ˜๋ฅผ ๋ฐ›์ง€ ์•Š๊ณ  ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.(์ œ๊ณตํ•œ๋‹ค)
Consumer<T> void accept(T t) System.out::println ์ธ์ˆ˜ 1๊ฐœ๋ฅผ ๋ฐ›์ง€๋งŒ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๋Š”๋‹ค.(void, ์†Œ๋น„ํ•œ๋‹ค)
Runnable void run() ์ธ์ˆ˜๋„ ๋ฐ›์ง€์•Š๊ณ  ๋ฐ˜ํ™˜๊ฐ’๋„ ์—†๋‹ค. ๋ง ๊ทธ๋Œ€๋กœ ์‹คํ–‰.
Callable V call() ์ธ์ˆ˜๋ฅผ ๋ฐ›์ง€ ์•Š๊ณ  ๋ฐ˜ํ™˜๋งŒ ํ•œ๋‹ค. Supplier์™€ ๋™์ผ, ๊ทธ์ € ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ์—์„œ ์˜๋ฏธ๋ฅผ ๋ช…ํ™•ํ•˜๊ธฐ ์œ„ํ•ด ๋“ฑ์žฅํ•œ ๊ฐœ๋….

๋‚˜๋จธ์ง€ ์ธํ„ฐํŽ˜์ด์Šค๋“ค์€ ์œ„์˜ ์ธํ„ฐํŽ˜์ด์Šค์—์„œ ์กฐ๊ธˆ ๋” ํŠนํ™”๋œ ์ธํ„ฐํŽ˜์ด์Šค๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.

BiFunction, BiPredicate, BiConsumer ์ฒ˜๋Ÿผ ์ธ์ˆ˜๋ฅผ 2๊ฐœ ๋ฐ›๋Š” ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์กด์žฌํ•˜๊ณ ,
IntPredicate, LongPredicate, DoublePredicate ... ์ฒ˜๋Ÿผ Int, Long, Double ํƒ€์ž…์„ ์ธ์ˆ˜๋กœ ๋ฐ›์Œ์„ ๋” ๋ช…ํ™•ํžˆ ํ•˜๊ฑฐ๋‚˜,
IntToDoubleFunction, IntFunction<R>, toIntFunction<T> ์™€ ๊ฐ™์ด ์ธ์ˆ˜, ๋ฆฌํ„ด ํƒ€์ž…์„ ๋ช…ํ™•ํžˆ ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋“ค์ด ์กด์žฌํ•œ๋‹ค.
๋•Œ๋ฌธ์— ํŠน์ • ํƒ€์ž…์„ ๋ฐ›๋Š”๊ฒƒ์ด ํ™•์‹คํ•˜๋‹ค๋ฉด ๊ธฐ๋ณธํ˜• ํŠนํ™” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

์ž๋ฐ”์—์„œ ๋ฏธ๋ฆฌ ์ค€๋น„ํ•ด๋‘” ํ‘œ์ค€ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค ๋ง๊ณ  ์ง์ ‘ ๋งŒ๋“ ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์‚ฌํ•ญ์— ํ•ด๋‹นํ•˜๋Š”์ง€ ํ™•์ธํ•ด ๋ณด์ž.

  • ์ž์ฃผ ์“ฐ์ด๋ฉฐ, ์ด๋ฆ„ ์ž์ฒด๊ฐ€ ์šฉ๋„๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ์„ค๋ช….
  • ๋ฐ˜๋“œ์‹œ ๋”ฐ๋ผ์•ผํ•˜๋Š” ๊ทœ์•ฝ์ด ์กด์žฌํ•œ๋‹ค.
  • ์œ ์šฉํ•œ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

์ปค์Šคํ…€ํ•œ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค๋•Œ์—๋Š” ํ•ญ์ƒ @FunctionalInterface ์• ๋„ˆํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด ์‹ค์ˆ˜๋กœ ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ์ผ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ํ•˜์ž.

๋งˆ์ง€๋ง‰์œผ๋กœ ์„œ๋กœ ๋‹ค๋ฅธ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฐ™์€ ์œ„์น˜์˜ ์ธ์ˆ˜๋กœ ๋ฐ›๋Š” ๋ฉ”์„œ๋“œ๋“ค์„ ๋‹ค์ค‘ ์ •์˜ํ•˜๋Š” ๊ฒƒ์— ์ฃผ์˜ํ•˜์ž.
(ExecutorService์˜ submit ์ฒ˜๋Ÿผ, Callable<T>, Runnable์ด ๋‹ค์ค‘ ์ •์˜ ๋˜์–ด์žˆ๋‹ค.) ์ด๋Š” ์‚ฌ์šฉํ•˜๋Š” ์ด๋กœ ํ•˜์—ฌ๊ธˆ ๋ชจํ˜ธํ•จ์„ ์•ˆ๊ฒจ์ค€๋‹ค.

๐Ÿ“Œ Item45. ์ŠคํŠธ๋ฆผ์€ ์ฃผ์˜ํ•ด์„œ ์‚ฌ์šฉํ•˜๋ผ.

์ŠคํŠธ๋ฆผ์€ ํ˜ธ์ถœ์„ ์—ฐ๊ฒฐํ•˜์—ฌ ๋‹จ ํ•˜๋‚˜์˜ ํ‘œํ˜„์‹์œผ๋กœ ๋กœ์ง์„ ์™„์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.
ํ•˜์ง€๋งŒ ์ž˜๋ชป ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์˜คํžˆ๋ ค ์ฝ๊ธฐ ์–ด๋ ต๊ณ , ์œ ์ง€ ๋ณด์ˆ˜๊ฐ€ ๊นŒ๋‹ค๋กœ์šด ์ฝ”๋“œ๊ฐ€ ๋œ๋‹ค. ๋•Œ๋ฌธ์— ๋ชจ๋“  ๋ฐ˜๋ณต๋ฌธ์„ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ฐ”๊พธ๊ธฐ ๋ณด๋‹ค๋Š” ๋‘˜์„ ์ ์ ˆํ•˜๊ฒŒ ์กฐํ•ฉํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ํ•„์š”ํ•˜๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ์—๋Š” Stream ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹๋‹ค.

- ์›์†Œ๋“ค์„ ํ•„ํ„ฐ๋งํ•œ๋‹ค.
- ์›์†Œ๋“ค์„ ์ผ๊ด€๋˜๊ฒŒ ๋ณ€ํ™˜ํ•œ๋‹ค.
- ์›์†Œ๋“ค์„ ํ•˜๋‚˜์˜ ์—ฐ์‚ฐ์„ ์ด์šฉํ•ด ๊ฒฐํ•ฉํ•œ๋‹ค.
- ์›์†Œ๋“ค์„ ์ปฌ๋ ‰์…˜์œผ๋กœ ๋ชจ์€๋‹ค

๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ์—๋Š” Stream์ด ์ ์ ˆํ•˜์ง€ ์•Š๋‹ค.

- ์ง€์—ญ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•˜์—ฌ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ๋•Œ.
- return ์„ ์ด์šฉํ•œ ์–ผ๋ฆฌ๋ฆฌํ„ด์ด๋‚˜, break, continue๋ฌธ ๋“ฑ์„ ์‚ฌ์šฉํ•  ๋•Œ.
- ๋ฉ”์„œ๋“œ์— ๋ช…์‹œ๋œ ๊ฒ€์‚ฌ ์˜ˆ์™ธ๋ฅผ ๋˜์งˆ ๋•Œ. 

๋žŒ๋‹ค์—์„œ๋Š” final ๋˜๋Š” ์‚ฌ์‹ค์ƒ final ์ธ ๋ณ€์ˆ˜๋งŒ ์ฝ์„ ์ˆ˜ ์žˆ๊ณ , ์ง€์—ญ๋ณ€์ˆ˜์˜ ๊ฐ’์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๋‹ค.

์ ์ ˆํ•œ ์ƒํ™ฉ์— ๋žŒ๋‹ค๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด ์ด์ œ๋Š” ๊ฐœ์ธ์˜ ์ทจํ–ฅ, ๋˜๋Š” ๋žŒ๋‹ค์˜ ์ˆ™๋ จ๋„์˜ ์ฐจ์ด์ด๋‹ค.
๊ฐœ๋ฐœ์ž์˜ ์ˆ™๋ จ๋„๋‚˜ ์ทจํ–ฅ์— ๋”ฐ๋ผ ์„ ํ˜ธ๋˜๋Š” ๋ฐฉ์‹์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ž์‹ ์ด ์„ ํ˜ธํ•˜๋Š” ๋ฐฉ์‹, ๋˜๋Š” ๋™๋ฃŒ๋“ค๋„ ์–ด๋ ต์ง€ ์•Š๊ฒŒ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ์‹์„ ํƒํ•˜์ž.

๐Ÿ“Œ Item50. ์ ์‹œ์— ๋ฐฉ์–ด์  ๋ณต์‚ฌ๋ณธ์„ ๋งŒ๋“ค๋ผ

์–ด๋–ค ๊ฐ์ฒด๋“  ๊ทธ ๊ฐ์ฒด์˜ ํ—ˆ๋ฝ ์—†์ด๋Š” ๊ฐ์ฒด์˜ ์ˆ˜์ •์ด ๋ถˆ๊ฐ€๋Šฅ ํ•ด์•ผํ•œ๋‹ค. ํ•˜์ง€๋งŒ ํ•œ ๊ฐ€์ง€๋ฅผ ๊ณ ๋ คํ•˜์ง€ ์•Š์œผ๋ฉด ์ž์‹ ๋„ ๋ชจ๋ฅด๊ฒŒ ๋‚ด๋ถ€๋ฅผ ์ˆ˜์ •ํ•˜๋„๋ก ํ—ˆ๋ฝํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ๋ณด์ž.

public class Point {
  private final int x;
  private final int y;
  
  public Point(final int x, final int y) {
      this.x = x;
      this.y = y;
  }
}

์ƒ๊ธฐ์˜ ์ฝ”๋“œ๋Š” ์™ธ๋ถ€์˜ ๋ณ€๊ฒฝ์œผ๋กœ ๋ถ€ํ„ฐ ์•ˆ์ „ํ• ๊นŒ?
๋‹ค๋“ค ์‰ฝ๊ฒŒ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋“ฏ์ด int์™€ ๊ฐ™์€ ์›์‹œ ํƒ€์ž…์€ ๊ฐ’์„ ์ „๋‹ฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์™ธ๋ถ€์—์„œ ์ „๋‹ฌํ•ด์ค€ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋”๋ผ๋„ ๋‚ด๋ถ€ ๊ฐ์ฒด์—๋Š” ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š”๋‹ค.

ํ•˜์ง€๋งŒ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋Š” ์–ด๋–จ๊นŒ?

public class Period{
    private final Date start;
    private final Date end;
    
    public Period(final Date start, final Date end) {
        this.start = start;
        this.end = end;
    }
}

Date ๊ฐ์ฒด๋Š” ์œ„์˜ int ์™€๋Š” ๋‹ฌ๋ฆฌ ์ฐธ์กฐ๊ฐ€ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌ๋˜๊ฒŒ ๋˜๊ณ , ์™ธ๋ถ€์—์„œ ํ•ด๋‹น Date ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ๊ฐ’์ด ๋ณ€๊ฒฝ ๋œ๋‹ค๋ฉด, Period ๊ฐ์ฒด ๋˜ํ•œ ๊ฐ’์˜ ๋ณ€๊ฒฝ์—์„œ ์•ˆ์ „ํ•˜์ง€ ์•Š๋‹ค.
final ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์˜€์ง€๋งŒ ์ด๋Š” Date ์ธ์Šคํ„ด์Šค ์ž์ฒด๊ฐ€ ๊ต์ฒด๋˜๋Š” ๊ฒƒ ๋งŒ์„ ๋ฐฉ์ง€ํ•  ๋ฟ, ์ธ์Šคํ„ด์Šค์˜ ๋‚ด๋ถ€ ๊ฐ’์˜ ๋ณ€๊ฒฝ๊นŒ์ง€ ๋ง‰์ง€๋Š” ๋ชปํ•œ๋‹ค.

์ด๋Ÿฌํ•œ ๊ตฌ์กฐ๋Š” ์•…์˜ ์ ์ธ ํ”„๋กœ๊ทธ๋ž˜๋จธ๋‚˜, ์ด๋Ÿฐ ์‚ฌ์‹ค์„ ๋ชจ๋ฅด๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ๋กœ๋ถ€ํ„ฐ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ๋ฝํ•˜๊ฒŒ ๋˜๊ณ , ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.
(ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์˜๋„ํ•œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ๋ฌด์‹œํ•  ์ˆ˜ ์žˆ๋‹ค.)
์–ด๋–ป๊ฒŒ ์ด๋Ÿฐ ์ฐธ์กฐ๋ฅผ ๋Š์–ด๋‚ผ ์ˆ˜ ์žˆ์„๊นŒ? ์ฐธ์กฐ๋ฅผ ๋Š์–ด ๋‚ด๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ์ƒ์„ฑ์ž์—์„œ ๋ฐฉ์–ด์  ๋ณต์‚ฌ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

public class Period{
  private final Date start;
  private final Date end;

  public Period(final Date start, final Date end) {
    this.start = new Date(start.getTime());
    this.end = new Date(end.getTime());
  }
}

์ƒˆ๋กœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ํด๋ผ์ด์–ธํŠธ์—์„œ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„˜๊ธด ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋”๋ผ๋„ ์•ˆ์ „ํ•˜๋‹ค.
์—ฌ๊ธฐ์„œ Data์—๋Š” clone ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ์Œ์—๋„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜๋Š”๋ฐ, ์ด๋Š” Data ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์€ ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ์•…์˜์ ์œผ๋กœ clone ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ ํ–ˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ด๋ ‡๊ฒŒ ์ƒ์„ฑ์ž๋ฉด ๋ฐฉ์–ด์  ๋ณต์‚ฌ๋กœ ๋ณ€๊ฒฝํ•ด์ฃผ๋ฉด ๋ชจ๋“  ํด๋ผ์ด์–ธํŠธ์˜ ์ ‘๊ทผ์—์„œ ์•ˆ์ „ํ•˜๋ƒ? ์•„์ง ํ•œ ๊ฐ€์ง€๊ฐ€ ๋‚จ์•˜๋‹ค. getter ์—์„œ ๋ฐ˜ํ™˜ํ•ด์ฃผ๋Š” ๊ฐ’ ๋˜ํ•œ ๋ฐฉ์–ด์  ๋ณต์‚ฌ๋ฅผ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ•ด๋‹น ๊ฐ’์„ ์–ป์€ ๋’ค ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
์ด๋•Œ๋Š” ์ƒ์„ฑ์ž์—์„œ์˜ ๋ฐฉ์–ด์  ๋ณต์‚ฌ์™€๋Š” ๋‹ฌ๋ฆฌ clone์„ ์‚ฌ์šฉํ•˜์—ฌ๋„ ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค. ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์ธ Date ๊ฐ์ฒด๋Š” ์šฐ๋ฆฌ๊ฐ€ ์ง€์ •ํ•œ Date ํด๋ž˜์Šค์ž„์ด ํ™•์‹คํ•˜๊ฒŒ ๋ณด์žฅ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋ฐฉ์–ด์  ๋ณต์‚ฌ๋Š”๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ์˜ ์ €ํ•˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ๋˜ํ•œ ๊ฐ™์€ ํŒจํ‚ค์ง€์— ์กด์žฌํ•˜๋Š” ๋“ฑ์˜ ์ด์œ ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์„์ˆ˜๋„ ์žˆ๋‹ค.
๋•Œ๋ฌธ์— ๋ถˆ๋ณ€์„ ์ด์šฉํ•˜์—ฌ ๋ฐฉ์–ด์  ๋ณต์‚ฌ๋ฅผ ํ•ด์•ผํ•  ์ผ์„ ์ตœ๋Œ€ํ•œ ์ค„์ด์ž.
๋งŒ์•ฝ ๋‘˜๋‹ค ๋ถˆ๊ฐ€๋Šฅํ•œ ์ƒํ™ฉ์ด๋ผ๋ฉด ๋ฌธ์„œ์— ์ž˜ ๋ช…์‹œํ•˜์—ฌ ๋ˆ„๊ตฐ๊ฐ€ ์‹ค์ˆ˜๋กœ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋„๋ก ๋ฐฉ์ง€ํ•œ๋‹ค.

๐Ÿ“Œ Item51. ๋ฉ”์„œ๋“œ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ์‹ ์ค‘ํžˆ ์„ค๊ณ„ํ•˜๋ผ

  • ๐Ÿ‘† ๋ฉ”์„œ๋“œ์˜ ์ด๋ฆ„์„ ์‹ ์ค‘ํ•˜๊ฒŒ ์ง“์ž!

    ์ ์–ด๋„ ๊ฐ™์€ ํŒจํ‚ค์ง€์— ์†ํ•œ ์ฝ”๋“œ๋ผ๋ฆฌ๋Š” ์ผ๊ด€๋œ ๊ทœ์น™์œผ๋กœ ์ด๋ฆ„์„ ์ง“๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์šฐ์„ ์‹œ ๋˜์–ด์•ผ ํ•œ๋‹ค.
    ๋˜ ์ผ๋ฐ˜์ ์œผ๋กœ ๊ฐœ๋ฐœ์ž๋“ค ์‚ฌ์ด์—์„œ ๋„๋ฆฌ ๋ฐ›์•„๋“ค์—ฌ์ง€๋Š” ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

    ๐Ÿ’ก ๊ทธ๋Ÿฌ๋‚˜ ๋„ˆ๋ฌด ๊ธด ์ด๋ฆ„์€ ํ”ผํ•˜์ž๊ณ  ๋˜์–ด์žˆ๋‹ค. (๊ธธ๋‹ค์˜ ๊ธฐ์ค€์€ ์–ด๋А์ •๋„ ์ผ๊นŒ, ๋‚˜๋Š” ์ข€ ๊ธธ๋”๋ผ๋„ ์—ญํ• ์„ ์ž˜ ์„ค๋ช…ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค.)

  • ๐Ÿ‘† ๋„ˆ๋ฌด ๋งŽ์€ ํŽธ์˜ ๋ฉ”์„œ๋“œ๋Š” ์ง€์–‘ํ•˜์ž!

    ํด๋ž˜์Šค๋‚˜ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ž์‹ ์˜ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•ด์•ผ ํ•œ๋‹ค, ํŽธ์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์•„์ง€๋ฉด ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ๋„ ๊ดด๋กญ๊ณ , ๊ตฌํ˜„ํ•˜๋Š” ์‚ฌ๋žŒ๋„ ๊ดด๋กญ๋‹ค.
    ๊ต‰์žฅํžˆ ์ž์ฃผ ์“ฐ์—ฌ ๊ผญ ํ•„์š”ํ•˜๋‹ค๊ณ  ํ™•์‹ ์ด ๊ฐ€๋Š” ๊ฒฝ์šฐ์—๋งŒ ๋งŒ๋“ค๋„๋ก ํ•˜์ž.

  • ๐Ÿ‘† ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ชฉ๋ก์€ ์งง๊ฒŒ ์œ ์ง€ํ•˜์ž!

    ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ๋„ˆ๋ฌด ๋Š˜์–ด๋‚˜๋ฉด ๊ธฐ์–ตํ•˜๊ธฐ ์–ด๋ ต๋‹ค. ํŠนํžˆ ์ œ๋Œ€๋กœ ๊ธฐ์–ตํ•˜์ง€ ๋ชปํ•˜๋Š” ๋™์ผํ•œ ํƒ€์ž…์˜ ๋ณ€์ˆ˜๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ ์žˆ๋‹ค๋ฉด, ๊ฐœ๋ฐœ์ž์˜ ์‹ค์ˆ˜์— ์˜ํ•ด ์ž˜๋ชป๋œ ๋กœ์ง์œผ๋กœ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค.
    (๋ฌผ๋ก , ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๋Š” ๋‚˜์ง€ ์•Š๋Š”๋‹ค..)

    ํ•œ ๋ฉ”์„œ๋“œ์— ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋„ˆ๋ฌด ๋งŽ๋‹ค๋ฉด ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ๋กœ ์ชผ๊ฐœ๊ฑฐ๋‚˜, ์„œ๋กœ๋ฅผ ์กฐํ•ฉํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์„ฑํ•˜๋ฉด ์ข‹๋‹ค.
    ๋งŒ์•ฝ ์œ„์น˜(x,y) ์™€ ๊ฐ™์€ ๊ฐ’์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›๋Š”๋‹ค๋ฉด ์ด๋ฅผ ๋ฌถ์–ด๋‘๋Š” ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ๋„ ์ข‹์€ ๋ฐฉ๋ฒ•์ด๋‹ค.

  • ๐Ÿ‘† ๋งค๊ฐœ๋ณ€์ˆ˜ ํƒ€์ž…์œผ๋กœ๋Š” ํด๋ž˜์Šค๋ณด๋‹ค๋Š” ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋‚ซ๋‹ค.

    ์˜ˆ๋ฅผ๋“ค์–ด HashMap์˜ ํƒ€์ž…์œผ๋กœ ๋ฐ›๊ธฐ๋ณด๋‹ค๋Š” Map์œผ๋กœ ๋ฐ›๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
    ํด๋ž˜์Šค ํƒ€์ž…์œผ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›๊ฒŒ ๋œ๋‹ค๋ฉด ํŠน์ • ๊ตฌํ˜„์ฒด๋งŒ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์œ ์—ฐ์„ฑ์ด ๋–จ์–ด์ง„๋‹ค.
    (ํŠน์ • ๊ตฌํ˜„ ํด๋ž˜์Šค๋กœ์˜ ๊ฐ•์ œ, ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํ•ด๋‹น ํด๋ž˜์Šค๋กœ์˜ ๋ณ€ํ™˜์ด ํ•„์š”ํ•˜๋‹ค.)

  • ๐Ÿ‘† boolean ํƒ€์ž…๋ณด๋‹ค๋Š” ์›์†Œ 2๊ฐœ์งœ๋ฆฌ Enum์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด๋ณด์ž.

    ๋ฉ”์„œ๋“œ ์ด๋ฆ„์ƒ boolean์„ ๋ฐ›์•„์•ผ ์ž์—ฐ์Šค๋Ÿฌ์šธ ๋•Œ์—๋Š” boolean ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›๋Š” ๊ฒƒ์ด ์˜๋ฏธ๊ฐ€ ๋” ๋ช…ํ™•ํ•  ๋•Œ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด Enum ํƒ€์ž…์„ ๊ณ ๋ คํ•ด๋ณด์ž.
    ์„ ํƒ์ง€๊ฐ€ ๋‘๊ฐœ๋ฐ–์— ์—†๋Š” ์ƒํ™ฉ์ด๋ผ๊ณ  ํ•˜๋”๋ผ๋„ ์ธ์ž๋กœ ๋ฐ›์„ ๊ฒƒ์— ๋Œ€ํ•œ ๋Œ€๋‹ต์ด ์„œ๋กœ ์ • ๋ฐ˜๋Œ€๋ผ๊ณ  ํ‘œํ˜„ํ•  ๋•Œ ์–ด์ƒ‰ํ•˜๋‹ค๋ฉด Enum ํƒ€์ž…์œผ๋กœ ๋”์šฑ ๋ช…ํ™•ํ•˜๊ฒŒ ํ‘œํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.
    ์˜ˆ๋ฅผ ๋“ค์–ด ํ˜„์žฌ ์ƒ‰์˜ ์„ ํƒ์ง€๊ฐ€ ๊ฒ€์ •, ํฐ์ƒ‰ ๋‘๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค๊ณ  ํ–ˆ์„ ๋•Œ Color.newInstance(true | false) ๋ณด๋‹ค๋Š”
    Color.newInstance(ColorList.WHITE | ColorList.BLACK)์ด ๋‚˜์„ ๊ฒƒ์ด๋‹ค. ๋˜ํ•œ ๋‚˜์ค‘์— ์ƒ‰์ด ์ถ”๊ฐ€๋œ๋‹ค๊ณ  ํ• ๋•Œ boolean ๋ณด๋‹ค ์ˆ˜์ •ํ•  ๋ถ€๋ถ„์ด ํ›จ์”ฌ ์ ๋‹ค.(์ถ”๊ฐ€๋งŒ ํ•˜๋ฉด ๋จ)

๐Ÿ“Œ Item54. null์ด ์•„๋‹Œ ๋นˆ ์ปฌ๋ ˆ์…˜์ด๋‚˜ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•˜๋ผ

ํ”ํžˆ ๋ฆฌ์ŠคํŠธ์™€ ๊ฐ™์€ ์ปฌ๋ ‰์…˜์ด๋‚˜ ๋ฐฐ์—ด์— ๊ฐ’์„ ๋‹ด์•„์„œ ๋ฐ˜ํ™˜ํ•œ๋‹ค๊ณ  ํ•  ๋•Œ ํ•ด๋‹น ๊ฐ’์ด ์กด์žฌํ•˜์ง€ ์•Š์„ ๋•Œ๋Š” null์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ๋ณธ ์ ์ด ์žˆ์„ ๊ฒƒ์ด๋‹ค.

private fianl List<User> users = ...; 

public List<User> getUsers() {
    
    if(users.isEmpty){
        return null;
    }
    return new ArrayList<>(users);
}

ํ•˜์ง€๋งŒ ์ด๋Ÿฐ์‹์œผ๋กœ ๊ฐ’์ด ์—†์„ ๋•Œ null์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋ฉด, ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํด๋ผ์ด์–ธํŠธ๋Š” ๋งค๋ฒˆ null์„ ๊ฒ€์‚ฌํ•˜๋Š” ๋ฐฉ์–ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์ค˜์•ผ ํ•œ๋‹ค.
null์„ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ๊ฐ€ ๋” ๋ณต์žกํ•ด์ง€๋Š” ์ƒํ™ฉ์ด ์ƒ๊ธธ์ˆ˜๋„ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ์ด๋‹ค.

List<User> users = ...getUsers();

users.forEach(System.out::println);

์ƒ๊ธฐ์™€ ๊ฐ™์€ ์ฝ”๋“œ์—์„œ getUsers๊ฐ€ null์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋ฉด NPE๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋ฐฉ์–ด์ฝ”๋“œ๊ฐ€ ์ž‘์„ฑ๋˜์–ด์•ผ ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ๋นˆ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋„˜๊ฒจ์ค€๋‹ค๋ฉด, ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ๋Š” ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.

๋นˆ ์ปฌ๋ ‰์…˜์„ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค. ๋˜๋Š” ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด๋‘” ๋นˆ ์ปฌ๋ ‰์…˜์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค.

return new ArrayList<>(users);

๋งค๋ฒˆ ๋นˆ ์ปฌ๋ ‰์…˜์„ ์ƒ์„ฑํ•˜๋Š” ๋น„์šฉ์ด ์•„๊น๋‹ค๋ฉด Collections.emptyList(emptySet,emptyMap) ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋งค๋ฒˆ ๋˜‘๊ฐ™์€ ๋นˆ ๋ถˆ๋ณ€ ์ปฌ๋ ‰์…˜์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋œ๋‹ค.
๋ถˆ๋ณ€ ๊ฐ์ฒด๋Š” ๊ณต์œ ํ•ด๋„ ์•ˆ์ „ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋ฐฐ์—ด์˜ ๊ฒฝ์šฐ์—๋Š” ๊ธธ์ด๊ฐ€ 0์ธ ๋ฐฐ์—ดnew int[0]์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋œ๋‹ค. ๋ฐฐ์—ด๊ฐ™์€ ๊ฒฝ์šฐ๋Š” ๊ธธ์ด๊ฐ€ 0์ด๋ฉด ํ•ญ์ƒ ๋ถˆ๋ณ€์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด๋‘๊ณ  ์‚ฌ์šฉํ•ด๋„ ๋œ๋‹ค.

๋ฏธ๋ฆฌ ์ƒ์„ฑํ•ด๋‘” ์ปฌ๋ ‰์…˜, ๋ฐฐ์—ด์ด ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•ด์ค€๋‹ค๊ณ ๋Š” ์žฅ๋‹ดํ•˜์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ•ญ์ƒ ์‚ฌ์šฉํ•  ๋•Œ์—๋Š” ์ „ํ›„์˜ ์„ฑ๋Šฅ์„ ์ธก์ •ํ•ด๋ณผ ํ•„์š”๊ฐ€ ์žˆ๋‹ค.

๐Ÿ“Œ Item55. ์˜ต์…”๋„ ๋ฐ˜ํ™˜์€ ์‹ ์ค‘ํžˆ ํ•˜๋ผ.

๋ฉ”์„œ๋“œ๊ฐ€ ํŠน์ • ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์—†์„ ๋•Œ ์ทจํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‘๊ฐ€์ง€ ์ด๋‹ค. ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๊ฑฐ๋‚˜, null์„ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜.
๊ทธ๋Ÿฌ๋‚˜ ์ง„์งœ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ƒํ™ฉ์ด ์•„๋‹ˆ๋ผ๋ฉด ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๊ฒƒ์€ ์ ํ•ฉํ•˜์ง€ ์•Š๊ณ , null์˜ ๋ฐ˜ํ™˜๋˜ํ•œ null ์ฒ˜๋ฆฌ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผํ•˜๋ฉฐ, ์˜ค๋ฅ˜์˜ ๊ฐ€๋Šฅ์„ฑ์„ ๋งŒ๋“ ๋‹ค.

์ž๋ฐ” 8 ๋ถ€ํ„ฐ๋Š” Optional๋กœ ์ด๋ฅผ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ๋‹ค.
์˜ต์…”๋„์€ ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๋Š” ๋ฉ”์„œ๋“œ๋ณด๋‹ค ์œ ์—ฐํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , NPE์˜ ๋ฐœ์ƒ ๊ฐ€๋Šฅ์„ฑ์„ ์ค„์—ฌ์ค€๋‹ค.

if(list.isEmpty()) {
    return Optional.empty();
}

// doSomething

return Optional.of(result);

empty() ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋นˆ ๊ฐ’์ž„์„ ๋„˜๊ฒจ์ค„ ์ˆ˜ ์žˆ๊ณ , of() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ’์ด ๋“  Optional ์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

์˜ต์…”๋„์—์„œ ๊ฐ’์„ ๊บผ๋‚ผ ๋–„์—๋Š” orElse("๊ฐ’์ด ๋น„์–ด์žˆ์Œ."); ๋‚˜ orElseGet(Supplier<T>) ๊ฐ™์ด ๊ฐ’์ด ๋น„์–ด์žˆ์„ ๋•Œ ๋Œ€์ฒดํ•  ๊ธฐ๋ณธ๊ฐ’์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๊ณ , orElseThrow(Exception::new); ๋กœ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜๋„ ์žˆ๋‹ค.
๊ธฐ๋ณธ๊ฐ’์„ ์„ค์ •ํ•  ๋•Œ orElseGet(Supplier<T>)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ’์ด ํ•„์š”ํ•  ๋•Œ ์ƒ์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ดˆ๊ธฐ ์„ค์ • ๋น„์šฉ์„ ์•„๋‚„ ์ˆ˜ ์žˆ๋‹ค.

isPresent()๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ฐ’์ด ์กด์žฌํ•˜๋Š”์ง€์˜ ์—ฌ๋ถ€๋ฅผ boolean ๊ฐ’์œผ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ณ , ๊ฐ’์ด ํ•ญ์ƒ ์กด์žฌํ•œ๋‹ค๋Š” ํ™•์‹ ์ด ์žˆ๋‹ค๋ฉด get()์œผ๋กœ ๊ฐ’์„ ๊บผ๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

Stream ๋„ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— map, flatMap, filter๋„ ์ง€์›ํ•œ๋‹ค.
์ž๋ฐ” 9 ๋ถ€ํ„ฐ๋Š” Optional.stream() ๋ฉ”์„œ๋“œ๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ๋Š”๋ฐ, ์ด ๋ฉ”์„œ๋“œ๋Š” Optional์„ Stream์œผ๋กœ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค. ๊ฐ’์ด ์žˆ๋‹ค๋ฉด ๊ทธ ๊ฐ’์„ ์›์†Œ๋กœ ๊ฐ€์ง€๋Š” Stream์„,
์—†๋‹ค๋ฉด ๋นˆ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

์˜ต์…”๋„๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ด ํ•ญ์ƒ ์ข‹์€ ๊ฒƒ์€ ์•„๋‹Œ๋ฐ, ๊ธฐ๋ณธํ˜• ํƒ€์ž…์€ ๋น„์–ด์žˆ๋‹ค๋ผ๋Š” ํ‘œํ˜„์ด ์—†์–ด ์˜ต์…”๋„์„ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์„ ์ˆ˜ ์žˆ์ง€๋งŒ,
๊ฐ’์ด List ํƒ€์ž…๊ณผ ๊ฐ™์€ ์ปฌ๋ ‰์…˜์ด๋‚˜ Stream, ๋ฐฐ์—ด, ์˜ต์…”๋„ ์ด๋ผ๋ฉด ๊ทธ๋ƒฅ ๋นˆ List ์™€ ๊ฐ™์ด ๋น„์–ด์žˆ๋Š” ์ปฌ๋ ‰์…˜์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ด ๋” ์ข‹๋‹ค. (์ถ”๊ฐ€์ ์ธ Optional ์ฒ˜๋ฆฌ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.)

๊ธฐ๋ณธ ํƒ€์ž…์„ ์˜ต์…”๋„๋กœ ๊ฐ์‹ผ๋‹ค๋ฉด Optional ์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๊ธฐ ๋ณด๋‹ค๋Š” OptionalInt ์™€ ๊ฐ™์€ ์ „์šฉ ์˜ต์…”๋„ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ž.

๐Ÿง ์˜ต์…”๋„ ์‚ฌ์šฉ์„ ๊ณ ๋ฏผํ•ด์•ผ ํ•  ๋•Œ

์˜ต์…”๋„์„ Map ์—์„œ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ? ๋งต ์•ˆ์— ํ‚ค๊ฐ€ ์—†์Œ์„ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒƒ์ด ๋‘๊ฐ€์ง€๊ฐ€ ๋œ๋‹ค.

  1. ์ง„์งœ ํ‚ค๊ฐ€ ์—†์„ ๋•Œ
  2. ์žˆ์ง€๋งŒ ๋น„์–ด์žˆ๋Š” ์˜ต์…”๋„

๋ณต์žก์„ฑ๋งŒ ์ฆ๊ฐ€ํ•  ๋ฟ, ์ด์ ์ด ์—†๋‹ค. ์˜ต์…”๋„์„ ์ปฌ๋ ‰์…˜์˜ ํ‚ค, ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ๋ฐฐ์—ด์˜ ์›์†Œ๋กœ ์‚ฌ์šฉํ•  ๋•Œ์—๋Š” ๋‹ค์‹œํ•œ๋ฒˆ ๊ณ ๋ฏผ์„ ํ•ด๋ณด์ž.

์˜ต์…”๋„์„ ์ธ์Šคํ„ด์Šค์˜ ํ•„๋“œ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ์–ด๋–จ๊นŒ?
์ด๋Ÿฐ ๊ฒฝ์šฐ๋Š” ๋Œ€๋ถ€๋ถ„ ํ•„์ˆ˜ ํ•„๋“œ๋ฅผ ๊ฐ€์ง„ ํด๋ž˜์Šค์™€ ์„ ํƒํ•„๋“œ๋ฅผ ๊ฐ€์ง„ ํ™•์žฅ ํด๋ž˜์Šค๋ฅผ ๋”ฐ๋กœ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ฒƒ์ด ๋‚˜์€ ๊ฒฝ์šฐ์ด๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ๋งŒ์•ฝ ํ•„๋“œ๊ฐ€ ๊ธฐ๋ณธํƒ€์ž…์ด๊ณ , ๋Œ€๋ถ€๋ถ„์ด ์„ ํƒ์  ํ•„๋“œ๋ผ๋ฉด Getter๊ฐ€ ์˜ต์…”๋„์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ด ๊ดœ์ฐฎ์„ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“Œ Item57. ์ง€์—ญ๋ณ€์ˆ˜์˜ ๋ฒ”์œ„๋ฅผ ์ตœ์†Œํ™”ํ•˜๋ผ

์ง€์—ญ๋ณ€์ˆ˜์˜ ์œ ํšจ๋ฒ”์œ„๋ฅผ ์ตœ์†Œํ™”(์ตœ๋Œ€ํ•œ ์‚ฌ์šฉํ•˜๋Š” ๋ฒ”์œ„๊นŒ์ง€๋งŒํ•˜๋ฉด) ๊ฐ€๋…์„ฑ์ด ์ข‹์•„์ง€๊ณ , ์˜ค๋ฅ˜์˜ ๊ฐ€๋Šฅ์„ฑ์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

์ง€์—ญ๋ณ€์ˆ˜์˜ ๋ฒ”์œ„๋ฅผ ์ค„์ด๋Š” ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•์€ ๊ฐ€์žฅ ์ฒ˜์Œ ์‚ฌ์šฉ๋  ๋•Œ ์„ ์–ธํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
์ฝ”๋“œ์˜ ๋งจ ์•ž๋ถ€๋ถ„์— ๋ฏธ๋ฆฌ ์„ ์–ธํ•ด๋‘๋ฉด, ๊ฐ€๋…์„ฑ๋„ ๋–จ์–ด์ง€๊ณ , ์‹ค์ œ ์‚ฌ์šฉํ•  ๋•Œ ์ดˆ๊ธฐํ™”ํ•ด๋‘” ๊ฐ’์ด ์ƒ๊ฐ์ด ๋‚˜์ง€ ์•Š๋Š”๋‹ค๊ฑฐ๋‚˜, ์ƒ๊ฐ๋ณด๋‹ค ๋ฒ”์œ„๋ฅผ ๋„“๊ฒŒ ์žก์•„๋‘ฌ
๊ทธ๊ฒƒ์„ ๋‹ค์‹œ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋Š” ์‹ค์ˆ˜๋ฅผ ๋ฒ”ํ•˜๊ฒŒ ๋  ์ˆ˜ ์žˆ๋‹ค.

์ด๋Ÿฌํ•œ ์˜ˆ์‹œ๋Š” for ๊ณผ while์˜ ์ฐจ์ด์—์„œ ๋ฐœ๊ฒฌ๋œ๋‹ค.

int i = 0;
while(i < 10) {
    // Do Something ..
    i++;

int i2 = 0;
while(i < 10) {
    // Do Something ..
    i2++;
}

ํ•ด๋‹น ์ฝ”๋“œ์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ณด์ด๋Š”๊ฐ€? ์ฒซ ๋ฐ˜๋ณต๋ฌธ์—์„œ i๋ฅผ ์ด์šฉํ•ด ๋ฐ˜๋ณต์„ ์ง„ํ–‰ํ–ˆ๊ณ , ๋‘ ๋ฒˆ์งธ ๋ฐ˜๋ณต๋ฌธ์—์„œ ํ”„๋กœ๊ทธ๋ž˜๋จธ์˜ ์‹ค์ˆ˜๋กœ ๋ฐ˜๋ณต๋ฌธ์˜ ์กฐ๊ฑด์—์„œ ๋‹ค์‹œ i๋ฅผ ๊ฐ€์ง€๊ณ  ํ™•์ธํ•œ๋‹ค.
์ปดํŒŒ์ผ ์˜ค๋ฅ˜๋Š” ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ณ , ๊ทธ์ € ๋‘๋ฒˆ์งธ ๋ฐ˜๋ณต๋ฌธ์ด ์‹คํ–‰๋˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค.

for๋ฌธ์„ ์ด์šฉํ•œ ๋ฐ˜๋ณต๋ฌธ์—์„œ๋Š” ์ด๋Ÿฐ ์ƒํ™ฉ์ด ์ผ์–ด๋‚  ์ˆ˜ ์—†๋‹ค.(๋ณ€์ˆ˜์˜ ์Šค์ฝ”ํ”„๊ฐ€ ๋ฐ˜๋ณต๋ฌธ)

for(int i=0; i<10; i++){
    // Do Something ..
}

for(int i=0; i<10; i++){
    // Do Something ..
}

์ƒ๊ธฐ์˜ ์ฝ”๋“œ๋Š” ์ปดํŒŒ์ผ ์—๋Ÿฌ๋„, ๋…ผ๋ฆฌ์  ์˜ค๋ฅ˜๋„ ์—†์ด ์ž˜ ๋Œ์•„๊ฐˆ ๊ฒƒ์ด๋‹ค. for ๋ฌธ์—์„œ ์ •์˜ํ•œ ๋ฐ˜๋ณต ์กฐ๊ฑด ๋ณ€์ˆ˜๋Š” ํ•ด๋‹น ๋ฐ˜๋ณต๋ฌธ ์•ˆ์—์„œ๋งŒ ์œ ํšจํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
๋•Œ๋ฌธ์— ๋™์ผํ•œ ๋ณ€์ˆ˜๋ช…์„ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๊ณ , ๋‘ ๋ฒˆ์งธ ๋ฐ˜๋ณต๋ฌธ์—์„œ i2๋กœ ์„ ์–ธํ•˜๊ณ  ์‹ค์ˆ˜๋กœ ์กฐ๊ฑด์—์„œ i๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒƒ์ด๋‹ค.

๐Ÿ“Œ Item58. ์ „ํ†ต์ ์ธ for ๋ฌธ๋ณด๋‹ค๋Š” for-each ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋ผ

๋ฐ˜๋ณต์—์„œ ์ธ๋ฑ์Šค๋‚˜ ๋ฐ˜๋ณต์ž๋Š” ํ•„์š”์—†๊ณ  ๋‹จ์ง€ ์›์†Œ๋งŒ์„ ํ•„์š”๋กœ ํ•œ๋‹ค๋ฉด for-each๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. for-each๋Š” ์ปฌ๋ ‰์…˜๊ณผ ๋ฐฐ์—ด์„ ๋ชจ๋‘ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ธฐ ๋–„๋ฌธ์— ์–ด๋–ค ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋‹ค๋ฃจ๋Š”์ง€ ์‹ ๊ฒฝ์“ฐ์ง€์•Š๊ณ  ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ๋ณด์ž.

List<String> alphabets = new ArrayList<>(List.of("A", "B", "C"));
List<String> numbers = new ArrayList<>(List.of("1", "2", "3", "4", "5"));

List<String> comb = new ArrayList<>();
for (Iterator<String> aIt = alphabets.iterator(); aIt.hasNext(); ) {
    for(Iterator<String> nIt = numbers.iterator(); nIt.hasNext(); ) {
        comb.add(aIt.next() + nIt.next());
    }
}

์•ŒํŒŒ๋ฒณ๊ณผ ์ˆซ์ž์˜ ๋ชจ๋“  ์กฐํ•ฉ์„ ๊ธฐ๋Œ€ํ•˜๊ณ  ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์˜€๋‹ค๊ณ  ํ•ด๋ณด์ž. ๊ทธ๋Ÿฌ๋‚˜ ์œ„์˜ ์ฝ”๋“œ์—์„œ๋Š” ์ˆซ์ž๋งˆ๋‹ค aIt.next()๋„ ๊ฐ™์ด ํ˜ธ์ถœ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— 4๋ฒˆ์งธ ๋ฐ˜๋ณต์—์„œ
์•ŒํŒŒ๋ฒณ์˜ ์›์†Œ๊ฐ€ ๋ฐ”๋‹ฅ๋‚˜ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒƒ์ด๋‹ค. ์œ„์˜ ์ƒํ™ฉ์—์„œ๋Š” ๋‘ ์ค‘์ฒฉ for๋ฌธ ์‚ฌ์ด์— aIt.next()๋ฅผ ์ €์žฅํ•˜๋Š” ๋ณ€์ˆ˜๋ฅผ ๋‘์–ด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ for-each ๋ฌธ์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๋” ๊น”๋”ํ•˜๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

for(String alphabet : alphabets) {
    for(String number : numbers) {
        comb.add(alphabet + number);
    }     
}

๊ทธ๋Ÿฌ๋‚˜ for-each๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ฒฝ์šฐ๋“ค์ด ์žˆ๋‹ค.

  1. ์ปฌ๋ ‰์…˜์„ ์ˆœํšŒํ•˜๋ฉฐ ์„ ํƒ๋œ ์›์†Œ๋ฅผ ์ œ๊ฑฐํ•˜๊ฑฐ๋‚˜, ๊ฐ’์„ ๋ณ€๊ฒฝํ•ด์•ผ ํ•œ๋‹ค.
  2. ์—ฌ๋Ÿฌ๊ฐœ์˜ ์ปฌ๋ ‰์…˜ ๋˜๋Š” ๋ฐฐ์—ด์„ ๋ณ‘๋ ฌ๋กœ ์ˆœํšŒํ•ด์•ผ ํ•œ๋‹ค. ์œ„ ์˜ ๋‘๊ฐ€์ง€ ์ƒํ™ฉ์—์„œ๋Š” ์ธ๋ฑ์Šค ๋˜๋Š” ๋ฐ˜๋ณต์ž๊ฐ€ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— for-each ๋ฌธ์œผ๋กœ ์ž‘์„ฑํ•˜๊ธฐ์— ์ ํ•ฉํ•˜์ง€ ์•Š๋‹ค.

์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด for-each๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋…์„ฑ, ์˜ค๋ฅ˜ ๋ฐœ์ƒ๋ฅ  ๋ฉด์—์„œ๋„ ํฐ ์žฅ์ ์„ ๊ฐ€์ง„๋‹ค.
๋งŒ์•ฝ ํด๋ž˜์Šค๋ฅผ ์„ค๊ณ„ํ•˜๋Š”๋ฐ ๋‚ด๋ถ€์˜ ๊ฐ’์„ ์ˆœํšŒํ•ด์•ผ ํ•œ๋‹ค๋ฉด Iterable<E> ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ๋„ ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.

๐Ÿ“Œ Item61. ๋ฐ•์‹ฑ๋œ ๊ธฐ๋ณธ ํƒ€์ž…๋ณด๋‹ค๋Š” ๊ธฐ๋ณธ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋ผ

์ž๋ฐ”์—๋Š” int, double, boolean ๊ฐ™์€ ๊ธฐ๋ณธ ํƒ€์ž…์ด ์žˆ๊ณ , ์ด์— ๋Œ€์‘ํ•˜๋Š” ์ฐธ์กฐ ํƒ€์ž…์ธ Integer, Double, Boolean ์ด ์กด์žฌํ•œ๋‹ค.
์ž๋ฐ”์—์„œ๋Š” ์˜คํ†  ๋ฐ•์‹ฑ๊ณผ, ์–ธ๋ฐ•์‹ฑ์„ ์ง€์›ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋‘˜์„ ํฌ๊ฒŒ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋ฐ•์‹ฑ๋œ ๊ธฐ๋ณธ ํƒ€์ž…์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์‹๋ณ„์„ฑ(identity)๋ฅผ ๊ฐ€์ง€๋Š” ์ฐธ์กฐํ˜• ๊ฐ์ฒด์ด๋‹ค. ๋•Œ๋ฌธ์— ์›์‹œํ˜• ํƒ€์ž…๊ณผ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š์œผ๋ฉด ๋ช‡๊ฐ€์ง€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฒซ ๋ฒˆ์งธ๋กœ ๊ฐ’์„ ๋น„๊ตํ•˜๋Š” ๊ฒฝ์šฐ์ด๋‹ค.

Comparator<Integer> order = (i, j) -> i < j ? -1 : (i == j ? 0 : 1)

ํ•ด๋‹น ์ฝ”๋“œ์—์„œ ์ฒซ ๋ฒˆ์งธ ์›์†Œ๊ฐ€ ๋‘ ๋ฒˆ์งธ ์›์†Œ๋ณด๋‹ค ์ž‘์œผ๋ฉด -1, ๊ฐ™์œผ๋ฉด 0, ํฌ๋‹ค๋ฉด 1์„ ๋ฐ˜ํ™˜ํ•  ๊ฒƒ์ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.
ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ ํ•œ๊ฐ€์ง€ ๋ฌธ์ œ์ ์ด ๋ฐœ์ƒํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด new Integer(10) ๊ณผ new Integer(10)์˜ ๊ฐ’์„ ๋น„๊ตํ•œ๋‹ค๊ณ  ํ•ด๋ณด์ž.
์ฒ˜์Œ i < j ์—์„œ๋Š” false ๊ฐ€ ๋  ๊ฒƒ์ด๋ผ๋Š” ๊ฒƒ์„ ์‰ฝ๊ฒŒ ์˜ˆ์ธกํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ๋‹ค์Œ์œผ๋กœ ์‹คํ–‰๋˜๋Š” i == j ์—์„œ๋Š” ์–ด๋–ค ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ๊นŒ?
๋‘ ๊ฐ์ฒด๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ๊ฐ์ฒด๊ธฐ ๋•Œ๋ฌธ ๋™์ผ์„ฑ ๋น„๊ต์ธ == ๋น„๊ต์—์„œ๋Š” false๊ฐ€ ๋‚˜์˜ฌ ๊ฒƒ์ด๊ณ , ๊ฒฐ๊ณผ ๊ฐ’์€ 1์ด ๋˜์–ด ์ฒซ ๋ฒˆ์งธ ์›์†Œ์˜ ๊ฐ’์ด ๋” ์ž‘๋‹ค๋Š” ์ž˜๋ชป๋œ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ ๊ฒƒ์ด๋‹ค.

๋‘ ๋ฒˆ์งธ๋กœ๋Š” Null ๊ฐ’์ด๋‹ค.
์›์‹œ ํƒ€์ž…์˜ ๊ฐ’๊ณผ ๋น„๊ต๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ƒํ™ฉ์—์„œ ๋ฐ•์‹ฑ๋œ ํƒ€์ž…์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด NullPointExeception์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.
๋ฐ•์‹ฑ๋œ ํƒ€์ž…์€ ๊ธฐ๋ณธ์ ์œผ๋กœ Null ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™”๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ฐ’์„ ๋น„๊ตํ•˜๊ธฐ์œ„ํ•ด ๋ฐ•์‹ฑ ํƒ€์ž…์ด ์ž๋™์œผ๋กœ ์–ธ๋ฐ•์‹ฑ ๋˜๋ฉฐ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋œ๋‹ค.

์„ธ ๋ฒˆ์งธ๋กœ๋Š” ๋ฐ•์‹ฑ, ์–ธ๋ฐ•์‹ฑ์„ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•˜๋Š” ์„ฑ๋Šฅ์ €ํ•˜์ด๋‹ค.
๋ฌผ๋ก  ๋ช‡๋ฒˆ์˜ ๋ฐ•์‹ฑ, ์–ธ๋ฐ•์‹ฑ์œผ๋กœ ์„ฑ๋Šฅ์ €ํ•˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค. ํ•˜์ง€๋งŒ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ์ด๋ผ๋ฉด?

Integer sum = 0;
for (int i = 0; i < Integer.MAX_VALUES; i++) {
    sum += i;    
}

1๋ถ€ํ„ฐ Integer์˜ ์ตœ๋Œ€๊ฐ’๊นŒ์ง€์˜ ์ˆ˜๋ฅผ ๋”ํ•˜๋Š” ๊ฐ„๋‹จํ•œ ํ”„๋กœ๊ทธ๋žจ์ด๋‹ค.
ํ•˜์ง€๋งŒ sum์ด Integer ํƒ€์ž…์œผ๋กœ ์„ ์–ธ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ’์˜ ๊ณ„์‚ฐ์„ ์œ„ํ•ด ์–ธ๋ฐ•์‹ฑ ๋˜๊ณ , ๋‹ค์‹œ ๊ฐ’์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ•์‹ฑ์ด ๋ฐ˜๋ณต์ ์œผ๋กœ ๋ฐœ์ƒํ•  ๊ฒƒ์ด๋‹ค.
์ด๋Ÿฐ ๊ณผ์ •์ด ๋ฌด์ˆ˜ํžˆ ๋งŽ์ด ๋ฐ˜๋ณต๋œ๋‹ค๋ฉด ์ด๋Š” ์„ฑ๋Šฅ์ €ํ•˜์˜ ์›์ธ์ด ๋œ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ๋ฐ•์‹ฑ ํƒ€์ž…์€ ์–ธ์ œ ์‚ฌ์šฉํ•ด์•ผํ• ๊นŒ?
๋จผ์ € DB์™€ ๋งคํ•‘๋˜๋Š” ์—”ํ‹ฐํ‹ฐ์™€ ๊ฐ™์€ ๊ฐ์ฒด์—์„œ๋Š” ์ผ๋ถ€๋Ÿฌ ๋ฐ•์‹ฑ ํƒ€์ž…์„ ์‚ฌ์šฉํ•œ๋‹ค. DB์— ์ €์žฅ๋  ๋•Œ ๊ฐ’์ด ์—†์Œ์„ ๋‚˜ํƒ€๋‚ด๊ธฐ์œ„ํ•ด Null ๊ฐ’์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋˜ ์ž๋ฐ”์˜ Collection ์€ ์›์‹œ ํƒ€์ž…์„ ๋‹ด์„ ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ๋ฐ•์‹ฑ๋œ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค. ์ด๋Š” ๋ฆฌํ”Œ๋ ‰์…˜์„ ์‚ฌ์šฉํ•  ๋•Œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ด๋‹ค.