JAVA/Java Stream

Stream 함수

lovineff 2020. 6. 4. 15:52

Stream<T> filter(Predicate<? super T> predicate)

조건에 맞는 요소만 추출한다.

// Predicate 반환 함수 선언
Predicate<Integer> isEven = n -> {return n % 2 == 0;};
System.out.println(isEven.test(10));

// Predicate 반환 함수를 사용
List<Integer> list = Arrays.asList(1,2,3,4,5);
list.stream().filter(isEven).forEach(System.out::println);

// filter 내부에 특정 조건을 넣는다.
list.stream().filter(d -> {
    if(d == 2) return true;
    else if(d == 3) return true;
    else return false;
}).forEach(System.out::println);

 

 

Stream<R> map(Function<? super T, ? extends R> mapper)

스트림의 원소를 매핑시킨 후 매핑시킨 값을 단일 스트림으로 반환

즉, Stream에 있는 값을 변환하기 위해 사용한다.

각 요소에 특정 작업을 수행하고 그 값을 반환한다.

특정 타입으로 반환이 가능하게 mapToInt, mapToLong, mapToDouble이 있다.

// Function 반환 함수 선언
Function<Integer, Integer> addOne = d -> {return d + 1;};
list.stream().map(addOne).forEach(System.out::println);

// Function 반환 함수 없이 사용
List<Integer> list = Arrays.asList(1,2,3,4,5);
list.stream().map(n -> n + 1).forEach(System.out::println);

// 객체 스트림으로 반환 가능
peopleList.stream().map(people -> {
    people.setAge(people.getAge() + 10);
    return people;
}).forEach(people -> System.out.println(people.getAge()));

// mapToInt 사용
peopleList.stream().mapToInt(People::getAge).forEach(System.out::println);

 

 

IntStream flatMap(Function<? super T, ? extends Stream> mapper)

스트림 원소를 매핑시킨 후 매핑시킨 값을 복수 스트림으로 반환

그리고 생성된 복수 스트림을 단일 스트림으로 변환하여 반환한다.

 

 

 

Stream<T> distinct()

스트림 원소의 중복을 제거한다.

List<People> peopleList = new ArrayList<>();
for(int i=0 ; i < 10 ; i ++){
    peopleList.add(new People(2, "a" + i));
}
peopleList.stream().map(People::getAge).distinct().forEach(System.out::println);

// 서로 다른 객체는 중복 제거가 안된다.
peopleList.stream().distinct().forEach(System.out::println);

 

 

Stream<T> sorted(Comparator<? super T> comparator)

스트림 원소를 정렬한다.

매개변수 없이 사용하려면, 스트림 원소객체에 Comparator 인터페이스가 구현이 되어있어야 사용 가능하다.

List<People> peopleList = new ArrayList<>();
for(int i=10 ; i > 0 ; i --){
    peopleList.add(new People(i, "a" + i));
}

// 기본 정렬
// Comparator 사용
peopleList.stream().map(People::getAge).sorted(Comparator.comparing(Integer::intValue)).forEach(System.out::println);

// Comparator 미사용 
peopleList.stream().map(People::getAge).sorted(Integer::compareTo).forEach(System.out::println);


// 역 정렬
List<People> peopleList = new ArrayList<>();
for(int i=0 ; i < 10 ; i++){
    peopleList.add(new People(i, "a" + i));
}
peopleList.stream().map(People::getAge).sorted(Comparator.comparing(Integer::intValue).reversed()).forEach(System.out::println);

 

 

Stream<T> peek(Consumer<? super T> action)

스트림의 요소로 구성된 스트림을 반환하고, 그 결과 스트림에서 요소가 소비될 때 각 요소에 대해 추가로 제공된 동작을 수행한다.

스트림에서 요소를 소모하지 않으므로, 주로 연산과 연산 사이에 결과를 확인하고 싶을 때 사용

List<People> peopleList = new ArrayList<>();
for(int i=0 ; i < 10 ; i++){
    peopleList.add(new People(i, "a" + i));
}
peopleList.stream().peek(people -> System.out.println(people.getAge()))
    .map(people -> {
        people.setAge(people.getAge() + 10); 
        return people;
    })
    .peek(people -> System.out.println("10 추가 > " + people.getAge()))
    .map(people -> {
        people.setAge(people.getAge() - 5); 
        return people;
    })
    .forEach(people -> System.out.println("연산 결과 > " + people.getAge()));

 

 

Stream<T> limit(long maxSize)

스트림 요소를 입력받은 maxSize 개수만큼만 스트림으로 반환한다.

즉, 스트림 요소 개수 감소후 스트림을 반환한다.

// 10개 요소 중 5개만 출력
List<People> peopleList = new ArrayList<>();
for(int i=0 ; i < 10 ; i++){
    peopleList.add(new People(i, "a" + i));
}
peopleList.stream().limit(5L).forEach(people -> System.out.println(people.getAge()));


// 5개 요소 중 10개 출력(5개만 있으므로, 5개만 출력된다)
List<People> peopleList = new ArrayList<>();
for(int i=0 ; i < 5 ; i++){
    peopleList.add(new People(i, "a" + i));
}
peopleList.stream().limit(10L).forEach(people -> System.out.println(people.getAge()));

 

 

Stream<T> skip(long n)

스트림 요소중 n개의 요소를 건너뛴 스트림을 반환한다.

// 5개 요소중 3개만 출력
List<People> peopleList = new ArrayList<>();

for(int i=0 ; i < 5 ; i++){
    peopleList.add(new People(i, "a" + i));
}

peopleList.stream().skip(2L).forEach(people -> System.out.println(people.getAge()));

 

boolean anyMatch(Predicate<? super T> predicate)

스트림 요소에 조건에 맞는게 있는지 검사

하나라도 있으면 true / 없으면 false 리턴

// age가 3인 객체가 있는지 검사
List<People> peopleList = new ArrayList<>();
for(int i=0 ; i < 10 ; i++){
    peopleList.add(new People(i, "a" + i));
}

boolean has3Age = peopleList.stream().anyMatch(people -> people.getAge() == 3);
System.out.println(has3Age);

 

 

boolean allMatch(Predicate<? super T> predicate)

스트림의 모든 요소가 조건에 맞는지 검사

모든 요소가 맞다면 true / 그렇지 않으면 false 반환

List<People> peopleList = new ArrayList<>();

for(int i=0 ; i < 10 ; i++){
    peopleList.add(new People(i, "a" + i));
}
boolean has3Age = peopleList.stream().allMatch(people -> people.getAge() == 3);  // 모든 요소의 age 값이 3과 일치하는지 검사
System.out.println(has3Age);

boolean biggerThenZeo = peopleList.stream().allMatch(people -> people.getAge() >= 0); // 모든 요소의 age값이 0이상인지 검사
System.out.println(biggerThenZeo);

 

 

boolean noneMatch(Predicate<? super T> predicate)

스트림의 모든 요소가 조건에 맞지 않는지 검사(allMatch 와 반대)

모든 요소가 조건에 맞지 않으면 true / 하나라도 맞으면 false 반환

List<People> peopleList = new ArrayList<>();

for(int i=0 ; i < 10 ; i++){
    peopleList.add(new People(i, "a" + i));
}
boolean notHave3Age = peopleList.stream().noneMatch(people -> people.getAge() == 3);
System.out.println(notHave3Age);

boolean notHaveMinusAge = peopleList.stream().noneMatch(people -> people.getAge() < 0);
System.out.println(notHaveMinusAge);

 

 

Optional<T> findFirst()

스트림 요소의 첫번째 요소를 반환한다.

List<People> peopleList = new ArrayList<>();

for(int i=10 ; i < 100 ; i++){
    peopleList.add(new People(i, "a" + i));
}

System.out.println(peopleList.stream().findFirst().orElse(new People(-1, null)).getAge());

 

 

Optional<T> findAny()

스트림 요소중 아무 요소 하나를 찾아 반환한다.

일반 Stream 사용시 첫번째 요소를 반환하므로, 병렬 처리시 사용하는게 좋다고 생각된다.

List<People> peopleList = new ArrayList<>();

for(int i=10 ; i < 100 ; i++){
    peopleList.add(new People(i, "a" + i));
}

// 요소의 age가 20보다 요소를 아무거나 찾아 하나의 나이를 출력한다.
System.out.println(peopleList.parallelStream().filter(people -> people.getAge() > 20).findAny().orElse(new People(-1, null)).getAge());

 

 

 

Optional 이란?

자바에서 null 처리를 쉽게 하기 위해 제공되는 class

즉, null인 경우와 null이 아닌 경우 처리를 쉽게 하기 위해 사용한다.

 

Optional class 내부 함수

Optional<T> of(T value)

Optional 객체 생성

value가 널이 아닌 경우에만 사용한다.

null인 경우 NPE가 발생된다.

String str = null;
Optional.of(str);

// 에러 발생
Exception in thread "main" java.lang.NullPointerException
    at java.util.Objects.requireNonNull(Objects.java:203)
    at java.util.Optional.<init>(Optional.java:96)
    at java.util.Optional.of(Optional.java:108)
    at Java.StreamStudy.main(StreamStudy.java:14)

 

Optional<T> ofNullable(T value)

Optional 객체 생성

value가 널인 가능성이 있는 경우 사용한다.

대부분의 경우 사용한다.

String str = null;

Optional.ofNullable(str);   // NPE가 발생하지 않는다.

 

T get()

Optional 객체의 값을 반환한다

객체의 값이 null이 아닌 경우에만 사용해야 한다.

값이 null인 경우 에러가 발생된다.

String str = null;
String result = Optional.ofNullable(str).get();

// 에러 발생
Exception in thread "main" java.util.NoSuchElementException: No value present
    at java.util.Optional.get(Optional.java:135)
    at Java.StreamStudy.main(StreamStudy.java:13)

 

boolean isPresent()

Optional 객체가 null인지 검사한다

null인 경우 false, null이 아닌 경우 true 반환

String str = null;
System.out.println(Optional.ofNullable(str).isPresent());   // false 반환

String str = "test";
System.out.println(Optional.ofNullable(str).isPresent());   // true 반환

 


void ifPresent(Consumer<? super T> consumer)

Optional 객체가 null이 아닌 경우 입력받은 함수를 실행 시킨다.

null인 경우 아무것도 하지 않고 종료된다.

String str = null;
Optional.ofNullable(str).ifPresent(System.out::println);    // 실행 결과가 없다.

String str = "test";
Optional.ofNullable(str).ifPresent(System.out::println);    // str 값이 출력된다.

 

 

Optional<T> filter(Predicate<? super T> predicate)

Stream Class의 filter와 동일한 기능을 한다.

Person person = new Person("name", 21);

String name = Optional.ofNullable(person)
                .filter(p -> {return p.getAge() > 10;})
                .map(Person::getName).orElse("");

System.out.println(name);

 

 

Optional<U> map(Function<? super T, ? extends U> mapper)

Stream Class의 map과 동일한 기능을 한다.

Person person = new Person("name", 21);

String name = Optional.ofNullable(person)
                .filter(p -> {return p.getAge() > 10;})
                .map(Person::getName).orElse("");

System.out.println(name);

 

 

T orElse(T other)

Optional 객체의 값이 null인 경우 입력받은 객체를 반환한다.

String str = null;
String newStr = Optional.ofNullable(str).orElse("is null");
System.out.println(newStr); // is null 출력

String str = "test";
String newStr = Optional.ofNullable(str).orElse("is null");
System.out.println(newStr); // test 출력

 

 

T orElseGet(Supplier<? extends T> other)

Optional 객체가 비어있다면 입력받은 함수를 실행한다.

String str = null;
String newStr = Optional.ofNullable(str).orElseGet(() -> "or else get");
System.out.println(newStr); // or else get 출력

 

 

T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X

Optional 객체가 비어있다면 Exception을 발생시킨다.

String str = null;
String newStr = Optional.ofNullable(str).orElseThrow(NoSuchElementException::new);

// 에러 발생
Exception in thread "main" java.util.NoSuchElementException
    at java.util.Optional.orElseThrow(Optional.java:290)
    at Java.StreamStudy.main(StreamStudy.java:13)

 

'JAVA > Java Stream' 카테고리의 다른 글

Map 반복문  (0) 2021.04.12
Map Parallel (Map 병렬처리) 방법  (0) 2021.03.30
Stream 객체 값 변경 예제  (0) 2020.11.30
Java 1.8 CompletableFuture 모든 동작 완료 확인  (0) 2020.06.04
JAVA Stream 기본  (0) 2020.06.04