검색결과 리스트
글
java 8 정리3
인프런 강의 6일차.
- 더 자바, Java 8 (백기선 강사님)
1. 인터페이스 기본 메소드와 스태틱 메소드 2
- Iterable의 기본 메소드
-> forEach()
-> spliterator()
- Collection의 기본 메소드(Collection은 Iterable의 상속받는 클래스이니 사실상 Collection = Iterable과 같다)
-> stream() / parallelStream()
-> removeIf(Predicate)
-> spliterator()
- Comparator의 기본 메소드
-> reversed()
-> thenComparing()
-> static reverseOrder() / naturalOrder()
-> static nullsFirst() / nullsLast()
-> static comparing()
package me.whiteship.java8to11;
import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
public class App {
public static void main(String[] args) {
/*GreetingInterface greetingInterface = new DefaultGreeting("park");
greetingInterface.printName(); //park 출력
greetingInterface.printNameUpperCase(); //PARK 출력
GreetingInterface.printAnything(); //Interface의 static 메소드 바로 사용*/
List<String> name = new ArrayList<>();
name.add("park");
name.add("dong");
name.add("hyeon");
name.add("kim");
//case1. foreach lambda
name.forEach(s -> {
//System.out.println(s);
});
//case2. foreach method reference
//name.forEach(System.out::println);
Spliterator<String> spliterator = name.spliterator();
//case3. spliterator 사용(name 배열을 순회하면서 출력한다)
//tryAdvance = hasNext와 같은 역할
//while(spliterator.tryAdvance(System.out::println));
/* spliterator.trySplit()를 사용한 split 시 배열에 대해 trySplit을 진행한 뒤 tryAdvance를 수행해야 한다.
즉 아래 코드는 오류가 발생한다.
Spliterator<String> spliterator = name.spliterator();
while(spliterator.tryAdvance(System.out::println));
Spliterator<String> spliterator1 = spliterator.trySplit(); //name 배열에 대해 split 진행
while(spliterator1.tryAdvance(System.out::println));
--------------------------------------------------------------
//정상 동작 쿼리
Spliterator<String> spliterator = name.spliterator();
Spliterator<String> spliterator1 = spliterator.trySplit(); //name 배열에 대해 split 진행
while(spliterator.tryAdvance(System.out::println));
while(spliterator1.tryAdvance(System.out::println));
*/
//name 배열에 대해 UppserCase실행 후 filer를 걸어서 P로 시작하는 값만 읽어서 count
name.stream().map(String::toUpperCase)
.filter(s -> s.startsWith("P"))
.count();
//k로 시작하는 문자열 제거
name.removeIf(s -> s.startsWith("k"));
name.forEach(System.out::println);
/*park
dong
hyeon*/
//case1. 문자열 역순으로 소팅
name.sort(String::compareToIgnoreCase);
name.forEach(System.out::println);
/*dong
hyeon
park
*/
//case2. 문자열 역순으로 소팅(Comparator 사용)
Comparator<String> compareToIgnoreCase = String::compareToIgnoreCase;
name.sort(compareToIgnoreCase.reversed());
name.forEach(System.out::println);
/*park
hyeon
dong
*/
//case3. 문자열 역순으로 소팅 reversd() 사용 후 thenComparing으로 추가 비교
//name.sort(compareToIgnoreCase.reversed().thenComparing());
name.forEach(System.out::println);
}
}
2. 스트림 API
- Stream : sequence of elements supporting sequential and parallel aggregate operations
-> 데이터를 담고 있는 저장소(컬렉션)이다.
-> Function in nature, 스트림이 처리하는 데이터 소스를 변경하지 않는다.
-> 스트림으로 처리하는 데이터는 오직 한번만 처리한다.
-> 무제한일 수도 있다. (Sort Circuit 메소드를 사용해서 제한할 수 있다.)
-> 중개 오퍼레이션은 근본적으로 lazy하다.
-> 손쉽게 병렬처리할 수 있다.
- 스트림 파이프라인
-> 0 또는 다수의 중개 오퍼레이션(intermediate operation)과 한개의 종료 오퍼레이션(terminal operation)으로 구성.
-> 스트림의 데이터 소스는 오직 터미널 오퍼레이션을 실행할 때에만 처리한다.
- 중개 오퍼레이션
-> Stream을 리턴한다.
-> Stateless / Statefull 오퍼레이션으로 더 상세하게 구분할 수도 있다. (대부분은 Stateless지만 distinct나 sorted처럼 이전 이전 소스 데이터를 참조해야 하는 오퍼레이션은 Statefull 오퍼레이션이다)
-> filter, map, limit, skip, sorted, ...
- 종료 오퍼레이션
-> Stream을 리턴하지 않는다.
-> collect, allMatch, count, forEach, min, max, ...
List<String> name = new ArrayList<>();
name.add("park");
name.add("dong");
name.add("hyeon");
name.add("kim");
//Stream<String> stringStream
name.stream().map((s) -> {
System.out.println(s); //map은 중개 오퍼레이션이기 때문에 터미널 오퍼레이션이 오기전까지 실행되지 않는다. 즉 해당 sout은 출력되지 않는다!
return s.toUpperCase();
}); //해당 상태는 종료 오퍼레이션 없이 끝난 스트림이다.(선언만 된 상태이다)
List<String> collect = name.stream().map((s) -> {
System.out.println(s); //map은 중개 오퍼레이션이기 때문에 터미널 오퍼레이션이 오기전까지 실행되지 않는다. 즉 해당 sout은 출력되지 않는다!
return s.toUpperCase();
}).collect(Collectors.toList());//종료 오퍼레이션인 collect 추가했기 때문에 처리 진행
//return이 upperCase이므로 sout 당시는 소문자가 출력되고, return값인 collect 변수 출력 시 대문자가 출력된다.
name.forEach(System.out::println); //대문자 출력
//병렬 스트림
List<String> collect1 = name.parallelStream().map((s)->{
System.out.println(s + " " + Thread.currentThread().getName()); //ForkJoinPool을 통해 다른 thread에서 실행됨을 확인 가능
return s.toUpperCase();
}).collect(Collectors.toList());
collect1.forEach(System.out::println);
package me.whiteship.java8to11;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import java.util.stream.Stream;
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>> keesunEvents = new ArrayList<>();
keesunEvents.add(springClasses);
keesunEvents.add(javaClasses);
System.out.println("spring 으로 시작하는 수업");
springClasses.stream()
.filter(oc -> oc.getTitle().startsWith("spring"))
.forEach(oc -> System.out.println(oc.getId()));
System.out.println("close 되지 않은 수업");
springClasses.stream()
.filter(Predicate.not(OnlineClass::isClosed))// filter(oc -> !oc.isClosed())와 같은 의미이다.
.forEach(oc -> System.out.println(oc.getId()));
System.out.println("수업 이름만 모아서 스트림 만들기");
//map이라는 중개 오퍼레이션을 사용해야함
springClasses.stream()
.map(oc -> oc.getTitle()) //input은 onlineClass로 들어오나 output은 다른 type으로 변경가능
//.forEach(s -> System.out.println(s)); //getTitle이 String이기 때문에 들어온 String 출력
.forEach(System.out::println); //method preference
System.out.println("두 수업 목록에 들어있는 모든 수업 아이디 출력");
//keesunEvents는 리스트 2개를 모아놓은 리스트이고, 이 2개를 합쳐서 1개의 스트림으로 만들어야한다. -> Flat 시킨다
keesunEvents.stream()
.flatMap(Collection::stream) //리스트를 flat 시켜 1개의 스트림으로 만들음
.forEach(oc -> System.out.println(oc.getId())); //input이 collection stream으로 들어감
System.out.println("10부터 1씩 증가하는 무제한 스트림 중에서 앞에 10개 빼고 최대 10개 까지만");
//Stream의 iterator를 가지고 구현 가능
Stream.iterate(10, i -> i + 1) //10부터 1씩 증가하는 무제한 스트림 (중개 오퍼레이션이기 때문에 iterate만 있어도 별다른 실행이 되지 않는다.
.skip(10)
.limit(10)
.forEach(System.out::println);
System.out.println("자바 수업 중에 Test가 들어있는 수업이 있는지 확인");
//Stream의 Match로 구현 가능
boolean test = javaClasses.stream().anyMatch(oc -> oc.getTitle().contains("Test"));
System.out.println(test);
System.out.println("스프링 수업 중에 제목에 spring이 들어간 제목만 모아서 List로 만들기");
//case1. filter 먼저 수행 (filter에서 onlineClass로 비교 수행)
List<String> spring = springClasses.stream()
.filter(oc -> oc.getTitle().contains("spring")) //filter을 먼저 해도 되고, map을 먼저 해도 됨. 다만 어떤 것을 먼저 하느냐에 따라 지나가는 타입이 달라지므로 구현에 주의!
.map(OnlineClass::getTitle)
.collect(Collectors.toList());
//case2. map 먼저 수행 (filter에서 String 으로 비교 수행)
List<String> spring1 = springClasses.stream()
.map(OnlineClass::getTitle)
.filter(t -> t.contains("spring"))
.collect(Collectors.toList());
}
}
'Java 정리' 카테고리의 다른 글
java 8 정리6 (0) | 2021.05.21 |
---|---|
java 8 정리5 (0) | 2021.05.20 |
java 8 정리4 (0) | 2021.05.19 |
java 8 정리2 (0) | 2021.05.13 |
java 8 정리1 (0) | 2021.05.12 |