파이널 프로젝트-주간블로깅 4회

Moon·2024년 9월 5일

Mini, Final

목록 보기
7/8

https://mangkyu.tistory.com/114

[ Collection의 Stream 생성 ]
Collection 인터페이스에는 stream()이 정의되어 있기 때문에, Collection 인터페이스를 구현한 객체들(List, Set 등)은 모두 이 메소드를 이용해 Stream을 생성할 수 있다. stream()을 사용하면 해당 Collection의 객체를 소스로 하는 Stream을 반환한다.

// List로부터 스트림을 생성
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> listStream = list.stream();
 ```
 
[ 배열의 Stream 생성 ]
배열의 원소들을 소스로하는 Stream을 생성하기 위해서는 Stream의 of 메소드 또는 Arrays의 stream 메소드를 사용하면 된다.
// 배열로부터 스트림을 생성
  
  ```java
Stream<String> stream = Stream.of("a", "b", "c"); //가변인자
Stream<String> stream = Stream.of(new String[] {"a", "b", "c"});
Stream<String> stream = Arrays.stream(new String[] {"a", "b", "c"});
Stream<String> stream = Arrays.stream(new String[] {"a", "b", "c"}, 0, 3); //end범위 포함 x
// members 변수는 여러 Member 객체를 담은 컬렉션이다.
// teenager 변수는 20살 아래는 Member 객체를 담을 컬렉션이다.
List<Member> teenagers = new ArrayList<>();
for (Member member : members) {
    if(member.getAge() < 20) {
        teenagers.add(member);
    }
}

List<String> teenagerNames = new ArrayList<>();
for (Member teenager : teenagers) {
    teenagerNames.add(teenager.getName());
}

위 코드를 스트림을 이용하면 다음과 같이 변환할 수 있다.

// members 변수는 여러 Member 객체를 담은 컬렉션이다.
// 해당 스트림 연산에서 데이터 소스는 members 컬렉션이다.
List<String> teenagerNames = members.stream()
        .filter(member -> member.getAge() < 20) // 내부 반복
        .map(Member::getName) // 파이프라이닝이 가능하다. 내부 반복
        .collect(toList());

[ 특정 연산 수행 - forEach ]
Stream의 요소들을 대상으로 어떤 특정한 연산을 수행하고 싶은 경우에는 forEach 함수를 이용할 수 있다. 앞에서 살펴본 비슷한 함수로 peek()가 있다. peek()는 중간 연산으로써 실제 요소들에 영향을 주지 않은 채로 작업을 진행하고, Stream을 반환하는 함수였다. 하지만 forEach()는 최종 연산으로써 실제 요소들에 영향을 줄 수 있으며, 반환값이 존재하지 않는다. 예를 들어 요소들을 출력하기를 원할 때 다음과 같이 forEach를 사용할 수 있다.

names.stream()
    .forEach(System.out::println);

기본형 특화 스트림
스트림은 숫자 스트림을 효율적으로 처리할 수 있도록 IntStream, DoubleStream, LongStream을 제공한다. 이들은 숫자 스트림의 합계를 계산하는 sum, 최대값 요소를 검색하는 max, 요소들의 평균값을 계산하는 average 등과 같이 자주 사용하는 숫자 관련 리듀싱 연산 수행 메서드를 제공한다. 또한 필요할 때 기본형 값을 다시 객체 스트림으로 복원하도록 boxed 메서드를 제공한다.

List<Member> memberList = Arrays.asList(
    new Member("member1", 20),
    new Member("member2", 19),
    new Member("member3", 18),
    new Member("member4", 15)
);

IntStream intStream = memberList.stream()
    .mapToInt(Member::getAge); // mapToInt는 IntStream을 반환한다.

Stream<Integer> boxed = memberList.stream()
    .mapToInt(Member::getAge)
    .boxed(); // boxed를 통해 IntStream을 Stream<Integer>로 다시 박싱할 수 있다.

OptionalDouble average = memberList.stream()
    .mapToInt(Member::getAge)
    .average(); // IntStream 등의 기본형 스트림은 average와 같은 다양한 유틸리티 메서드를 지원한다.

// OptionalDouble은 getAsDouble 등과 같이 꺼내어 사용할 수 있다.
System.out.println(average.getAsDouble());
// Stream이 비어있어서 average 값이 없는 상황에는 다음과 같이 기본값을 지정할 수 있다.
System.out.println(average.orElse(0));

https://yoo-dev.tistory.com/38

배열로 스트림 만들기
배열을 인수로 받는 정적 메서드 Arrays.stream을 이용해서 스트림을 만들 수 있다.

int[] numbers = {2, 3, 5, 7, 11, 13};
int sum = Arrays.stream(numbers).sum();

https://devbksheen.tistory.com/entry/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94-%EC%8A%A4%ED%8A%B8%EB%A6%BCStream-%EB%A7%8C%EB%93%A4%EA%B8%B0?category=877739

💡forEach()
forEach()는 종단 연산에 속한다.

학생의 정보를 가지고 있는 StudentDTO클래스가 있다고 할 때, 해당 클래스에 각각 정보를 넣어주고, printStudentNames 메서드를 동해 학생의 이름을 출력하도록 했다. 자세한 설명은 주석을 참고하자.

package stream;

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

public class StudentForEachSample {

    public static void main(String[] args) {
        StudentForEachSample sample = new StudentForEachSample();
        List<StudentDTO> studentList = new ArrayList<>();
        studentList.add(new StudentDTO("요다", 43, 99, 10));
        studentList.add(new StudentDTO("만두", 30, 71, 85));
        studentList.add(new StudentDTO("찐빵", 32, 81, 75));
        sample.printStudentNames(studentList);
    }

    public void printStudentNames(List<StudentDTO> studentList) {
    
        //1) DTO List에서 forEach를 통해서 각각의 DTO를 뽑아내서, 변수에 담아서, 걔의 getName을 출력
        studentList.stream().forEach(student -> System.out.println(student.getName()));
         //2) DTO List를 List<String>의 형태로 바꿔서 forEach로 뽑는다.
         //여기서 map()은 "데이터를 특정 데이터로 변환" 하는 역할을 한다.
        studentList.stream().map(student -> student.getName()).forEach(name -> System.out.println(name));
       
    }
}

참고로 주석에서 2번의 map과 forEach의 출력 문장은 각각 다음과 같이 처리할 수도 있다.

map(StudentDTO::getName)
forEach(System.out::println)

https://mong-dev.tistory.com/28

0개의 댓글