자바의 정석 챕터 14를 읽고 정리
2.4 Optional<T>와 OptionalInt
- Optional<T>는 Generic 클래스로 "T타입의 객체"를 감싸는 Wrapper 클래스
- 모든 타입의 참조변수를 담을 수 있음
public final class Optional<T> {
private final T value // T타입의 참조변수
}
- 결과를 Optional객체에 담아서 반환할 경우 null 체크가 간편함
Optional 객체 생성하기
- Optional 객체를 생성할 때는 of() 또는 ofNullable()을 사용
String str = "abc";
Optional<String> optVal = Optional.of(str);
Optional<String> optValNull = Optional.ofNullable(null);
- Optional<T> 타입의 참조변수를 기본값으로 초기화할 때는 empty() 사용이 바람직함
Optional<String> optVal = null; // null로 초기화
Optional<String> optVal2 = Optional.<String>empty(); // 빈 객체로 초기화
Optional 객체의 값 가져오기
- Optional 객체에 저장된 값을 가져올 때는 get()을 사용
- 데이터가 null일 경우 NoSuchElementException 발생
- null 방지하기 위해 orElse() 사용
Optional<String> optVal = Optional.of("Abc");
String s1 = optVal.get();
String s2 = optVal.orElse("");
// 람다식 표현도 가능
String s3 = optVal.orElseGet(String::new); // () -> new String() // null 경우 빈 String 생성
String s4 = optVal.orElseThrow(NullPointerExcetion::new); // null 경우 에러 발생
2.5 스트림의 최종 연산
- 최종 연산 후에는 스트림이 닫히므로 더 이상 사용 불가
- 최종 연산의 결과는 스트림 요소의 합과 같은 단일 값이거나, 스트림의 요소가 담긴 배열 또는 컬렉션일 수 있다.
forEach()
- forEach()는 스트림의 요소를 소모하는 최종 연산
- 반환 타입이 void이므로 스트림의 요소룰 출력하는 용도로 많이 사용됨
void forEach(Consumer<? super T> action)
조건 검사 - allMatch(), anyMatch(), noneMatch(), findFirst(), findAny()
- 스트림의 요소에 대해 지정된 조건과 일치하는지 일치 안하는지 확인하는 메소드
- 연산결과로 boolean을 반환
String ex = "Test";
String exArray[] = {"Test", "TEST"};
boolean exBool = Arrays.stream(exArray).anyMatch(i -> ex.contains(i));
통계- count(), sum(), average(), max(), min()
리듀싱 - reduce()
- 스트림의 요소를 줄여나가면서 연산을 수행하고 최종결과를 반환.
int count = intStream.reduce(0, (a, b) -> a+1);
int sum = intStream.reduce(0, (a, b) -> a+b);
Optional max = intStream.reduce((a, b) -> a > b ? a:b);
// 람다식 표현
Optional min = intStream.reduce(Integer::min); // int min(int a, int b)
// OptionalInt에서 값 꺼낼 경우
int minValue = min.getAsInt();
2.6 collect()
- Collector 인터페이스를 구현한 것
- 직접 구현 가능
스트림을 컬렉션과 배열로 변환 - toList(), toSet(), toMap(), toCollection(), toArray()
List<String> names = stuStream.map(Student::getName).collect(Collectors.toList());
ArrayList<String> list = names.stream().collect(Collectors.toCollection(ArrayList::new));
Map<String, Person> map = personStream.collect(Collectors.toMap(p -> p.getRegId(), p -> p));
그룹화와 분할 - groupomgBy(), partitioningBy()
- Student 클래스
@ToString
@Getter
class Student {
String name;
boolean isMale;
int hak;
int ban;
int score;
Student(String name, boolean isMale, int hak, int ban, int score) {
this.name = name;
this.isMale = isMale;
this.hak = hak;
this.ban = ban;
this.score = score;
}
enum Level {HIGH, MID, LOW}
}
Stream<Student> stuStream = Stream.of(
new Student ("ㄱ", true, 1, 1, 300);
new Student ("ㄴ", true, 1, 2, 100);
new Student ("ㄷ", false, 1, 1, 100);
new Student ("ㄹ", true, 1, 3, 200);
new Student ("ㅁ", false, 1, 1, 150);
new Student ("ㅂ", true, 1, 2, 50);
);
partitioningBy()에 의한 분류
- 성별로 나누어 List에 담기
Map<Boolean, List<Student>> stuBySex = stuStream.collect(partitioningBy(Student::isMale);
List<String> males = stuBySex.get(true);
List<String> females = stuBySex.get(false);
groupingBy()에 의한 분류
- 반 별로 그룹지어 Map에 담기
- groupingBy()를 하면 기본적으로 List<T>에 저장
Map<Integer, List<Student>> stuByBan = stuStream.collect(groupingBy(Student::getBan));
'개발 > Java & Kotlin' 카테고리의 다른 글
[Spring] 스프링 시큐리티 (1) (0) | 2022.07.04 |
---|---|
[Spring] 스프링 AOP (2) (0) | 2022.07.04 |
[Spring] 스프링 AOP (1) (0) | 2022.07.01 |
[Java] 람다와 스트림(4) (0) | 2022.07.01 |
[Java] 람다와 스트림(3) (0) | 2022.06.30 |