Java

[Java8] Stream(스트림) - map/filter/sort/distinct

didue 2021. 11. 24. 08:06
반응형

 

 

Java8에서 선보인 Stream API를 근래 업무에서 너무 편하게 잘쓰고있어서 정리해보려 한다.

필요의 순간에 아주 유용하게 쓸 수 있는 API니 잘 알아두자!

Java Stream

기존에 자바 Collection이나 Array의 요소를 가공할 때는 loop(for, foreach)를 사용해서 요소를 골라내는 작업을 했다면, Stream은 람다형(함수형 인터페이스) 으로 간단하게 요소를 처리할 수 있도록 한다

장점

  • 코드의 양을 줄여 간결하게 표현
  • 손쉬운 병렬처리(multi-threading)

 


 

Stream 사용법

 

객체집합.스트림생성.중개연산.최종연산

이러한 형태의 기본문법으로 사용한다. 

스트림 생성

Collection과 Array와 같은 객체집합으로 스트림을 생성한다.

이외에도 다양한 방법으로 스트림을 생성할 수 있다. ( ※ 참고 사이트가 도움이 될 수 있습니다😊) 

중개연산

중개연산은 원소를 가공하는 연산으로서 자주 사용하게되는 메소드를 정리해보았다. 

Method Description etc.
map 특정조건의 요소의 값 반환(연산) 요소들의 대,소문자 변형
filter 조건에 맞는 요소만 필터링 길이제한, 특정문자 포함단어 취득 등의 작업
sorted 요소 정렬 요소들을 정렬 
distinct 요소 중복 제거 중복되지 않은 요소들로 정제하는 작업



filter()

요소에서 특정 원소를 filtering하는 메소드로써, List나 Array에서 원치 않게 null(혹은 공백 "")이 들어올 경우 등의 손쉽게 처리할 수 있습니다.

//원래의 배열
String[] fruits = {"apple", "grape", "orange" , null, "banana", ""};
//null요소를 제거된 새로운 배열
String[] existed = {};

//stream().filter()
existed = Arrays.stream(fruits).filter(item -> isNotNull(item))
                .toArray(String[]::new);
                
//결과 
// ["apple", "grape", "orange", "banana"]



distinct()

distinct 메소드로 원소의 중복을 쉽게 처할 수 있습니다.

//원래의 배열
String[] fruits = {"apple", "grape", "orange" , "grape", "banana", "banana"};
//null요소를 제거된 새로운 배열
List<String> distincted = new ArrayList<>();

//stream().distinct()
distincted = Arrays.asList(elements).stream().distinct().collect(Collectors.toList());

//출력
distincted.forEach(System.out::println);

//Result :
//apple
//grape
//orange
//banana

 

최종연산

최종연산은 스트림 요소들을 다시 모으거나, 값을 세는 등 앞선 중개연산을 통해 가공한 스트림 요소를 마무리하는 단계이다.

 

collet()

스트림의 값들을 다시 모아주는 메소드.  toMap, toSet, toList로 다시 Collection으로 바꿔준다.

/**
 * 중복요소 제거
 * @param key
 * @param target
 * @return
 */
public List<String> distinctElements(List<Map<String, Object>> resultData, String key){ 
	
	List<String> target = mkListFromMap(resultData, key);
	
	if(target != null){
		target = target.stream().filter(distinctByKey(value-> value)).collect(Collectors.toList());
	}
	
	return target;
}

private <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
	
	Map<Object,Boolean> seen = new ConcurrentHashMap<>();
	return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}

 

위 코드는 최근 업무에서 Stream을 사용하여 작성한 중복요소 제거코드이다. 앞서 작성한 내용들을 응용한 부분이니 이해하여보고 다시 본인만의 스타일대로 응용해보는것도 좋을것같다^_^

 




- 참고사이트 

https://docs.oracle.com/javase/8/docs/api/index.html

https://futurecreator.github.io/2018/08/26/java-8-streams/

https://dpdpwl.tistory.com/81

반응형