sequence of elements supporting sequential and parallel aggregate operations
Stream은 연속된 데이터를 처리하는 오퍼레이션들의 모임이다.
무제한으로 데이터가 들어와도 처리가 가능하다.
- Short Circuit 메소드를 사용하여 들어오는 데이터를 제한할 수 있다.
Functional in nature, 스트림이 처리하는 데이터 소스는 변경하지 않는다. (원본 변경 x)
즉, 스트림으로 전달받은 데이터 자체를 변경하지 않는다.
List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
// list에 저장된 데이터를 대문자로 바꾸는 처리를 하는 stream
Stream<String> stringStream = list.stream()
.map(String::toUpperCase); // stream을 리턴
// list 객체 안의 기존 데이터는 변경되지 않음
list.forEach(System.out::println); // apple banana
// 종료 오퍼레이션을 만나지 못했으므로, 코드가 실행되지 않음
// 단순히 스트림을 정의한 것뿐 실행은 안됨
list.stream().map((s) -> {
System.out.println(s); // 출력되지 않음
return s.toUpperCase();
});
List<String> collect = list.stream().map((s) -> {
System.out.println(s); // 소문자로 출력됨
return s.toUpperCase(); // 대문자로 변경됨
}).collect(Collectors.toList()); // list 객체로 반환됨
collect.forEach(System.out::println); // 대문자로 출력됨
List<String> parallelCollect = list.parallelStream().map((s) -> {
System.out.println(s + " , <Thread name> " + Thread.currentThread().getName());
return s.toUpperCase();
}).collect(Collectors.toList());
parallelCollect.forEach(System.out::println);
// setter, getter, 생성자는 만들어져있다고 가정
public class OnlineClass {
private Integer id;
private String title;
private boolean closed;
}
public class App {
public static void main(String[] args) {
List<OnlineClass> springClasses = new ArrayList<>();
springClasses.add(new OnlineClass(1, "spring boot", true));
springClasses.add(new OnlineClass(2, "spring data jpa", true));
springClasses.add(new OnlineClass(3, "spring mvc", false));
springClasses.add(new OnlineClass(4, "spring core", false));
springClasses.add(new OnlineClass(5, "rest api development", false));
List<OnlineClass> javaClasses = new ArrayList<>();
javaClasses.add(new OnlineClass(6, "The Java, Test", true));
javaClasses.add(new OnlineClass(7, "The Java, Code manipulation", true));
javaClasses.add(new OnlineClass(8, "The Java, 8 to 11", false));
List<List<OnlineClass>> events = new ArrayList<>();
events.add(springClasses);
events.add(javaClasses);
System.out.println("spring 으로 시작하는 수업");
springClasses.stream()
.filter(onlineClass -> onlineClass.getTitle().startsWith("spring")) // 중개 오퍼레이션
.forEach(onlineClass -> System.out.println(onlineClass.getTitle())); // 종료 오퍼레이션
System.out.println("close 되지 않은 수업");
springClasses.stream()
.filter(onlineClass -> !onlineClass.isClosed()) // 중개 오퍼레이션
.forEach(onlineClass -> System.out.println(onlineClass.getTitle())); // 종료 오퍼레이션
System.out.println("수업 이름만 모아서 스트림 만들기");
springClasses.stream()
.map(OnlineClass::getTitle) // 중개 오퍼레이션 (OnlineClass -> String)
.forEach(System.out::println); // 종료 오퍼레이션 (String 출력)
System.out.println("두 수업 목록에 들어있는 모든 수업 아이디 출력");
events.stream()
.flatMap(Collection::stream) // 스트림 input으로 들어온 List를 flatten시켜 OnlineClass 객체로 만든다.
.forEach(onlineClass -> System.out.println(onlineClass.getId())); // 종료 오퍼레이션
System.out.println("10부터 1씩 증가하는 무제한 스트림 중에서 앞에 10개 빼고 최대 10개 까지만");
Stream.iterate(10, i -> i+1) // 증가 스트림 생성
.skip(10) // 앞에 10개 제외
.limit(10) // 최대 10개
.forEach(System.out::println); // 종료 오퍼레이션
System.out.println("자바 수업 중에 Test가 들어있는 수업이 있는지 확인");
boolean result = javaClasses.stream()
.anyMatch(onlineClass -> onlineClass.getTitle().contains("Test")); // boolean으로 반환
System.out.println(result);
System.out.println("스프링 수업 중에 제목에 spring이 들어간 것만 모아서 List로 만들기");
List<String> list = springClasses.stream()
.map(OnlineClass::getTitle) // 제목만 모아서 새로운 stream 객체를 생성
.filter(title -> title.contains("spring")) // 조건에 맞게 거름
.collect(Collectors.toList()); // 처리한 스트림을 List 객체로 반환
list.forEach(System.out::println);
}
}
이 포스팅은 백기선님의 더 자바, Java 8을 수강하고 정리한 내용입니다.