스트림에서 제공하는 map() 메소드는 메소드 내부에 전달된 람다식이 적용되어 변경된 스트림 데이터를 반환한다.
예에서 보듯이 문자열 스트림의 각 데이터를 정수로 변환한 후 reduce() 메소드를 이용해 합계를 누적하여 합계를 반환하고 그 결과를 출력하는 간단한 코드이다.
스트림 연산의 마지막에 사용된 get() 메소드는 reduce()로 처리된 데이터를 최종 꺼내는 메소드 이다.
MapTest .java
import java.util.Arrays;
public class MapTest {
public static void main(String[] args) {
Integer data = Arrays.stream(new String[]{"210", "44", "56", "40"})
.map(n -> Integer.parseInt(n)) // 문자열 요소를 정수로 변환
.reduce((x, y) -> x + y) // 합계를 구한 후
.get(); // 꺼내어 정수로 반환
System.out.println(data);
}
}
** 결과
350
그럼, 좀 더 다양한 예로 스트림의 연산자의 예를 확실히 알아보자
이미 충분히 연습을 했기 때문에 코드에 대한 자세한 설명은 생략할텐데, 다만 이번에 스트림으로 다루는 데이터는 사용자가 정의한 클래스이고, Lombok을 추가하여 필요한 멤버 메소드를 간단히 처리하였다.
MapTest1.java
@Setter
@Getter
@AllArgsConstructor
@ToString
class Student {
private String name;
private int jumsu;
}
public class MapTest1 {
public static void main(String[] args) {
// 1) 스트림으로 변환함
Stream<Student> stm = Stream.of(
new Student("강아지", 89),
new Student("송아지", 90),
new Student("망아지", 85),
new Student("원숭이", 76),
new Student("레오파드", 100));
System.out.println("총 학생 수: " + stm.map(x -> x.getJumsu()).count());
List<Student> a = Arrays.asList(
new Student("강아지", 89),
new Student("장수풍뎅이", 90),
new Student("망아지", 85),
new Student("말벌", 76),
new Student("레오파드", 100)
);
Stream<Student> stm2 = a.stream();
System.out.println("\n점수가 90점 이상인 학생");
stm2.filter(x -> x.getJumsu() >= 90).forEach(System.out::println);
System.out.print("\n전체 총점: ");
stm2 = a.stream();
Optional<Integer> sum = stm2.map(x -> x.getJumsu()).reduce((x, y) -> x + y);
sum.ifPresent(System.out::print);
}
}
** 결과
총 학생 수: 5
점수가 90점 이상인 학생
Student(name=장수풍뎅이, jumsu=90)
Student(name=레오파드, jumsu=100)
전체 총점: 440
다음의 코드도 앞서 본 MapTest1.java와 유사한데, 이번에는 처리할 자료가 파일로 있어 파일을 읽어 들이는 작업을 추가하였다.
텍스트 형태로 제공되는 자료 “birth_2021.txt”는 한국 여성정책 연구원에서 제공하는 2021년도 각 행정구역별 출산율 통계 자료의 일부로써 자세한 내용을 확인하고 싶으면 아래 URL로 접속하여 확인해 보길 권한다.
데이터 참고: https://gsis.kwdi.re.kr/statHtml/statHtml.do?orgId=338&tblId=DT_1AD0610R
birth_2021.txt
서울특별시 0.626
부산광역시 0.728
대구광역시 0.785
인천광역시 0.778
광주광역시 0.896
대전광역시 0.810
울산광역시 0.940
세종특별자치시 1.277
경기도 0.853
강원도 0.979
충청북도 0.949
충청남도 0.963
전라북도 0.850
전라남도 1.017
경상북도 0.966
경상남도 0.903
제주특별자치도 0.951
MapTest2.java
import java.io.File;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.Scanner;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Setter
@Getter
@AllArgsConstructor
@ToString
class BirthByCity {
private String city;
private Double numberOfBirths;
}
public class MapTest2 {
public static void main(String[] args) throws Exception {
List<BirthByCity> birth = new ArrayList<>();
// 파일에 저장된 데이터를 읽어들임
try (Scanner fileIn = new Scanner(new File("birth_2021.txt"))) {
while(fileIn.hasNext()) {
String temp = fileIn.nextLine();
birth.add(
new BirthByCity(temp.split(" ")[0], Double.parseDouble(temp.split(" ")[1])));
}
}
Optional<Double> total = birth.stream()
.map(x -> x.getNumberOfBirths()).reduce((x, y) -> x + y);
System.out.printf("2021년 전국 출산률 합계: %.3f%%, 평균 출산률 : %.3f%%%n", total.get(), total.get() / birth.size());
System.out.print("최대 출산(1인당) : ");
System.out.println(
birth.stream().mapToDouble(x->x.getNumberOfBirths()).max().getAsDouble()
);
System.out.printf("출산율 최소 도시(%s : %.3f)%n",
birth.stream().min(Comparator.comparingDouble(x -> x.getNumberOfBirths())).get().getCity(),
birth.stream().min(Comparator.comparingDouble(x -> x.getNumberOfBirths())).get().getNumberOfBirths()
);
System.out.printf("출산율 최대 도시(%s : %.3f)%n",
birth.stream().max(Comparator.comparingDouble(x -> x.getNumberOfBirths())).get().getCity(),
birth.stream().max(Comparator.comparingDouble(x -> x.getNumberOfBirths())).get().getNumberOfBirths()
);
System.out.println("\n<< 각 지역별 출산율 >>");
birth.stream().sorted((x, y) -> x.getCity().compareTo(y.getCity()))
.forEach(x -> System.out.println(x.getCity() + " / " + x.getNumberOfBirths()));
}
}
** 결과
2021년 전국 출산률 합계: 15.271%, 평균 출산률 : 0.898%
최대 출산(1인당) : 1.277
출산율 최소 도시(서울특별시 : 0.626)
출산율 최대 도시(세종특별자치시 : 1.277)
<< 각 지역별 출산율 >>
강원도 / 0.979
경기도 / 0.853
경상남도 / 0.903
경상북도 / 0.966
광주광역시 / 0.896
대구광역시 / 0.785
대전광역시 / 0.81
부산광역시 / 0.728
서울특별시 / 0.626
세종특별자치시 / 1.277
울산광역시 / 0.94
인천광역시 / 0.778
전라남도 / 1.017
전라북도 / 0.85
제주특별자치도 / 0.951
충청남도 / 0.963
충청북도 / 0.949
좀 내용이 길어졌는데, 읽어보기에는 그다지 어렵지 않은 내용이라고 생각한다.
Stream에서 아직 못 다룬 내용은 추후 계속 다룰 예정이다.
다음에는 Java 1.8에서 제공하는 Optional과 시간과 날짜를 다루는 LocalDate, LocalDateTime에 대해 알아보도록 하겠다.
이전 글: [Java] 10. Stream 마무리-1
[Java] 10. Stream 마무리-1 (0) | 2023.09.22 |
---|---|
[Java] 9. 다양한 Stream의 생성 (0) | 2023.09.13 |
[Java] 8. Stream의 개념과 사용 방법-1 (0) | 2023.09.06 |
댓글 영역