Coding/언어-JAVA

JAVA 스트림(Stream) #Day8

꿀딴지- 2023. 8. 16. 20:09

스트림(Stream) : 데이터의 흐름 _ 자바 8이후 도입

⇒ 스트림에 있는 메서드를 어떻게 사용할 수 있을지 익히는 것

  • 컬렉션이나 배열, 파일 등 데이터들을 가지고 람다식을 활용하여 반복처리하는 문법요소
    (컬렉션프레임웍이랑 연결해서 많이 씀)
  • 코드를 직관적으로 이해하고 작성할 수 있고, 다양한 유형의 데이터를 일관된 방식으로 다룰 수 있음
    (→ 너무 복잡해 지기 시작하면 가독성이 더 떨어짐)

 

스트림 특징 :

1. 생성, 중간연산, 최종연산 3단계의 파이프라인으로 구성할 수 있다

  • 컬렉션, 배열로부터 스트림을 생성하고(오리지날 스트림) → 중간연산으로 구현하여 처리 후(filter, map, …) → 최종연산으로 결과를 내놓고 끝
  • 중간연산은 여러개 가능하나, 최종연산은 1번만 가능하며 반드시 있어야 함

2. 원본 데이터 소스를 변경하지 않는다(read-only)

3. 일회용이다(onetime-only) : 최종연산 이후 중간연산 불가(추가작업 필요 시 다시 스트림 생성)

4. 스트림은 내부 반복으로 처리한다.

 

 

<스트림 생성> : 배열, 컬렉션, 임의의 수 등

// Arrays.stream
int[] scores = {100, 95, 90, 85, 80};
IntStream scoreStream = Arrays.stream(scores);

String[] langs = {"python", "java", "javascript", "c", "c++", "c#"};
Stream<String> langStream = Arrays.stream(langs);

// Collection.stream()
List<String> langList = new ArrayList<>();
langList = Arrays.asList("python", "java", "javascript", "c", "c++", "c#");
Stream<String> langListStream = langList.stream();

// Stream.of()
Stream<String> langListOfStream = Stream.of("python", "java", "javascript", "c", "c++", "c#");

// Ramdon하게 생성(무한 스트림)
IntStream ints = new Random().ints();
IntStream ints = new Random().ints(5); // 스트림 생성의 범위를 5개로 제한
IntStream ints = new Random().ints().limit(5);
IntStream intStream = IntStream.rangeClosed(1, 10); //특정 범위의 정수

<스트림 사용> 중간 연산 (Intermediate Operation)

  • distinct() : 중복제거
  • filter() : 조건에 맞는 데이터만을 정제. 조건이 참이되는 요소만 필터링. 조건은 람다식을 사용하여 정의
  • map() : 원하는 필드만 추출하거나 특정 형태로 변환. 람다식으로 정의
  • flatMap() : 중첩구조를 제거하고 단일컬렉션으로 만들어 줌
  • sorted() : 기본정렬(오름차순)
  • sorted(Comparator.reverseOrder()) : 내림차순
  • skip() : 일부요소 건너 뜀
  • limit() : 일부를 자름
  • peek() : 요소를 순회하며 특정작업 수행(forEach - 최종연산자)

IntStream, DoubleStream, LongStream : 기본형 스트림(스트림 내부 값이 객체가 아니라 기본타입임)

→ Stream<Integer> 오토 박싱/언박싱이 계속 일어나기 때문에 내부를 기본형으로 MapToInt 등으로 바꾼상태에서 스트림연산 필요

List<String> names = Arrays.asList("kimcoding", "javalee", "hackerna", "luckyguy");
int[] numbers = new int[]{1,2,3,4}

names.stream()
    .distinct() //중복제거
    .filter(element -> element.startsWith("k")) // k로 시작하는 요소만 필터링 
    .forEach(element -> System.out.println(element));

Arrays.stream(numbers)
    .filter(num -> num%2 ==0)
    .forEach(num-> System.out.println(num));

names.stream()
    .map(element -> element.toUpperCase()) // 요소들을 하나씩 대문자로 변환
    .forEach(element->System.out.println(element));

// 1~10 범위의 정수로 구성된 스트림 생성
// 앞의 5개의 숫자를 건너뛰고 숫자 6부터 출력
IntStream intStream = IntStream.rangeClosed(1, 10);
intStream.skip(5).forEach(System.out::println);

// 앞에서부터 5개의 숫자만 출력
intStream.limit(5).forEach(System.out::println);

<스트림 사용> 최종 연산 (Terminal Operation)

  • forEach() :
  • sum(), count(), average(), max(), min() : 기본집계
  • allMatch(), anyMatch(), noneMatch() : 매칭
  • reduce() : 스트림의 요소를 줄여나가면서 연산을 수행하고 최종결과 반환
  • collect() : 요소 수집
int[] intArray = {1,2,3,4,5};

// 평균
OptionalDouble average = Arrays.stream(intArr).average(); // OptionalDouble
double average = Arrays.stream(intArray).average().getAsDouble();
// 최대값
int max = Arrays.stream(intArray).max().getAsInt();

// anyMatch() 하나라도 일치하는지 반환 boolean
boolean result = Arrays.stream(intArray).anyMatch(element-> element % 3 == 0);

// 초기값이 없는 reduce() : 출력 30
int sum1 = Arrays.stream(intArray)
         .map(element -> element * 2)
         .reduce((a , b) -> a + b)
         .getAsInt();

// Student 객체로 구성된 배열 리스트 생성 
// 스트림 연산 결과를 Map으로 반환
List<Student> totalList = Arrays.asList(
    new Student("김코딩", 100, Student.Gender.Male),
    new Student("박해커", 80, Student.Gender.Male),
        );
        
Map<String, Integer> maleMap = totalList.stream()
    .filter(s -> s.getGender() == Student.Gender.Male)
    .collect(Collectors.toMap(
          student -> student.getName(), // Key
          student -> student.getScore() // Value
    ));

Optional , Optional double, OptonalInt, OptionalLong

→ 래퍼 클래스 : null에러가 발생하지 않도록 비어있으면 0을 반환.(값 자체가 없는것과 0인 것을 구분하기 위해 존재)

getAsInt()등을 통해 다시 기본형으로 변환(스트림 파이프라인과는 관계 없음)

'Coding > 언어-JAVA' 카테고리의 다른 글

JAVA 파일입출력(File I/O) #Day9  (0) 2023.08.17
JAVA 사용자 입출력(Scanner, Printf)  (0) 2023.08.17
JAVA 익명클래스, 람다 #Day8  (0) 2023.08.16
JAVA 에너테이션 #Day7  (0) 2023.08.12
JAVA 열거형(Enum) #Day7  (0) 2023.08.11