본문 바로가기

Java 길찾기/이것이 자바다

[Java] 스트림 파이프라인 대량의 데이터를 가공해서 축소하는 것을 일반적으로 리덕션(Reduction)이라고 하는데, 데이터의 합계, 평균값, 카운팅, 최대값, 최소값 등이 대표적인 리덕션의 결과물이라고 볼 수 있다. 그러나 컬렉션의 요소를 리덕션의 결과물로 바로 집계할 수 없을 경우에는 집계하기 좋도록 필터링, 매핑, 정렬, 그룹핑 등의 중간 처리가 필요하다. 중간 처리와 최종 처리 스트림은 데이터의 필터링, 매핑, 정렬, 그룹핑 등의 중간 처리와 합계, 평균, 카운팅, 최대값, 최소값 등의 최종 처리를 파이프라인(pipelines)으로 해결한다. 파이프라인은 여러 개의 스트림이 연결되어 있는 구조를 말한다. 파이프라인에서 최종 처리를 제외하고는 모두 중간 처리 스트림이다. 중간 스트림이 생성될 때 요소들이 바로 중간 처리(필터.. 더보기
[Java] 스트림의 종류 자바 8 부터 새로 추가된 java.util.stream 패키지에는 스트림(stream) API들이 포진하고 있다. 패키지 내용을 보면 BaseStream 인터페이스를 부모로 해서 자식 인터페이스들이 상속 관계를 이루고 있다. BaseStream 인터페이스에는 모든 스트림에서 사용할 수 있는 공통 메소드들이 정의되어 있을 뿐 코드에서 직접적으로 사용되지는 않는다. 하위 스트림인 Stream, IntStream, LongStream, DoubleStream이 직접적으로 이용되는 스트림인데, Stream은 객체 요소를 처리하는 스트림이고, IntStream, LongStream, DoubleStream은 각각 기본 타입인 int, long, double 요소를 처리하는 스트림이다. 이 스트림 인터페이스의 구.. 더보기
[Java] 스트림 소개 스트림은(Stream)은 자바 8부터 추가된 컬렉션(배열 포함)의 저장 요소를 하나씩 참조해서 람다식(함수적-스타일(functional-style))으로 처리할 수 있도록 해주는 반복자이다. 반복자 스트림 자바7 이전까지는 List 컬렉션에서 요소를 순차적으로 처리하기 위해 Iterator 반복자를 다음과 같이 사용해왔다. List list = Arrays.asList("홍길동", "김자바", "오징어"); Iterator iterator = list.iterator(); while(iterator.hasNext()) { String name = iterator.next(); System.out.println(name); } 이 코드를 stream을 사용해서 변경하면 다음과 같다. List list = .. 더보기
[Java] 메소드 참조 메소드 참조(Method References)는 말 그대로 메소드를 참조해서 매개 변수의 정보 및 리턴 타입을 알아내어, 람다식에서 불필요한 매개 변수를 제거하는 것이 목적이다. 람다식은 종종 기존 메소드를 단순히 호출만 하는 경우가 많다. 예를 들어 두 개의 값을 받아 큰 수를 리턴하는 Math 클래스의 max() 정적 메소드를 호출하는 람다식은 다음과 같다. (left, right) -> Math.max(left, right); 람다식은 단순히 두 개의 값을 Math.max() 메소드의 매개값으로 전달하는 역할만 하기 때문에 다소 불편해 보인다. 이 경우에는 다음과 같이 메소드 참조를 이용하면 매우 깔끔하게 처리할 수 있다. Math :: max; 메소드 참조도 람다식과 마찬가지로 인터페이스의 익명 .. 더보기
[Java] 표준 API의 함수적 인터페이스 - minBy(), maxBy() 정적 메소드 BinaryOperator 함수적 인터페이스는 minBy()와 maxBy() 정적 메소드를 제공한다. 이 두 메소드는 매개값으로 제공되는 comparator를 이용해서 최대 T와 최소 T를 얻는다. 이 두 메소드는 매개값으로 제공되는 Comparator를 이용해서 최대 T와 최소 T를 얻는 BinaryOperator를 리턴한다. 리턴 타입 정적 메소드 BinaryOperator minBy(Comparator 더보기
[Java] 표준 API의 함수적 인터페이스 - and(), or(), negate 디폴트 메소드와 isEqual() 정적메소드 Predicate 종류의 함수적 인터페이스는 and(), or(), negate() 디폴트 메소드를 가지고 있다. 이 메소드들은 각각 논리 연산자인 &&, ||, ! 와 대응된다고 볼 수 있다. and() 메소드는 두 Predicate가 모두 true를 리턴하면 최종적으로 ture를 리턴하는 Predicate를 생성한다. or()는 두 predicate 중 하나만 true를 리턴하더라도 최종적으로 true를 리턴하는 Predicate를 생성한다. negate()는 원래 Predicate의 결과가 true이면 false로, false이면 true를 리턴하는 새로운 Predicate를 생성한다. 다음은 and(), or(), negate() 디폴트 메소드를 제공하는 Predicate 함수적 인터페이스들이다... 더보기
[Java] 표준 API의 함수적 인터페이스 - andThen(), compose() 디폴트 메소드 디폴트 및 정적 메소드는 추상 메소드가 아니기 때문에 함수적 인터페이스에 선언되어도 여전히 함수적 인터페이스의 성질을 잃지 않는다. 여기서 함수적 인터페이스 성질이란 하나의 추상 메소드를 가지고 있고, 람다식으로 익명 구현 객체를 생성할 수 있는 것을 말한다. java.util.function 패키지의 함수적 인터페이스는 하나 이상의 디폴트 및 정적 메소드를 가지고 있다. Consumer, Function, Operator 종류의 함수적 인터페이스는 andThen()과 compose() 디폴트 메소드를 가지고 있다. andThen()과 compose() 디폴트 메소드는 두 개의 함수적 인터페이스를 순차적으로 연결하고, 첫 번째 처리 결과를 두 번째 매개값으로 제공해서 최종 결과값을 얻을 때 사용한다. a.. 더보기
[Java] 표준 API의 함수적 인터페이스 - Operator, Predicate Operator 함수적 인터페이스 Operator 함수적 인터페이스는 Function과 동일하게 매개 변수와 리턴값이 있는 applyXXX() 메소드를 가지고 있다. 하지만 이 메소드들은 매개값을 리턴값으로 매핑(타입 변환)하는 역할보다는 매개값을 이용해서 연산을 수행한 후 동일한 타입으로 리턴값을 제공하는 역할을 한다. 매개 변수의 타입과 수에 따라서 아래와 같은 Operator 함수적 인터페이스들이 있다. 인터페이스명 추상 메소드 설명 BinaryOperator T apply(Tt, Tt) T와 T를 연산한 후 T 리턴 UnaryOperator T apply(Tt) T를 연산한 후 T 리턴 DoubleBinaryOperator double applyAsDouble(double, double) 두 개의.. 더보기