본문 바로가기
개발/Java

[Java] 람다와 스트림(5)

by devhooney 2022. 7. 4.
728x90

자바의 정석 챕터 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));
728x90

'개발 > Java' 카테고리의 다른 글

[Java] 기본 자료구조  (0) 2022.07.08
[Java] 기본 알고리즘  (0) 2022.07.07
[Java] 람다와 스트림(4)  (0) 2022.07.01
[Java] 람다와 스트림(3)  (0) 2022.06.30
[Java] 람다와 스트림(2)  (0) 2022.06.29