선언형으로 데이터 소스를 처리
람다식으로 요소 처리 코드를 제공
내부 반복자를 사용하므로 병렬 처리가 쉽다.
외부반복자(external iterator) : 개발자가 코드로 직접 컬렉션의 요소를 반복해서 가져오는 코드 패턴
ex) index를 사용하는 for문, Iterator를 이용하는 while문
내부반복자 : 컬렉션 내부에서 요소들을 반복시키고 개발자는 요소당 처리해야할 코드만 제공하는 코드 패턴
중간 연산과 최종 연산
List<Integer> numbers = List.of(1, 3, 6, 7, 8, 11);
int sum = numbers.stream()
.filter(number -> number > 4 && (number % 2 == 0)) // 람다식으로 요소 처리 코드를 제공
.mapToInt(number -> number) // 중간 연산 스트림 중 하나
.sum(); // 최종연산
System.out.println("# 선언형 프로그래밍: " + sum);
파이프라인(pipelines) : 여러개의 스트림이 연결되어 있는 구조
중간 스트림이 생성될 때 요소들이 바로 중간 연산(필터링, 매핑, 정렬)되는 것이 아니라 최종 연산이 시작되기 전까지는 지연
중간 연산
최종 연산
List<String> people;
// 데이터를 넣음
people.stream()
.distinct() // 중간 연산 (Stream<String>)
.filter(s -> s.startsWith(lastName)) // 중간 연산 (Stream<String>)
.sorted() // 중간 연산 (Stream<String>)
.collect(Collectors.toList()); // List<String>
// array로 stream을 만드는 법
List<String> list = Arrays.asList("a", "b", "c");
// list로 stream을 만드는 법 : Collection 인터페이스에 메서드가 정의되어 있음
Stream<String> listStream = list.stream();
listStream.forEach(System.out::prinln); //스트림의 모든 요소를 출력.
// array로부터 스트림을 생성 (여러가지)
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 범위 미포함
// 원시형 자료형을 위한 특수한 종류의 Stream
// IntStream, LongStream, DoubleStream (각각 메서드를 찾아봐서 사용)
// 4이상 10미만의 숫자를 갖는 IntStream
IntStream stream = IntStream.range(4, 10);
NullPointerException(NPE), 즉 null 값으로 인해 에러가 발생하는 현상을 객체 차원에서 효율적으로 방지하고자 도입
연산 결과를 Optional에 담아서 반환하면, 따로 조건문을 작성해주지 않아도 NPE가 발생하지 않도록 코드를 작성할 수 있다.
특징
public final class Optional<T> {
private final T value; // T타입의 참조변수
}
Optional<String> opt1 = Optional.ofNullable(null);
Optional<String> opt2 = Optional.ofNullable("123");
System.out.println(opt1.isPresent()); //Optional 객체의 값이 null인지 여부를 리턴합니다.
System.out.println(opt2.isPresent());
Optional<String> opt3 = Optional.<String>empty();
Optional<String> optString = Optional.of("codestates");
System.out.println(optString);
System.out.println(optString.get());
String nullName = null;
String name = Optional.ofNullable(nullName).orElse("kimcoding");
System.out.println(name);
List<String> languages = Arrays.asList(
"Ruby", "Python", "Java", "Go", "Kotlin");
Optional<List<String>> listOptional = Optional.of(languages);
int size = listOptional
.map(List::size)
.orElse(0);
System.out.println(size);