람다를 제대로 활용하기 위해선 Java의 Collection과 Stream에 대한 정리가 필요할 것이라 생각하여 글을 포스팅 한다.
우선 사용하게 될 package들을 정리해 보았다.
- java.util.Collection(Interface)
- List, Set, Map CRUD를 위해서 활용한다.
- java.util.Collections(Class)
- Collection Inteface의 객체들을 관리하는 클래스이다.
- 객체간의 변환과 객체의 데이터를 탐색하는 기능을 주로 가진다.
- java.util.Arrays
- [ ]형태의 배열 또는 Collection 이너페이스의 객체들을 배열로 관리하는 기능을 가진다.
람다식 활용법
- 1. 람다식을 활용하기 위해서 Stream으로 바꾸는 방법
- stream() 을 사용하거나 java.util.stream의 stream.of() 함수를 이용한다.
- stream의 객체 생성 -> 집계 연산, 탐색, 출력(중간 작업/ 종단 작업) Collection -> stream 방식을 활용하면 된다.
- 2. Stream에서 다시 Collection으로 바꾸는 방법
- java.util.stream.Stream의 Collect()를 통해서 Collection 객체로 변환한다.
- 방법 1
- Collect(Collector c)
- List, Set, Map 변환 작업 후 각 개체의 메소드를 통해 데이터를 처리할 경우 사용
- 방법 2
- Collect(Supplier, BiConsumer, BiConsumer)
- List, set, map에 존재하지 않는 경우 사용, 확장할 수 있는 기능을 사용하고 싶을 때 사용한다.
- 방법 1
- java.util.stream.Stream의 Collect()를 통해서 Collection 객체로 변환한다.
Collectors의 메소드 정리
1. group by
- groupingBy(Function<? super T, ? extends K> classifier):
- 대상 조건은 function으로 이용하여 스트림의 각 요소를 변환한 결과가 true 값일 때 실행되는 구문으로 지정한다.
- groupingBy(Function<? super T, ? extends K> classifier, Collector<? super T,A,D> downstream)
- 첫번째 매개인자 Function으로 스트림의 각 요소를 변환한 결과를 리턴하는 객체이며 두 번째 매개인자는 리턴되는 객체가 어떻게 유지되는 지 결정한다.
- groupingBy(Function<? super T, ? extends K> classifier, Supplier<M> mapFactory, Collector<? super T,A,D> downstream)
- 첫번째 매개인자 Function으로 스트림의 각 요소를 반환한 결과를 리턴하는 객체, 두번째 매개인자는 리턴되는 객체를 Map으로 지정하고 세번째 매개인자는 Map을 어떻게 유지할지 결정한다.
2. join
- joining()
- 문자열 스트림 요소를 연결한 문자열을 생성하는 메소드
- joining(CharSequence delimeter)
- 구분자를 지정해서 문자열의 스트림 요소를 생성
- joining(CharSequence delimeter, CharSequence prefix, CharSequence suffix)
- 구분자의 시작태그 끝 태그 지정
GroupBy와 Join을 사용한 예제
System.out.println("1. 나열된 문자열의 길이로 그룹핑");
Stream<String> s= Stream.of("나","너","우리","모두","노래해요");
Map<Integer, List<String>> res= s.collect(Collectors.groupingBy(t->t.length()));
System.out.println(res);
//결과
//{1=[나, 너], 2=[우리, 모두], 4=[노래해요]}
groupingBy를 활용하여 문자열의 길이 별로 다르게 매핑하였다. 결과 값에서 볼 수 있듯이 길이에 따라 다르게 매핑된 것을 볼 수 있다.
System.out.println("2. 나열된 문자열의 길이로 그룹핑 + join");
Stream<String> s01= Stream.of("나","너","우리","모두","노래해요");
//조인은 문자열로
Map<Integer, String> res01=
s01.collect(Collectors.groupingBy(t->t.length(),Collectors.joining()));
System.out.println(res01);
//결과
//{1=나너, 2=우리모두, 4=노래해요}
결과 값에 Join을 사용해서 문자열을 이어붙인 결과이다. 리턴되는 객체가 어떻게 유지될지를 설정할 수 있는 매개인자 2개까지 groupingBy 문에 joining을 활용하여 문자열을 이어 붙여 주었다.
System.out.println("3. 나열된 문자열의 길이로 그룹핑 + join 매개인자 세개");
Stream<String> s02= Stream.of("나","너","우리","모두","노래해요");
Map<Integer,String> res02
=s02.collect(Collectors.groupingBy(t->t.length(),
TreeMap::new,Collectors.joining()));
System.out.println(res02);
//결과
//{1=나너, 2=우리모두, 4=노래해요}
매개인자 3개짜지 groupingBy문을 이용하여 리턴되는 map객체의 형태와, joining을 지정하는 방식을 활용하였다.
Stream<String> s01= Stream.of("딸기","바나나","메론","포도");
String str=s01.collect(Collectors.joining());
System.out.println(str);
//결과
//딸기바나나메론포도
s01= Stream.of("딸기","바나나","메론","포도");
str=s01.collect(Collectors.joining(":", "<<",">>"));
System.out.println(str);
//결과
//<<딸기:바나나:메론:포도>>
위의 첫번째 예제에서는 collect의 joining을 사용하여 모든 문자열을 이어 붙여 주었으며, 두 번째 예제에서는 문자열 연결시 " : "로 구분 지으며 prefix에는 << , suffix에는 >>를 넣어 주는 문자열을 만들어 주었다. 추후 문자열을 관리함에 있어 자주 사용될 수 있는 구문이므로 익혀두면 분명 도움이 될 것이다.
3. partition
- partitioningBy(Predicate<? super T> predicate)
- 매개인자 판정을 기준으로 true, false를 분할 시킨다.
- partitioningBy(Predicate<? super T> predicate, Collector<? super T,A,D> downstream)
- 매개인자 판정을 기준으로 true, false를 분할하고 Collector의 Map에다가 저장하는 방식이다
Stream<Character> str= Stream.of('1','2','a','b','3');
Map<Boolean, List<Character>> res=
str.collect(Collectors.partitioningBy(c->Character.isDigit(c)));
System.out.println(res);
//결과
//{false=[a, b], true=[1, 2, 3]}
str= Stream.of('1','2','a','b','3');
Map<Boolean, String> res02=
str.collect(Collectors.partitioningBy(c->Character.isDigit(c),
Collectors.mapping(c->c.toString(), Collectors.joining())
)
);
System.out.println(res02);
//결과
//{false=ab, true=123}
위의 첫 번째 에제에서는 문자인지 숫자인지를 판별 기준으로 나누어서 각각을 다른 카테고리로 저장시켜 주었다. 반면 두번째 함수에서는 인자가 두 개 짜리인 partitioningBY를 활용하여, Map에 저장될 방식을 재정의 함으로서 만들어진 문자열들을 이어 붙여주는 방식을 활용하였다.
4. 집계
stream 컬랙션의 값을 집계를 낸 후 숫자로 변경해서 연산하는 메소드들을 정리하였다.
- IntSummaryStatistics
- 합계, 최소, 최대, 평균, 개수를 산출하여 int로 리턴
- LongSummaryStatistics
- DoubleSummaryStatistics
- minBy
- 최소 값
- maxBy
- 최대 값
String[] my_str= {"딸기","바나나","메론","포도"};
Stream<String> s= Stream.of(my_str);
Optional<String> m=s.collect(Collectors.minBy(Comparator.naturalOrder()));
System.out.println("최소값 ="+ m);
//결과
//최소값 =Optional[딸기]
s= Stream.of(my_str);
m=s.collect(Collectors.maxBy(Comparator.naturalOrder()));// 자연 정렬
System.out.println("최대값 ="+ m);
//결과최대값 =Optional[포도]
//
//카운팅
s= Stream.of(my_str);
System.out.println("counting:" +s.collect(Collectors.counting()));
//결과
//counting:4
// 서머리 집계를 해보자.
s= Stream.of(my_str);
IntSummaryStatistics res= s.collect(Collectors.summarizingInt(t->t.length()));
System.out.println(res);
//결과
//IntSummaryStatistics{count=4, sum=9, min=2, average=2.250000, max=3}
Stream<String> s04= Stream.of("10","20","30","40","50");
LongSummaryStatistics res01=s04
.collect(Collectors
.summarizingLong(t->Long.parseLong(t)));
System.out.println(res01);
//결과
//LongSummaryStatistics{count=5, sum=150, min=10, average=30.000000, max=50}
'JAVA' 카테고리의 다른 글
JAVA 스트림(Stream) 정리 (0) | 2021.09.17 |
---|---|
함수형 인터페이스(Functional Interface) & 기초 람다 (0) | 2021.09.17 |
JavaFX GUI활용한 프로그램 개발 (0) | 2021.08.12 |
JAVA 클래스와 객체 (0) | 2021.08.10 |
java와 javac 버전이 다를 때 해결법(Window) (0) | 2021.07.20 |