BackEnd_Servers

[BackEnd_Servers] JAVA8(Stream API) 이해 및 활용(1)

wookjae 2021. 10. 19. 15:01

1. Stream API (함수형 프로그래밍)

 

* Stream API ? 

Java는 객체지향 언어이다. Java로 프로그래밍을 할 시 대부분, "명령형(선언형) 프로그래밍"을 사용하였다. 하지만, Java8부터 "Stream API", "Optional", "Lambda", "Functional Interface" 등., 지원하면서 Java를 함수형으로 프로그래밍 할수 있는 API들이 제공되고 있다. "Stream API"데이터를 추상화하고, 처리하는데 반복적으로 사용되는 함수들을 정의 해 두었다. 데이터를 추상화하였다는 것은 데이터의 종류에 무관하게 같은 방식으로 데이터를 처리할 수 있다는 것을 의미한다. 이에따라, 유연성과 재사용성이 증대된다. 

 

 

* Stream API 활용 

--> 배열과, 리스트를 정렬된 상태로 출력

함수형 프로그래밍으로 리팩토링(Stream API)

* Stream API는 원본데이터를 복사하여 별개의 Stream을 생성하여 조작하므로, 원본데이터를 변형하지 않는다.

 

* 코드가 간결해지며, 가독성이 높아진다.

 

 


2. Stream API 특징?

 

* 특징(1). 원본의 데이터를 변경하지 않는다. 

Stream API는 원본데이터를 참조하여, 별도의 Stream을 생성한다. 따라서, 원본데이터는 읽기만 할 뿐이며, 정렬이나 필터링 등의 구체적인 작업은 별도로 생성된 Stream 요소에서 처리된다.

* 리스트로부터(List<String>) 스트림을 생성한다. 

* 위 생성된스트림으로 데이터를 정렬 후 정렬이 적용 된 리스트를 반환한다.

 

 

* 특징(2). 스트림은 일회성이다.

Stream API는 일회용이기 때문에 한번 사용이 끝날 시, 재 사용이 불가능하다. Stream을 다시 사용할 경우, Stream을 다시 생성해야한다. 사용 후 닫힌 Stream을 재 사용할시, illegalStateException이 발생하게 된다. 

 

 

* 특징(3). 내부 반복으로 작업을 처리한다. 

Stream사용시 코드가 간결해지는 이유 중 하나는 '내부반복' 때문이다. 기존 선언형 프로그래밍에서는 반복문을 사용하기 위해 for나 while 등과 같은 명령을 사용해야 했지만, Stream에서는 메소드 내부에 반복문이 내제되어 있으므로 생략이 가능하여 코드가 간결해 진다.

--> forEach 함수의 인자 값 으로 함수형인터페이스 "Consumer" 를 받는다.  

 * Consumer - "객체"를 T매개변수로 받으며, 반환 값 이 없는 함수형 인터페이스 

 


3. Stream API 연산종류 

--> Stream은 데이터를 처리하기 위한 다양한 연산들을 지원한다. Stream이 제공하는 연산은 큰 맥락으로 (생성하기, 가공하기, 결과만들기) 3가지 단계로 나뉜다.

생성하기 Stream객체를 생성하는 단계
Stream은 재사용이 불가능하므로 한번 사용이 끝날 시, 다시 생성해주어야 한다. 
Stream 연산을 수행하기 위해, 우선 Stream객체를 생성해 주어야 한다. "Array", "Collections", "RandomNumbers", "File".. 등 여러요소를 기반으로 Stream을 생성할 수 있다. 주의할 점은 연산이 끝나면 Stream이 닫히기 때문에, Stream이 닫혔을 경우 다시 Stream을 생성해야 한다는 것 이다.
가공하기 원본의 데이터를 별도의 데이터로 가공하기 위한 연산작업 (여러 연산작업 반복가능)
연산된 결과를 Stream으로 다시 반환하기 때문에 연속해서 연산을 이어갈 수 있다. 
가공하기 단계는 원본의 데이터를 별도의 데이터로 변형하는 중간 연산단계이다. 특정 원본데이터로 생성된 Stream을 원하는 형태로 처리할 수 있으며, 연산의 반환값은 Stream이기 때문에 필요에 따라 중간연산을 연결해서 사용할 수 있다.
결과만들기 가공된 데이터로부터 원하는 결과를 만들기위한 최종연산 (최종 반환)
Stream의 요소들을 소모하면서 연산이 수행되기 때문에 한번만 처리가능하다.

 

* 원본데이터로(List<String>) 부터 스트림(Stream)을 생성한다. 

 

* 생성된 스트림을 3번의 가공작업(데이터필터, 데이터변형, 데이터정렬)을 수행한다.

 (연속적인 Stream연산 == Pipeline으로 부르기도 한다) 

 

* 위 3번의 가공작업에 관한, 최종연산을 통하여 결과를 도출한다.

 

* Stream연산들은 함수형 인터페이스(Functional Interface)를 인자로 받는다. 

  (함수형 인터페이스는 Java8 "Lambda 표현식"으로 구현한다)

 

 

 

Exit..