HOME > java > java8

Java8의 Stream max, min 사용 방법

By JS | 14 Jul 2018

max, min

max(Comparator)는 param으로 넘겨준 Comparator로 스트림의 아이템들을 모두 비교하여 최대 값 1개를 리턴합니다. 이 때, 객체를 직접 넘겨주지 않고 Optional<object> 객체로 wrapping하여 넘겨줍니다.

아래 코드는 Comparator를 생성하고 그것에 대한 max의 결과입니다. Comparator를 보면 내부적으로 compareToIgnoreCase를 수행합니다. 그래서 max(comp1)의 결과로 ruby가 리턴됩니다.(compareToIgnoreCase는 알파벳 순서대로 정렬하므로 가장 높은 r이 max값으로 리턴) 그리고 isPresent()로 lastOne의 아이템이 null이 아닌 경우만 로그로 출력하였습니다.

List<String> langs =
        Arrays.asList("java", "kotlin", "haskell", "ruby", "javascript");

final Comparator<String> comp1 = (s1, s2) -> s1.compareToIgnoreCase(s2);
Optional<String> lastOne = langs.stream().max(comp1);
if (lastOne.isPresent()) {
    System.out.println("last one: " + lastOne.get());
}

결과

last one: ruby

기본적인 comparator는 String에 정의되어 있기 때문에 아래처럼 더 간단히 쓸 수 있습니다. 또 Optional 객체는 ifPresent를 사용하여 한줄로 쓸 수도 있습니다.

List<String> langs =
        Arrays.asList("java", "kotlin", "haskell", "ruby", "javascript");
Optional<String> lastOne2 = langs.stream().max(String::compareToIgnoreCase);
lastOne2.ifPresent(System.out::println);

결과

ruby

min(Comparator)은 max와 정반대입니다. 위와 동일한 Comparator를 사용하면 알파벳 순서가 가장 빠른 haskell이 리턴됩니다.

List<String> langs =
        Arrays.asList("java", "kotlin", "haskell", "ruby", "javascript");
Optional<String> firstOne = langs.stream().min(String::compareToIgnoreCase);
firstOne.ifPresent(System.out::println);

결과

haskell

아래 코드는 Comparator를 직접 구현하여 길이가 가장 길거나 짧은 문자를 리턴하도록 수정하였습니다. Comparator에서 스트링의 length를 비교하도록 변경하였습니다.

List<String> langs =
        Arrays.asList("java", "kotlin", "haskell", "ruby", "javascript");
final Comparator<String> comp2 = (p1, p2) -> Integer.compare( p1.length(), p2.length());
Optional<String> largest = langs.stream().max(comp2);
largest.ifPresent(s ->
        System.out.println("largest: " + s));

Optional<String> shortest = langs.stream().min(comp2);
shortest.ifPresent(s ->
        System.out.println("shortest: " + s));

결과

largest: javascript
shortest: java