JAVA

[Java] 스트림(Stream)

바켠주 2024. 6. 11. 20:35
728x90

스트림

반복을 위해 사용

특징

  • 한 번 사용된 스트림은 재사용할 수 없다.
  • 생성, 가공, 최종 과정을 거친다.

스트림 생성

  • 배열(Array)
  • 리스트(List)
  • generate 메소드
  • 범위 지정
  • 빌더(Builder)

1. 배열 → 스트림

stream()

int[] arr = new int[] {1,2,3,4,5};
Stream<Integer> stream = (Stream<Integer>)stream(arr);
Stream<Integer> st1 = stream(new Integer[] {1,2,3,4,5});

2. 리스트 → 스트림

.stream()

List<Integer> list = new ArrayList<>();
Stream<Integer> stream = list.stream();

3. 빌더 → 스트림

Stream.

Stream<Integer> stream = Stream.<Integer>builder()
	.add(1).add(2).add(3)
    .build();

스트림 가공

  • map
  • filter
  • sorted

1. map

스트림의 값을 하나씩 가져와 변환시켜 새로운 스트림으로 생성한다.

 

map의 매개변수로 Function 함수형 인터페이스를 사용한다.

Stream<Integer> stream = list.stream().map(n -> n * 2);

 

리스트의 숫자를 하나씩 가져와 2를 곱해 새로운 스트림으로 생성한다.

2. filter

스트림의 값을 하나씩 가져와 조건에 맞는 값만 새로운 스트림으로 생성한다.

 

filter의 매개변수로 Predicate 함수형 인터페이스를 사용한다.

Stream<Integer> stream = list.stream()
	.filter(n -> n % 2 == 0);

 

리스트의 숫자를 하나씩 가져와 짝수인 수만 새로운 스트림으로 생성한다.

3. sorted

스트림의 값을 두 개씩 가져와 비교하고 정렬한다.

 

sorted의 매개변수로 Comparator 함수형 인터페이스를 사용한다.

 

기본적으로 오름차순 정렬된다.

 

내림차순 정렬은 (뒤에 값 - 앞에 값)을 해준다

sorted((o1, o2) -> o1 - o2) => 오름차순(기본)
sorted((o1, o2) -> o2 - o1) => 내림차순

 

☑️문자열 정렬

Stream<String> strStream = list.stream().sorted(); // 오름차순 정렬
Stream<String> strStreamDesc = list.stream()
	.sorted((o1, o2) -> Objects.hash(o2) - Objects.hash(o1)); //내림차순 정렬

 

내림차순의 경우 문자열을 해시코드로 변경해 비교한다.

 

☑️ 숫자 정렬

Stream<Integer> intStream = list.stream().sorted(); //오름차순
Stream<Integer> intStream = list.stream()
	.sorted((o1, o2) -> o2 - o1); //내림차순

 

☑️ 객체 정렬

아래 코드와 같은 Phone 클래스를 생성하고 리스트의 제네릭의 타입으로 지정하고 값을 대입한다.

@Builder
@Data
public class Phone {
    private Integer number;
    private String model;
}

//리스트 생성
List<Phone> list = List.of(
	Phone.builder().number(1).model("아이폰").build(),
	Phone.builder().number(2).model("갤럭시").build(),
	Phone.builder().number(3).model("샤오미").build()
);

 

정렬할 기준을 정하고 객체의 기준값에 접근해 값을 가져와 비교한다.

//모델명 기준
Stream<Phone> phoneStream = list.stream()
	.sorted((o1, o2) -> String.CASE_INSENSITIVE_ORDER.compare(o1.getModel(), o2.getModel()));
//넘버 기준
Stream<Phone> phoneStream = list.stream()
	.sorted((o1, o2) -> o2.getNumber() - o1.getNumber());

model명을 기준으로 정렬하고 싶은 경우 가져온 phone 객체에서 getModel로 접근해 값을 가져와 비교한다.

 

String을 비교하기 위해 아래 코드를 사용한다.

String.CASE_INSENSITIVE_ORDER.compare()

스트림 결과 

  • collect
  • forEach

1. collect 

스트림을 리스트로 변환할 때 사용한다.

List<Phone> list = phoneStream.collect(Collectors.toList());

list에 위에서 만든 phoneStream을 리스트로 변환해 대입한다.

2. forEach

반복해서 결과를 출력할 때 사용한다.

phoneStream.forEach(phone -> System.out.println(phone));
phoneStream.forEach(System.out :: println);

스트림 객체의 요소를 반복해 출력한다.