GiantStepDEV

์ŠคํŠธ๋ฆผ(Stream)?

  • ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋žจ์„ ์ด์šฉํ•ด ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ์†Œ์Šค(๋ฐฐ์—ด, ํ”„๋ ˆ์ž„ ์›Œํฌ ๋“ฑ)๋ฅผ ํ‘œ์ค€ํ™”๋œ ๋ฐฉ๋ฒ•์œผ๋กœ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•œ ๊ฒƒ
  • Stream์€ Collection ์•ˆ์— ์žˆ์Œ.

์ŠคํŠธ๋ฆผ์„ ์“ฐ๋Š” ์ด์œ ?

  • ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•ด์ง€๊ณ  ์ผ๊ด€์„ฑ ์œ ์ง€๊ฐ€ ๊ฐ€๋Šฅํ•ด์ง.
    โžก๏ธ ๋งฅ๋„๋‚ ๋“œ ๊ฐ•๋‚จ ์ง€์ ์ด๋“  ๋ถ€์‚ฐ ์ง€์ ์ด๋“  ํ–„๋ฒ„๊ฑฐ ๋ง›์ด ๋˜‘๊ฐ™์€ ๊ฒƒ ์ฒ˜๋Ÿผ ๋ˆ„๊ฐ€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋“  ๋™์ผํ•œ ํ˜•์‹์ด ๋‚˜์˜ฌ ์ˆ˜ ๋ฐ–์— ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ์˜ ์‹ ๋ขฐ๋„๊ฐ€ ๋†’์•„์ง€๊ณ  ๋ฒ„๊ทธ๊ฐ€ ์ƒ๊ธฐ์ง€ ์•Š์Œ.

์ŠคํŠธ๋ฆผ ํŠน์ง•

  1. ์ž๋ฃŒ์˜ ๋Œ€์ƒ๊ณผ ๊ด€๊ณ„์—†์ด ๋™์ผํ•œ ์—ฐ์‚ฐ ์ˆ˜ํ–‰
  2. ์™ธ๋ถ€ ๋ฐ˜๋ณต์„ ํ†ตํ•ด ์ž‘์—…ํ•˜๋Š” ์ปฌ๋ ‰์…˜๊ณผ ๋‹ฌ๋ฆฌ ๋‚ด๋ถ€ ๋ฐ˜๋ณต์„ ํ†ตํ•ด ์ž‘์—… ์ˆ˜ํ–‰ ( ๋ฐ˜๋ณต๋ฌธ ๋ฐฐ์ œ )
  3. ์ŠคํŠธ๋ฆผ์€ ํ•œ๋ฒˆ ์ƒ์„ฑ ๋œ ํ›„ ์ตœ์ข…์—ฐ์‚ฐ์„ ํ†ตํ•ด ์†Œ๋ชจ๋˜๋ฉด ์žฌ์‚ฌ์šฉ ๋ถˆ๊ฐ€ (์ตœ์ข…์—ฐ์‚ฐ์€ ํ•œ ๋ฒˆ๋งŒ ๊ฐ€๋Šฅ!!)
  4. ์›๋ณธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Œ
  5. ์ง€์—ฐ ์—ฐ์‚ฐ ์ง€์›
  6. ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ ์ง€์› parallelStream() :  ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์‰ฌ์›€
    ๋ณ‘๋ ฌ์ฒ˜๋ฆฌ๋กœ ๋ฐ”๊พธ๋ ค๋ฉด ์ŠคํŠธ๋ฆผ ์ƒ์„ฑ ํ•  ๋•Œ stream() ๋Œ€์‹  parallelStream()์œผ๋กœ ๋ฐ”๊พธ๋ฉด ๋จ.

์ŠคํŠธ๋ฆผ ๋™์ž‘ ํ๋ฆ„

์ŠคํŠธ๋ฆผ ์ƒ์„ฑ โžก๏ธ ์ŠคํŠธ๋ฆผ ์ค‘๊ฐœ ์—ฐ์‚ฐ(์ŠคํŠธ๋ฆผ์˜ ๋ณ€ํ™˜) โžก๏ธ ์ŠคํŠธ๋ฆผ ์ตœ์ข… ์—ฐ์‚ฐ

Integer[] arr = {1,2,3,4,5,6,7,8,9,10};
List<Integer> list = new ArrayList(Arrays.asList(arr));
list.stream().filter(s -> s.intValue() >= 5).forEach(e -> System.out.print(e + " ");

list.stream() ์ŠคํŠธ๋ฆผ ์ƒ์„ฑ

.filter(s -> s.intValue() >= 5) ์ค‘๊ฐ„ ์—ฐ์‚ฐ

.forEach(e -> System.out.print(e + " "); ์ตœ์ข… ์—ฐ์‚ฐ

list.stream().filter(s -> s.intValue() >= 5).forEach(System.out::println);
๋กœ ๋ฐ”๊ฟ€ ์ˆ˜๋„ ์žˆ์Œ!

๐Ÿถsum(), count()

Integer[] arr = {1,2,3,4,5,6,7,8,9,10};
List<Integer> list = new ArrayList<>(Arrays.asList(arr));

int sum = list.stream().mapToInt(e -> e).sum();
System.out.println("ํ•ฉ๊ณ„ : " + sum);
  • mapToInt(e -> e) : e(์š”์†Œ)๋ฅผ ๋Œ๋ฉด์„œ e๋ฅผ intํ˜•์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์ƒˆ๋กœ์šด ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ฐ˜ํ™˜
Integer[] arr = {1,2,3,4,5,6,7,8,9,10};
List<Integer> list = new ArrayList<>(Arrays.asList(arr));

int count = (int)list.stream().count();
System.out.println("ํšŸ์ˆ˜ : " + count);
  • count()๋Š” return ๊ฐ’์ด long ์ด๊ธฐ ๋•Œ๋ฌธ์— ํ˜•๋ณ€ํ™˜ ํ•„์š”

๐Ÿถ๋‚ด๋ถ€ ๋ฐ˜๋ณต์ž ์‚ฌ์šฉ

class Student {
	String name;
    int score;
    
    public Student(String name, int score) {
    	this.name = name;
        this.score = score;
    }
    
    public String getName() {
    	return name;
    }
    public int getScore() {
    	return score;
    }
}
import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    list.add(new Student("ํ™๊ธธ๋™", 87));
    list.add(new Student("์ด์ˆœ์‹ ", 65));
    list.add(new Student("ํ•œ์„๋ด‰", 98));
    
    list.stream().forEach(s -> {
    	String name = s.getName();
        int score = s.getScore();
        System.out.println(name + "-" + score);
    });
double avg = list.stream().mapToInt(s -> s.getScore()).average().getAsDouble();
System.out.prinf("ํ‰๊ท  ์ ์ˆ˜ : %.2f", avg);

๐Ÿถ๋ฐฐ์—ด๋กœ ๋ถ€ํ„ฐ ์ŠคํŠธ๋ฆผ ๋งŒ๋“ค๊ธฐ

  • stream์€ Collection์— ์žˆ์–ด์„œ ๋ฐฐ์—ด์€ stream ์“ธ ์ˆ˜ ์—†์Œ.
    Stream<E> ์ฐธ์กฐ๋ณ€์ˆ˜๋ช… = Arrays.stream(๋ฐฐ์—ด๋ช…);
import java.util.Arrays;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
    	String[] arr = {"ํ™๊ธธ๋™", "ํ•œ์„๋ด‰", "์ด์ˆœ์‹ ", "์‹ ์‚ฌ์ž„๋‹น", "์•ˆ์ค‘๊ทผ", "๊ฐ•๊ฐ์ฐฌ"};
    	Stream<String> stream1 = Arrays.stream(arr);
    	stream1.forEach(e - > System.out.print(e + " "));
    
    	Stream<String> stream2 = Arrays.stream(arr, 1, 3);
    	stream2.forEach(e -> System.out.print(e + " ");

	}
}
ํ™๊ธธ๋™ ํ•œ์„๋ด‰ ์ด์ˆœ์‹  ์‹ ์‚ฌ์ž„๋‹น ์•ˆ์ค‘๊ทผ ๊ฐ•๊ฐ์ฐฌ 
ํ•œ์„๋ด‰ ์ด์ˆœ์‹ 

๐Ÿถ์ˆซ์ž ๋ฒ”์œ„๋กœ ๋ถ€ํ„ฐ ์ŠคํŠธ๋ฆผ ๋งŒ๋“ค๊ธฐ

IntStream stream = IntStream.rangeClosed(1,100);
int sum = stream.sum();
System.out.println("ํ•ฉ๊ณ„ : " + sum);

๐ŸถํŒŒ์ผ๋กœ ๋ถ€ํ„ฐ ์ŠคํŠธ๋ฆผ ์–ป๊ธฐ(path)

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) throws IOException {
        Path path = Paths.get("src/์ŠคํŠธ๋ฆผ์˜ˆ์ œ4_0208/chicken.txt");
        Stream<String> stream = Files.lines(path, Charset.defaultCharset());
        stream.forEach(System.out::println);
        System.out.println();
    }
}

๐Ÿถ์ค‘๊ฐœ ์—ฐ์‚ฐ

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

์ŠคํŠธ๋ฆผ ํ•„ํ„ฐ๋ง

filter()

  • ์กฐ๊ฑด์— ๋งž๋Š” ์š”์†Œ๋งŒ์œผ๋กœ ๊ตฌ์„ฑ๋œ ์ƒˆ๋กœ์šด ์ŠคํŠธ๋ฆผ ๋ฐ˜ํ™˜
IntStream stream = IntStream.of(7,5,5,2,1,3,5,4,5,6);
stream.filter(n -> n % 2 != 0).forEach(e -> System.out.print(e + " "));
7 5 5 1 3 5 5

distinct()

  • ์ŠคํŠธ๋ฆผ์—์„œ ์ค‘๋ณต๋œ ์š”์†Œ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ์ƒˆ๋กœ์šด ์ŠคํŠธ๋ฆผ ๋ฐ˜ํ™˜
IntStream stream = IntStream.of(7,5,5,2,1,3,5,4,5,6);
stream.distinct().forEach(s -> System.out.print(s + " ");
7 5 2 1 3 4 6

์ŠคํŠธ๋ฆผ ๋ณ€ํ™˜

map()

  • ์ž…๋ ฅํ•œ ์š”์†Œ ๊ทธ๋Œ€๋กœ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ฐ˜ํ™˜
Stream<String> stream = Stream.of("HTML", "CSS", "JAVA", "JAVASCRIPT");
stream.map(e -> e.length()).forEach(e -> System.out.print(e + " "));
4 3 4 10

flatMap()

  • ์ž…๋ ฅํ•œ ์š”์†Œ๋ฅผ ๊ฐ€์žฅ ์ž‘์€ ๋‹จ์œ„๋กœ ๋ฐ˜ํ™˜
    (์˜ˆ์ œ์ฒ˜๋Ÿผ split()ํ•˜๋ฉด split ์กฐ๊ฑด๋Œ€๋กœ ๋ฐ˜ํ™˜๋จ)
  • map()์€ split() ํ•ด๋„ ์•ˆ์ชผ๊ฐœ์ง
String[] arr = {"I study hard", "You study JAVA", "I am hungry"};
Stream<String> stream4 = Arrays.stream(arr);
stream4.flatMap(s -> Stream.of(s.split(" "))).forEach(System.out::println);
I
study
hard
You
study
JAVA
I
am
hungry

map()์œผ๋กœ ์‹คํ–‰์‹œ ๊ฒฐ๊ณผ

java.util.stream.ReferencePipeline$Head@3567135c
java.util.stream.ReferencePipeline$Head@327471b5
java.util.stream.ReferencePipeline$Head@4157f54e

์ŠคํŠธ๋ฆผ ์ œํ•œ

limit()

  • ํ•ด๋‹น ์ŠคํŠธ๋ฆผ์˜ ์ฒซ ๋ฒˆ์งธ ์š”์†Œ๋ถ€ํ„ฐ ์ „๋‹ฌ๋œ ๊ฐœ์ˆ˜ ๋งŒํผ์˜ ์š”์†Œ๋กœ๋งŒ ์ด๋ฃจ์–ด์ง„ ์ƒˆ๋กœ์šด ์ŠคํŠธ๋ฆผ ๋ฐ˜ํ™˜
IntStream stream5 = IntStream.range(0, 10);
stream5.limit(5).forEach(n -> System.out.print(n + " "));
0 1 2 3 4

skip()

  • ํ•ด๋‹น ์ŠคํŠธ๋ฆผ์˜ ์ฒซ ๋ฒˆ์งธ ์š”์†Œ๋ถ€ํ„ฐ ์ „๋‹ฌ๋œ ๊ฐœ์ˆ˜ ๋งŒํผ์˜ ์š”์†Œ๋ฅผ ์ œ์™ธํ•˜๊ณ  ์ถœ๋ ฅ
IntStream stream6 = IntStream.range(0, 10);
stream6.skip(5).forEach(n -> System.out.print(n + " "));
stream7.skip(3).limit(5).forEach(n -> System.out.print(n + " "));
5 6 7 8 9
3 4 5 6 7

์ŠคํŠธ๋ฆผ ์ •๋ ฌ

sorted()

  • ํ•ด๋‹น ์ŠคํŠธ๋ฆผ์„ ์ฃผ์–ด์ง„ ๋น„๊ต์ž(comparator)๋ฅผ ์ด์šฉํ•˜์—ฌ ์ •๋ ฌ
Stream<String> stream8 = Stream.of("HTML", "CSS", "JAVA", "JAVASCRIPT");
Stream<String> stream9 = Stream.of("HTML", "CSS", "JAVA", "JAVASCRIPT");
stream8.sorted().forEach(e -> System.out.print(e + " "));
stream9.sorted(Comparator.reverseOrder()).forEach(e -> System.out.print(e + " "));
CSS HTML JAVA JAVASCRIPT 
JAVASCRIPT JAVA HTML CSS

์ŠคํŠธ๋ฆผ ์ตœ์ข… ์—ฐ์‚ฐ

Stream.of() : ์š”์†Œ์˜ ์ถœ๋ ฅ

Stream<String> stream = Stream.of("ํ•˜๋‚˜", "๋‘˜", "์…‹", "๋„ท");
stream.forEach(System.out::println);
ํ•˜๋‚˜
๋‘˜
์…‹
๋„ท

์š”์†Œ์˜ ์†Œ๋ชจ

  • ์ŠคํŠธ๋ฆผ์˜ ์š”์†Œ๋ฅผ ์†Œ๋ชจํ•˜์—ฌ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰

โญ reduce() : ์ฒซ๋ฒˆ์งธ ์š”์†Œ์™€ ๋‘๋ฒˆ์งธ ์š”์†Œ๋ฅผ ๊ฐ€์ง€๊ณ  ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰, ๊ทธ ๊ฒฐ๊ณผ์™€ ์„ธ๋ฒˆ์งธ ์š”์†Œ๋ฅผ ๊ฐ€์ง€๊ณ  ๋‹ค์‹œ ์—ฐ์‚ฐ

Stream<String> stream1 = Stream.of("ํ•˜๋‚˜", "๋‘˜", "์…‹", "๋„ท");
Stream<String> stream2 = Stream.of("ํ•˜๋‚˜", "๋‘˜", "์…‹", "๋„ท");
IntStream stream3 = IntStream.of(7,5,5,2,1,3,5,4,6);
OptionalInt sum = stream3.reduce((s1,s2) -> s1 + s2);
System.out.println(sum.getAsInt());
Optional<String> rst1 = stream1.reduce((s1, s2) -> s1 + "+" + s2); // Optional์€ NullpointerException ๋ฐฉ์ง€
rst1.ifPresent(System.out::println); // ์—†์œผ๋ฉด null ๋ฐ˜ํ™˜
38
ํ•˜๋‚˜+๋‘˜+์…‹+๋„ท

์š”์†Œ์˜ ๊ฒ€์‚ฌ

anyMatch() : ํ•ด๋‹น ์ŠคํŠธ๋ฆผ์˜ ์ผ๋ถ€ ์š”์†Œ๊ฐ€ ์กฐ๊ฑด์— ๋งŒ์กฑํ•˜๋ฉด true

allMatch() : ํ•ด๋‹น ์ŠคํŠธ๋ฆผ์˜ ๋ชจ๋“  ์š”์†Œ๊ฐ€ ์กฐ๊ฑด์— ๋งŒ์กฑํ•˜๋ฉด true

noneMatch() : ํ•ด๋‹น ์ŠคํŠธ๋ฆผ์˜ ๋ชจ๋“  ์š”์†Œ๊ฐ€ ํŠน์ • ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ true

IntStream stream6 = IntStream.of(30,90,70,10);
IntStream stream7 = IntStream.of(30,90,70,10);
IntStream stream8 = IntStream.of(30,90,70,10);
System.out.println(stream6.anyMatch(n -> n > 80)); // true
System.out.println(stream7.allMatch(n -> n > 9)); // true
System.out.println(stream8.noneMatch(n -> n > 90)); // trse

์š”์†Œ์˜ ํ†ต๊ณ„

count()

IntStream stream9 = IntStream.of(30,90,70,10);
System.out.println(stream9.count());
4

max()

IntStream stream10 = IntStream.of(30,90,70,10);
System.out.println(stream10.max().getAsInt());
90

min()

IntStream stream11 = IntStream.of(30,90,70,10);
System.out.println(stream11.min().getAsInt());
10
System.out.println(stream10.max();
์ถœ๋ ฅํ•˜๋ฉด OptionalInt๊ฐ€ ๋ถ™์–ด์„œ ๋‚˜์˜ค๋ฏ€๋กœ
System.out.println(stream10.max().getAsInt() ๋กœ ์ถœ๋ ฅํ•  ๊ฒƒ

์š”์†Œ์˜ ์—ฐ์‚ฐ

IntStream stream12 = IntStream.of(30,90,70,10);
DoubleStream stream13 = DoubleStream.of(30.3,90.9,72.3,10.1);
System.out.println(stream12.sum());
System.out.println(stream13.average().getAsDouble());
200
50.9

๐Ÿธ ์‹ค์Šต ์˜ˆ์ œ

๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ ์ถ”์ถœ

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<TravelCustomer> customerList = new ArrayList<>();
        customerList.add(new TravelCustomer("ํ™๊ธธ๋™", 30, 3000));
        customerList.add(new TravelCustomer("๊น€๋”ธ๊ธฐ", 13, 2000));
        customerList.add(new TravelCustomer("์ด์ˆœ์‹ ", 25, 2500));
        customerList.add(new TravelCustomer("๊ฐ•๊ฐ์ฐฌ", 19, 4500));
        System.out.println("๊ณ ๊ฐ ๋ช…๋‹จ ์ถœ๋ ฅ");
        customerList.stream().map(c -> c.getName()).forEach(System.out::println);
        int total = customerList.stream().mapToInt(c -> c.getPrice()).sum();
        System.out.println("์ด ์—ฌํ–‰ ๋น„์šฉ : " + total + "์›");
        System.out.println("== 20์„ธ ์ด์ƒ ์„ฑ์ธ ์ถœ๋ ฅ ==");
        customerList.stream().filter(e -> e.age >= 20)
                .map(c -> c.getName())
                .sorted()
                .forEach(System.out::println);
    }
}

class TravelCustomer {
    String name;
    int age;
    int price;

    public TravelCustomer(String name, int age, int price) {
        this.name = name;
        this.age = age;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public int getPrice() {
        return price;
    }
}
profile

GiantStepDEV

@kongmi

ํฌ์ŠคํŒ…์ด ์ข‹์•˜๋‹ค๋ฉด "์ข‹์•„์š”โค๏ธ" ๋˜๋Š” "๊ตฌ๋…๐Ÿ‘๐Ÿป" ํ•ด์ฃผ์„ธ์š”!