티스토리 뷰

JAVA

[Java] stream 알아보기

DevBee 2022. 2. 11. 09:54

스트림

컬렉션의 저장 요소를 하나씩 참조하여 람다식으로 처리할 수 있도록 해주는 반복자

 

스트림 구성

  • 중간 처리 : 필터링, 매핑, 정렬, 그룹핑 등
  • 최종 처리 : 합계, 평균, 카운팅 등

 

특징

  • 람다식으로 요소 처리 코드를 제공
  • 내부 반복자를 사용한 병렬 처리
  • 중간, 최종 처리 가능

 

스트림 얻기

스트림을 사용하기 위해 먼저 스트림을 얻어야 합니다.

 

  • 컬렉션으로부터 스트림 얻기
    • stream = studentList.stream();
  • 배열로부터 스트림 얻기
    • stream = Arrays.stream(strArray);
  • 숫자 범위로부터 스트림 얻기
    • stream = IntStream.rangeClosed(1, 100);
  •  파일로부터 스트림 얻기
    • Path path = Paths.get(“*/*.txt”);
    • stream = Files.lines(path, Charset.defaultCharset());
  • 디렉토리로부터 스트림 얻기
    • stream = Files.list(path)

 

스트림 사용하기

위에서 스트림을 얻었으니 얻은 스트림을 처리하는 방법의 종류를 살펴보겠습니다.

 

1) 중간 처리

  • 필터링
    • distinct() : 중복 제거
    • filter(Predicate ...) : 매개값으로 주어진 Predicate가 true를 리턴하는 요소만 필터링
public static void main(String[] args){

    List<String> names = Arrays.asList("강성현", "강성현", "깡냉", "강냉", "깡냉");
    
    names.stream()
    	 .distinct()
         .filter(n -> n.startsWith("강")) // 중복 제거 후 필터링 
         .forEach(System.out::println);
         
}

//-- 결과 --//
강성현
강냉
    • 매핑
      • flatMapXXX() : Array나 Object로 감싸져 있는 모든 원소를 단일 원소 스트림으로 반환
      • mapXXX() : 단일 스트림의 원소를 매핑시킨 후 매핑시킨 값을 다시 스트림으로 반환
      • mapToInt : 스트림을 IntStream으로 변환
      • mapToDouble : 스트림을 DoubleStream으로 변환
      • asDoubleStream() : IntStream을 DoubleStream으로 변환
      • boxed() : int, long, double 요소를 Integer, Long, Double 요소로 박싱. 즉, wrapper 클래스로 변환
public static void main(String[] args) {

    ArrayList<string> list = new ArrayList<>(Arrays.asList("Apple","Banana","Melon"));
    list.map(String::toUpperCase)
        .forEach(System.out::println);
    
    System.out.println();
    
    //Creating an IntStream
    IntStream stream = IntStream.of(3, 5, 9, 12, 14);
  
    //Using DoubleStream asDoubleStream()
    stream.asDoubleStream()
          .forEach(System.out::println);
}

//-- 결과 --//
APPLE
BANANA
MELON

3.0
5.0
9.0
12.0
14.0
  • 정렬
    • sorted() : 정렬. 객체 요소일 경우에는 클래스가 Comparable을 구현해야 함.
public class Cat {
    public Cat(int number, String name) {
        this.number = number;
        this.name = name;
    }
	
    private int number;
    private String name;
	
	// getter, setter
}

//----------------------------------------------------------------------------//
public class CatStream {

    public static void main(String[] args) {
        List<Cat> cats = Arrays.asList(
            new Cat(2, "sana"),    
            new Cat(3, "momo"),
            new Cat(1, "mina"),    
            new Cat(4, "jihyo")
        );

        cats.stream()
            .sorted(Comparator.comparing(Cat::getNumber)) // 정렬 Cat의 number 변수로 정렬한다.
            .forEach(System.out::println); // 출력
    }
}

//-- 결과 --//
Cat [number=1, name=mina]
Cat [number=2, name=sana]
Cat [number=3, name=momo]
Cat [number=4, name=jihyo]
  • 루핑
    • peek() : 반복. 이후 반드시 최종 처리 메소드가 호출되어야 함.

 

2) 최종 처리

  • 루핑
    • forEach() : 반복. peek() 과 같지만 최종 처리임.
  • 매핑
    • allMatch : 모든 요소들이 매개값(Predicate)으로 주어진 조건을 만족하는지 확인
    • anyMatch : 최소 한 개의 요소가 주어진 조건을 만족하는지 확인
    • nonMatch : 모든 요소들이 주어진 조건을 만족하지 않는지 확인
public static void main(String[] args){
    int[] intArr = {2, 4, 6};
    
    boolean result = Arrays.stream(intArr)
                           .allMatch(a -> a%2 == 0); 
    System.out.println("2의 배수? " + result);
    
    result = Arrays.stream(intArr)
                   .anyMatch(a -> a%3 == 0);
    System.out.println("3의 배수가 하나라도 있나? " + result);
    
    result = Arrays.stream(intArr)
                   .noneMatch(a -> a%3 == 0);
    System.out.println("3의 배수가 없나? " + result);
}
    
//-- 결과 --//
2의 배수? true 
3의 배수가 하나라도 있나? true 
3의 배수가 없나? false
  • 기본 집계
    • sum : 합 구하기
    • count : 요소의 개수 
    • average : 평균 구하기
    • max : 최댓값 구하기
    • min : 최솟값 구하기
public static void main(String[] args){
    int[] intArr = {1, 2, 3, 4, 5}; 
    
    // count() 요소 개수 반환 
    long count = Arrays.stream(intArr)
                       .filter(n -> n%2 == 0)
                       .count(); 
    System.out.println(count); 
    
    // sum() 요소 총합 반환 
    long sum = Arrays.stream(intArr)
                     .filter(n -> n%2 == 0)
                     .sum();
    System.out.println(sum); 
    
    // average() 요소 평균 반환
    double avg = Arrays.stream(intArr)
                       .filter(n -> n%2 == 0)
                       .average()
                       .getAsDouble();
    System.out.println(avg);
    
    // max() 최대값 반환
    int max = Arrays.stream(intArr)
                    .filter(n -> n%2 == 0)
                    .max()
                    .getAsInt();
    System.out.println(max);
    
    // min() 최소값 반환
    int min = Arrays.stream(intArr)
                    .filter(n -> n%2 == 0)
                    .min()
                    .getAsInt();
    System.out.println(min);
    
    // findFirst() 첫 번째 요소 반환
    int first = Arrays.stream(intArr)
                      .filter(n -> n%2 == 0)
                      .findFirst()
                      .getAsInt();
    System.out.println(first);
}

//-- 결과 --//
2
6
3.0
4
2
2

 

❗️클래스의 메소드를 참조할 떄 :: 를 사용하여 간단하게 표현할 수 있음

...
    .forEach(s -> System.out.println(s));
    
//-- 메소드 참조 사용 시 --//
...
    .forEach(System.out::println);

 

참고

'JAVA' 카테고리의 다른 글

[JAVA] Annotation 알아보기  (0) 2022.02.19
[Java Version] Java 8 vs 11vs 17  (0) 2022.02.11
[Java Study 15] 람다식  (0) 2021.05.15
[Java Study 14] 제네릭  (1) 2021.05.15
[Java Study 13] I/O  (0) 2021.05.13
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함