- 스트림(Stream) 이란?

 

자바8 이전에는 배열이나 컬렉션 안의 각 요소들에 접근하기 위해 for나 Iterator 등을 사용했는데,

자바8 부터는 Stream을 이용해서 보다 간결하고 가독성 높은 코드로 각 요소들에 접근하고, 컨트롤하는 것이 가능해졌다.

또 하나의 장점은 병렬처리가 가능하다는 점으로, 쓰레드를 이용해 많은 요소들을 빠르게 처리할 수 있다.

 

스트림은 선언, 가공, 반환 세 부분으로 이뤄진다. 

// 스트림 선언 방법
Stream<타입> stream명 = Arrays.stream(배열명);
Stream<타입> stream명 = 리스트명.stream();
Stream<타입> stream명 = Stream.of('값', '값'....);

 

가공부에서는 제공하는 메소드들을 이용해 요소들을 원하는 형태로 가공하며,

반환부를 통해 원하는 타입으로 다시 반환 받을 수 있다. 

 

다음은 리스트 'langs' 를 sorted() 메소드를 이용해 정렬(가공) 후, 다시 리스트로 반환하는 코드이다.

langs.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());

 

장점으로는 사용하기 편하고, 코드가 짧아지며 그러므로 가독성이 높아진다는 것. 
단점으로는 디버깅이 어려움. 그리고 한번 사용하면 close되기 때문에 재활용이 불가능하다는 단점이 있다. 

스트림(Stream)을 이용하면 배열이나 컬렉션(List, Map, Set)등을 사용해 원하는 값을 얻고자 할 경우,
For문의 도배를 줄일 수 있고, 이미 정의되어 있는 많은 메소드들을 이용하여 원하는 값을 쉽게 가져올 수 있다. 
다만, 디버깅이 어렵다는 단점이 있다. 

디버깅이 어려운 이유는 스트림은 한번에 모든 것이 수행되기 때문에, 에러나기 직전에 디버깅을 거는것이 불가능하다. 
따라서 스트림 안에서 에러 발생 시, 모두 분해 후 재 조립하는 과정을 거쳐야 한다. 

 

 

- 제공하는 함수들

filter 
sorted
allMatch : return boolean
anyMatch : return boolean
noneMatch : return boolean
max(Comparator.comparing(객체::값)) : return Optionnal<객체>
min(Comparator.comparing(객체::값)) : return Optionnal<객체>
collect(Collectors.groupingBy(객체::값)) : return Map<그룹핑 값, List<객체>>

.

.

 

예제 )

public static void main (String[] args) {
	List<String> langs = Arrays.asList("Java", "Scala", "React", "Swift", "Angular");
		
	// forEach() 순차 접근
	langs.stream().forEach(System.out::println);
		
	// sorted() 정렬
	langs = langs.stream().sorted().collect(Collectors.toList());
		
	// sorted(Comparator.reverseOrder()) 역순 정렬
	langs = langs.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
		
	// filter( input Param -> method ) 필터
	langs = langs.stream().filter( name -> name.contains("a")).collect(Collectors.toList());
		
		
	List<People> peoples = People.getPeopleList();
/* peoples
People[name:홍길동, age:17, gender:1]
People[name:홍길자, age:18, gender:2]
People[name:홍길남, age:13, gender:1]
People[name:홍길순, age:15, gender:2] */
		
		
	// 조건이 모두 match 하는지 (return : boolean으로 anyMatch, noneMatch도 있음.)
	peoples.stream().allMatch( person -> person.getName().contains("홍"));

	// 특정 속성 값에 대해 최대값을 가지는 요소 구하기.
	Optional<People> maxPeople = peoples.stream().max(Comparator.comparing(People::getAge));
	if(maxPeople.isPresent()) {
		System.out.println("나이가 많은 사람은?");
		System.out.println(maxPeople.toString()); // Optional[People[name:홍길자, age:18, gender:2]]
	}
    
    // 그룹핑
    Map<Integer, List<People>> groupByGender = People.getPeopleList().stream().collect(Collectors.groupingBy(People::getGender));
    System.out.println("남/여 목록");
    groupByGender.forEach((gender, peopleList) -> {
    System.out.println(gender);
    peopleList.forEach(System.out::println);
    });
	
/* 남/여 목록
1
People[name:홍길동, age:17, gender:1]
People[name:홍길남, age:13, gender:1]
2
People[name:홍길자, age:18, gender:2]
People[name:홍길순, age:15, gender:2] */
}

+ Recent posts