• ABOUT
  • PORTFOLIO
  • POSTS
  • GUESTBOOK

ยฉ 2025 BlueCool12 All rights reserved.

2025.08.12Java

๐Ÿ”„ ์ž๋ฐ” Stream API ๊ฐ€์ด๋“œ - ์ƒ์„ฑ, ์—ฐ์‚ฐ, ์žฅ๋‹จ์  ์ •๋ฆฌ

1. Stream API

Stream API๋Š” Java 8์—์„œ ๋„์ž…๋œ ๊ธฐ๋Šฅ์œผ๋กœ ์ปฌ๋ ‰์…˜ ๋ฐ์ดํ„ฐ๋ฅผ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์Šคํƒ€์ผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์ œ๊ณต๋˜๋Š” API์ด๋‹ค. ๊ธฐ์กด์˜ for๋ฌธ์ด๋‚˜ Iterator๋ฅผ ์ด์šฉํ•œ ์™ธ๋ถ€ ๋ฐ˜๋ณต ๋ฐฉ์‹ ๋Œ€์‹  ๋‚ด๋ถ€ ๋ฐ˜๋ณต ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚จ๋‹ค.

// for๋ฌธ
for (String name : names) {
if (name.length() > 4) {
System.out.println(name.toUpperCase());
}
}

// Stream
names.stream()
.filter(n -> n.length() > 4)
.map(String::toUpperCase)
.forEach(System.out::println);


- ์ฃผ์š” ํŠน์ง•

  • ์„ ์–ธํ˜• ์ฒ˜๋ฆฌ
    ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ• ์ง€๋ณด๋‹ค ๋ฌด์—‡์„ ํ• ์ง€๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. ์ด๋กœ ์ธํ•ด ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•˜๊ณ  ์ง๊ด€์ ์œผ๋กœ ์ž‘์„ฑ๋  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ ๋ถˆ๋ณ€์„ฑ
    ์›๋ณธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ์ƒˆ๋กœ์šด ๊ฒฐ๊ณผ ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฐ์ดํ„ฐ์˜ ์•ˆ์ •์„ฑ์ด ์œ ์ง€๋˜๋ฉฐ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ์— ์œ ๋ฆฌํ•˜๋‹ค.
  • ์ง€์—ฐ ์—ฐ์‚ฐ
    ์ค‘๊ฐ„ ์—ฐ์‚ฐ์€ ์‹ค์ œ ๊ฒฐ๊ณผ๊ฐ€ ํ•„์š”ํ•  ๋•Œ๊นŒ์ง€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค. ์ตœ์ข… ์—ฐ์‚ฐ์ด ํ˜ธ์ถœ๋  ๋•Œ ์ „์ฒด ์ŠคํŠธ๋ฆผ ํŒŒ์ดํ”„๋ผ์ธ์ด ์‹คํ–‰๋œ๋‹ค.
  • ๋‚ด๋ถ€ ๋ฐ˜๋ณต
    ๋ฐ˜๋ณต ์ฒ˜๋ฆฌ๋ฅผ Stream ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ๋ฐ˜๋ณต ๊ตฌ์กฐ๋ฅผ ์ž‘์„ฑํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.


2. ์ŠคํŠธ๋ฆผ ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌโ€‹์กฐ

Stream API๋Š” ์—ฐ์†๋œ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๊ณผ์ •์„ ํŒŒ์ดํ”„๋ผ์ธ ํ˜•ํƒœ๋กœ ์—ฐ๊ฒฐํ•˜์—ฌ ์ˆ˜ํ–‰ํ•œ๋‹ค. ์ŠคํŠธ๋ฆผ ํŒŒ์ดํ”„๋ผ์ธ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์ŠคํŠธ๋ฆผ ์ƒ์„ฑ -> ์ค‘๊ฐ„ ์—ฐ์‚ฐ -> ์ตœ์ข… ์—ฐ์‚ฐ์˜ ์„ธ ๋‹จ๊ณ„๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.


- ์ŠคํŠธ๋ฆผ ์ƒ์„ฑ (Source)

์ปฌ๋ ‰์…˜, ๋ฐฐ์—ด, ํŒŒ์ผ ๋“ฑ์˜ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋กœ๋ถ€ํ„ฐ ์ŠคํŠธ๋ฆผ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. Java์—์„œ๋Š” ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ Stream์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. 

// 1. ์ปฌ๋ ‰์…˜์—์„œ ์ƒ์„ฑ
List<String> list = List.of("Blue", "Cool", "Good");
Stream<String> stream1 = list.stream();

// 2. ๋ฐฐ์—ด์—์„œ ์ƒ์„ฑ
String[] arr = {"This", "is", "Array"};
Stream<String> stream2 = Arrays.stream(arr);

// 3. ์ˆซ์ž ๋ฒ”์œ„์—์„œ ์ƒ์„ฑ
IntStream intStream = IntStream.range(1, 5);
LongStream longStream = LongStream.rangeClosed(1, 5);

// 4. ์ง์ ‘ ์ƒ์„ฑ
Stream<Double> randoms = Stream.generate(Math::random).limit(5);

// 5. ๋นŒ๋” ์‚ฌ์šฉ
Stream<String> buildStream = Stream.<String>builder()
.add("This")
.add("is")
.add("Builder")
.build();


- ์ค‘๊ฐ„ ์—ฐ์‚ฐ (Intermediate Operations)

๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€ํ™˜, ํ•„ํ„ฐ๋ง, ์ •๋ ฌํ•˜๋Š” ๊ณผ์ •์„ ๋‹ด๋‹นํ•˜๋ฉฐ Stream ํŒŒ์ดํ”„๋ผ์ธ์˜ ์ค‘๊ฐ„ ๋‹จ๊ณ„์—์„œ ์ˆ˜ํ–‰๋˜๋Š” ์—ฐ์‚ฐ์ด๋‹ค. ์ด ๊ณผ์ •์—์„œ ์ง€์—ฐ ์—ฐ์‚ฐ(Lazy Evaluation)์ด ๋ฐœ์ƒํ•œ๋‹ค.

์ง€์—ฐ ์—ฐ์‚ฐ์ด๋ž€ ์ตœ์ข… ์—ฐ์‚ฐ์ด ํ˜ธ์ถœ๋˜๊ธฐ ์ „๊นŒ์ง€ ์‹ค์ œ ์—ฐ์‚ฐ์ด ์ˆ˜ํ–‰๋˜์ง€ ์•Š๊ณ  ์ตœ์ข… ์—ฐ์‚ฐ์ด ์‹คํ–‰๋˜๋Š” ์‹œ์ ์— ์ „์ฒด ํŒŒ์ดํ”„๋ผ์ธ์ด ํ•œ ๋ฒˆ์— ์ฒ˜๋ฆฌ๋˜๋Š” ๋ฐฉ์‹์„ ์˜๋ฏธํ•œ๋‹ค.

๋˜ํ•œ ์ค‘๊ฐ„ ์—ฐ์‚ฐ์€ Stream ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๋Ÿฌ ์—ฐ์‚ฐ์„ ์—ฐ๊ฒฐํ•˜๋Š” ์ฒด์ด๋‹ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๊ณผ์ •์„ ํ•˜๋‚˜์˜ ํŒŒ์ดํ”„๋ผ์ธ์œผ๋กœ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

๋Œ€ํ‘œ์ ์ธ ์ค‘๊ฐ„ ์—ฐ์‚ฐ ๋ฉ”์„œ๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

filter(Predicate)             // ์กฐ๊ฑด์— ๋งž๋Š” ์š”์†Œ๋งŒ ํ•„ํ„ฐ๋ง
map(Function) // ์š”์†Œ๋ฅผ ๋‹ค๋ฅธ ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜
flatMap(Function) // ์ค‘์ฒฉ๋œ ๊ตฌ์กฐ๋ฅผ ํ‰ํƒ„ํ™”
sorted() / sorted(Comparator) // ์š”์†Œ ์ •๋ ฌ
distinct() // ์ค‘๋ณต ์ œ๊ฑฐ
limit(long) // ์•ž์—์„œ๋ถ€ํ„ฐ n๊ฐœ ์š”์†Œ ์„ ํƒ
skip(long) // ์•ž์—์„œ๋ถ€ํ„ฐ n๊ฐœ ์š”์†Œ ๊ฑด๋„ˆ๋œ€
peek(Consumer) // ์š”์†Œ๋ฅผ ์†Œ๋น„ํ•˜์ง€ ์•Š๊ณ  ์ค‘๊ฐ„ ์ฒ˜๋ฆฌ ๊ณผ์ • ํ™•์ธ


- ์ตœ์ข… ์—ฐ์‚ฐ (Terminal Operation)

์ŠคํŠธ๋ฆผ ํŒŒ์ดํ”„๋ผ์ธ์˜ ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„์—์„œ ์ˆ˜ํ–‰๋˜๋Š” ์—ฐ์‚ฐ์œผ๋กœ ์ค‘๊ฐ„ ์—ฐ์‚ฐ์„ ํ†ตํ•ด ์ฒ˜๋ฆฌ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ตœ์ข… ๊ฒฐ๊ณผ๋กœ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜ ์†Œ๋น„ํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

์ตœ์ข… ์—ฐ์‚ฐ์ด ํ˜ธ์ถœ๋˜๋ฉด ๊ทธ๋•Œ๊นŒ์ง€ ์ •์˜๋œ ์ค‘๊ฐ„ ์—ฐ์‚ฐ๋“ค์ด ํ•œ ๋ฒˆ์— ์‹คํ–‰๋˜๋ฉด์„œ ์ŠคํŠธ๋ฆผ ํŒŒ์ดํ”„๋ผ์ธ์ด ์ข…๋ฃŒ๋œ๋‹ค. ๋˜ํ•œ ์ตœ์ข… ์—ฐ์‚ฐ์ด ์ˆ˜ํ–‰๋œ ์ŠคํŠธ๋ฆผ์€ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

๋Œ€ํ‘œ์ ์ธ ์ตœ์ข… ์—ฐ์‚ฐ ๋ฉ”์„œ๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. 

forEach(Consumer)                 // ๊ฐ ์š”์†Œ๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ์ฒ˜๋ฆฌ
collect(Collector) // ์ŠคํŠธ๋ฆผ ์š”์†Œ๋ฅผ ์ปฌ๋ ‰์…˜ ๋“ฑ์œผ๋กœ ๋ณ€ํ™˜
toArray() // ์ŠคํŠธ๋ฆผ ์š”์†Œ๋ฅผ ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜
reduce(BinaryOperator) // ์š”์†Œ๋ฅผ ๋ˆ„์  ์—ฐ์‚ฐํ•˜์—ฌ ํ•˜๋‚˜์˜ ๊ฒฐ๊ณผ๋กœ ๋ฐ˜ํ™˜
count() // ์š”์†Œ์˜ ๊ฐœ์ˆ˜ ๋ฐ˜ํ™˜
findFirst() // ์ฒซ ๋ฒˆ์งธ ์š”์†Œ ๋ฐ˜ํ™˜
findAny() // ์š”์†Œ ์ค‘ ํ•˜๋‚˜๋ฅผ ๋ฐ˜ํ™˜ (๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ ์‹œ ์ฃผ๋กœ ์‚ฌ์šฉ)
allMatch(Predicate) // ๋ชจ๋“  ์š”์†Œ๊ฐ€ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š”์ง€ ํ™•์ธ
anyMatch(Predicate) // ํ•˜๋‚˜๋ผ๋„ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š”์ง€ ํ™•์ธ
noneMatch(Predicate) // ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ์š”์†Œ๊ฐ€ ์—†๋Š”์ง€ ํ™•์ธ
min(Comparator) // ์ตœ์†Œ๊ฐ’ ๋ฐ˜ํ™˜
max(Comparator) // ์ตœ๋Œ€๊ฐ’ ๋ฐ˜ํ™˜


์ŠคํŠธ๋ฆผ ์ƒ์„ฑ๋ถ€ํ„ฐ ์—ฐ์‚ฐ๊นŒ์ง€์˜ ํ๋ฆ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. 

List<String> names = List.of("BlueCool", "PYO", "MIN", "BlueMin");

// ๊ธธ์ด๊ฐ€ 4๋ณด๋‹ค ํฐ ์ด๋ฆ„๋งŒ ํ•„ํ„ฐ๋ง -> ๋Œ€๋ฌธ์ž๋กœ ๋ณ€ํ™˜ -> ์•ŒํŒŒ๋ฒณ์ˆœ ์ •๋ ฌ -> ์ถœ๋ ฅ
names.stream() // ์ŠคํŠธ๋ฆผ ์ƒ์„ฑ (Source)
.filter(name -> name.length() > 4) // ์ค‘๊ฐ„ ์—ฐ์‚ฐ: ์กฐ๊ฑด ํ•„ํ„ฐ๋ง (Predicate)
.map(String::toUpperCase) // ์ค‘๊ฐ„ ์—ฐ์‚ฐ: ๋ฌธ์ž์—ด์„ ๋Œ€๋ฌธ์ž๋กœ ๋ณ€ํ™˜ (Function)
.sorted() // ์ค‘๊ฐ„ ์—ฐ์‚ฐ: ์•ŒํŒŒ๋ฒณ์ˆœ ์ •๋ ฌ
.forEach(System.out::println); // ์ตœ์ข… ์—ฐ์‚ฐ: ์š”์†Œ ์ถœ๋ ฅ (Consumer)


3. ๊ธฐ๋ณธํ˜• ์ŠคํŠธ๋ฆผ (Primitive Stream)

Stream API๋Š” ๋งค์šฐ ํŽธ๋ฆฌํ•œ ๊ธฐ๋Šฅ์ด์ง€๋งŒ ๋ชจ๋“  ์ƒํ™ฉ์—์„œ ํ•ญ์ƒ ์ตœ์„ ์˜ ์„ ํƒ์€ ์•„๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ๊ฐ€ ์ž‘๊ฑฐ๋‚˜ ์—ฐ์‚ฐ์ด ๋‹จ์ˆœํ•œ ๊ฒฝ์šฐ์—๋Š” ๊ธฐ์กด์˜ ๋ฐ˜๋ณต๋ฌธ์ด ๋” ์ง๊ด€์ ์ด๊ฑฐ๋‚˜ ์„ฑ๋Šฅ ๋ฉด์—์„œ ์œ ๋ฆฌํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

๋˜ํ•œ ๊ธฐ๋ณธํ˜•์ด ์•„๋‹Œ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ๋ฐ•์‹ฑ(Boxing)๊ณผ ์–ธ๋ฐ•์‹ฑ(Unboxing) ๊ณผ์ •์—์„œ ๋ถˆํ•„์š”ํ•œ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด Java์—์„œ๋Š” ๊ธฐ๋ณธํ˜• ์ „์šฉ ์ŠคํŠธ๋ฆผ์„ ์ œ๊ณตํ•œ๋‹ค.

๋Œ€ํ‘œ์ ์ธ ๊ธฐ๋ณธํ˜• ์ŠคํŠธ๋ฆผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • IntStream
  • LongStream
  • DoubleStream

์ด๋Ÿฌํ•œ ๊ธฐ๋ณธํ˜• ์ŠคํŠธ๋ฆผ์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ธฐ๋ณธ ํƒ€์ž…์„ ์ง์ ‘ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด ๋ถˆํ•„์š”ํ•œ ๊ฐ์ฒด ์ƒ์„ฑ๊ณผ ๋ฐ•์‹ฑ/์–ธ๋ฐ•์‹ฑ ๋น„์šฉ์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

// 1๋ถ€ํ„ฐ 9๊นŒ์ง€์˜ ์ˆซ์ž ์ค‘ ์ง์ˆ˜๋งŒ ์„ ํƒํ•œ ๋’ค ํ•ฉ๊ณ„๋ฅผ ๊ตฌํ•˜๋Š” ์˜ˆ์‹œ
IntStream.range(1, 10)
.filter(n -> n % 2 == 0)
.sum();

์ˆซ์ž ์—ฐ์‚ฐ์—์„œ ๋ณด๋‹ค ํšจ์œจ์ ์ธ ์ŠคํŠธ๋ฆผ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.


4. ๋ณ‘๋ ฌ ์ŠคํŠธ๋ฆผ (Parallel Stream)

Stream API๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ‘๋ ฌ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์—ฌ๋Ÿฌ CPU ์ฝ”์–ด๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ๋ฅผ ๋™์‹œ์— ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ณ‘๋ ฌ ์ŠคํŠธ๋ฆผ์€ parallelStream() ๋˜๋Š” parallel() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8);

// ๋ณ‘๋ ฌ ์ŠคํŠธ๋ฆผ ์ƒ์„ฑ
numbers.parallelStream()
.map(n -> n * 2)
.forEach(System.out::println);

๋˜๋Š” ๊ธฐ์กด ์ŠคํŠธ๋ฆผ์— parallel()์„ ํ˜ธ์ถœํ•˜์—ฌ ๋ณ‘๋ ฌ ์ŠคํŠธ๋ฆผ์œผ๋กœ ์ „ํ™˜ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

numbers.stream()
.parallel()
.map(n -> n * 2)
.forEach(System.out::println);

โ€‹๋ณ‘๋ ฌ ์ŠคํŠธ๋ฆผ์€ ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ๊ฐ€ ํฌ๊ณ  ์—ฐ์‚ฐ๋Ÿ‰์ด ๋งŽ์€ ๊ฒฝ์šฐ ์„ฑ๋Šฅ ํ–ฅ์ƒ์— ๋„์›€์ด ๋  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์—ฐ์‚ฐ์ด ๋‹จ์ˆœํ•˜๊ฑฐ๋‚˜ ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ๊ฐ€ ์ž‘์€ ๊ฒฝ์šฐ, ๋™๊ธฐํ™”๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ, ์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•œ ์—ฐ์‚ฐ์ธ ๊ฒฝ์šฐ์—๋Š” ์˜คํžˆ๋ ค ์„ฑ๋Šฅ์ด ์ €ํ•˜๋  ์ˆ˜ ์žˆ๋‹ค.

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

์ด์ „ ๊ธ€
๐Ÿ“‘ ์ž๋ฐ” ์ž๋ฃŒํ˜• ์™„์ „ ์ •๋ฆฌ [๊ธฐ๋ณธํ˜•, ์ฐธ์กฐํ˜•, Wrapper ํด๋ž˜์Šค]
๋‹ค์Œ ๊ธ€
๐Ÿ”ฃ ๋ฉ”ํƒ€๋ฌธ์ž ์ดํ•ด๋กœ ์‹œ์ž‘ํ•˜๋Š” ์ •๊ทœํ‘œํ˜„์‹
์žฅ์‹์šฉ ๋กœ๊ณ