반응형

본 글은 책 자바의 정석을 ref 하여 요약한 것입니다.


https://komas.tistory.com/68

 

[JAVA]자바 익명 클래스와 람다식 정리

익명 클래스는 말 그대로 클래스의 이름이 없다는 말이다. 이름이 없으므로 생성자를 가질 수 없다. 익명 클래스를 정의하려면 상속을 받거나 인터페이스로 구현해야한다. 참조 변수에 넣어두

komas.tistory.com

 

https://komas.tistory.com/69

 

[JAVA] 자바 메소드 참조

메서드 참조란 말 그대로 다른 클래스의 메소드를 참조하여 사용한다입니다. 빌려쓴다고 이해하시면 편합니다. (호출이 아닌 구현부를 빌림) 코드로 설명하겠습니다. public class ProviderClass { public

komas.tistory.com

 

 

 

 


 

스트림

자바 8부터 추가된 함수적 스타일 처리

중간처리는 지연되고, 최종 처리가 시작되면 처리를 시작한다.

 

✔ 스트림의 종류

Stream, IntStream, LongStream, DoubleStream

 


 

✔ 스트림 만들기

List<Integer> list = Arrays.asList(1,2,5,3);
Stream<Integer> slist= list.stream();

long[] arr = {1,2,10,5,3,4,3};
LongStream sarr = Arrays.stream(arr);

 

컬렉션 프레임워크는 Stream<T>  로 변환된다.

mapToXXX()로 변환하면 IntStream, LongStream, DoubleStream로 변경할 수 있다.

 

기본형 배열은 type에 맞게  IntStream, LongStream, DoubleStream 로 변환된다.

객체 배열일 경우 Stream<T> 로 변환된다.

 

 

객체는 Stream<T>

기본형 배열은 IntStream, LongStream, DoubleStream

 

 


 

✔ 중간 처리 함수

매핑, 필터링, 정렬

 

 

skip(n)

개수만큼 건너뛴다.

 

 

limit(n)

개수만큼 제한한다.

 

 

peek(Consumer)

forEach와 비슷한 역할을 하는 중간 연산이라고 보면 된다.

보통 단순히 중간 조회를 위해 사용됨

 

 

distinct()

중복을 제거한다. equals() 값이 같으면 제거, IntStream, LongStream, DoubleStream 일 경우 값이 같으면 제거

 

 

filter(Predicate)

true인 값만 남기고 제거한다.

 

 

map(Function)

요소를 대체하는 새로운 요소로 구성된 스트림을 만든다. (보통 type변환, 일괄 연산 등)

 

map() -> (객체 -> 객체), (기본형 -> 기본형), 값 변환

mapToInt -> IntStream으로 변환

mapToLong -> LongStream으로 변환

mapToDouble -> LongStream으로 변환

mapToObj -> 객체로 변환

type 변환과 값 변경도 가능

 

List<Integer> list = Arrays.asList(1,2,5,3);
Stream<Integer> slist= list.stream();
IntStream is = slist.mapToInt(e->e);

long[] arr = {1,2,10,5,3,4,3};
LongStream sarr = Arrays.stream(arr);
Stream<Integer> bs = sarr.mapToObj(e -> (int) e);

 

flatMap()

스트림의 요소가 배열일때  flatten Stream을 만들 때 사용한다.

 

 

boxed()

IntStream, LongStream, DoubleStream  ---->   Stream<T>

 

 

sorted(Comparator)

정렬을 제공한다.

Comparable이 제공된 객체를 사용하거나, Comparator를 제공해주면 된다.

* IntStream, LongStream, DoubleStream 일 경우 인수를 제공하지 않으면 오름차순으로 정렬, 내림차순을 원할 경우 Comparator.reverseOrder()

 

* thenComparing() - 정렬 추가가 가능

* reversed() - 내림차순 가능

 

List<Student> students = Arrays.asList(
                new Student("Lee", 1),
                new Student("Lee", 2),
                new Student("Park",1),
                new Student("Park",2),
                new Student("Kim",2)
        );

       List<Student> sortedList= students.stream().sorted(
               Comparator.comparing(Student::getName)
               .thenComparing(Student::getNumber)
               .reversed()
               ).collect(Collectors.toList());

        System.out.println(sortedList);
        
//        [Student{name='Park', number=2}, Student{name='Park', number=1}, 
//        Student{name='Lee', number=2}, Student{name='Lee', number=1}, Student{name='Kim', number=2}]

 


 

✔ 최종 처리 함수

반복, 카운팅, 평균, 총합

최종 처리 함수의 반환 타입은 기본형이거나 OptionalXXX

 

 

forEach(Consumer)

요소를 하나하나씩 처리한다.

 

 

sum() - IntStream, LongStream, DoubleStream

반환 타입

타입에 맞는 기본형

 

 

count() - IntStream, LongStream, DoubleStream

반환 타입

long

 

 

max(), min() - IntStream, LongStream, DoubleStream

Stream<T> 일 경우 인수로 Comparator 필요

IntStream, LongStream, DoubleStream 일 경우 필요하지 않다.

반환 타입

Stream<T>일 경우 Optional<T>

IntStream, LongStream, DoubleStream 일 경우 OptionalXXX

 

 

average() - IntStream, LongStream, DoubleStream

반환 타입

OptionalDouble

 

 

findFirst()

반환 타입

Stream<T>일 경우 Optional<T>

IntStream, LongStream, DoubleStream 일 경우 OptionalXXX

 

 

reduce(identify, BinaryOperator)

identify는 요소가 없을 때 반환하는 값(Default)

BinaryOperator에 요소 하나하나씩 누적해가며 계산한다.

반환 타입

identify를 지정하면 기본형으로 반환

지정하지 않으면 OptionalXXX로 반환

 

 

allMatch(Predicate)

모든 요소가 일치하면 true 반환

anyMatch(Predicate)

하나의 요소라도 true라면 true 반환

noneMatch(Predicate)

모든 요소가 false라면 true 반환

 


 

✔ collect(Collector)

collect 함수는 내부에 수집기를 정의해줘야 한다.

보통 Collectors(수집기 구현체)에 구현된 메서드들을 활용한다.

 

Student[] students = {new Student("Lee",23), new Student("Park",26), new Student("Kim",26)};

List<Integer> ageList = Arrays.stream(students)
        .map(e-> e.age)
        .collect(Collectors.toList());
System.out.println("ageList " + ageList);

Set<Integer> ageSet = Arrays.stream(students)
        .map(e-> e.age)
        .collect(Collectors.toSet());
System.out.println("ageSet " + ageSet);

TreeSet<Integer> ageTreeSet = Arrays.stream(students)
        .map(e -> e.age)
        .collect(Collectors.toCollection(()-> new TreeSet<Integer>())); // TreeSet::new
System.out.println("ageTreeSet " + ageTreeSet.higher(23));

 

 

 

collect() 사용자 직접 정의

Collector(수집기) 인터페이스를 구현하기 위해선 대략 3가지의 요소가 필요하다.

 

supplier

 - 수집된 데이터를 담을 구현체 생성 (싱글 스레드는 하나, 멀티 스레드는 여러개가 생성)

accumalator

 - 생성된 객체에 원하는 요소 수집

combiner

 - 병렬 처리된 각 컨테이너 객체들을 결합 지정

 

List<Student> students = Arrays.asList(
        new Student("Lee", 1),
        new Student("Park",1),
        new Student("Kim",2),
        new Student("Cha",2)
);

List<Student> ls = students.stream().
        filter((s)-> s.getNumber() == 1).
        collect(ArrayList::new, List::add, List::addAll);

System.out.println(ls);
// [Student{name='Lee', number=1}, Student{name='Park', number=1}]

 

 

 

collect() 그룹핑

Collectors.groupingBy()

- 내부에서 key, Collector(수집기)를 지정한다.

 

Collectors.mapping(Function, Collector)

- 매핑한 후 Collector(수집기)를 사용한다.

 

List<Student> students = Arrays.asList(
        new Student("Lee", 1),
        new Student("Park",1),
        new Student("Kim",2),
        new Student("Cha",2)
);

Map<Integer, List<Student>> m1 = students.stream()
        .collect(Collectors.groupingBy(Student::getNumber)); // key
System.out.println(m1);
// {1=[Student{name='Lee', number=1}, Student{name='Park', number=1}], 2=[Student{name='Kim', number=2}, Student{name='Cha', number=2}]}


Map<Integer,List<String>> m2 = students.stream()
                .collect(Collectors.groupingBy(
                        Student::getNumber, // key
                        Collectors.mapping(Student::getName, Collectors.toList()))); // value
System.out.println(m2);
// {1=[Lee, Park], 2=[Kim, Cha]}


Map<Integer,List<String>> m3 = students.stream()
        .collect(Collectors.groupingBy(
                Student::getNumber, // key
                HashMap::new, // 구현체 지정 가능
                Collectors.mapping(Student::getName, Collectors.toList()))); // value
System.out.println(m3);
// {1=[Lee, Park], 2=[Kim, Cha]}

 

 

 

partioningBy(Predicate, Collector)

true인 것만 적용하여 분리

반환 타입은 <boolean>

 

 

Collectors 수집기 함수

averagingDouble() 

counting()

maxBy(Comparator)

minBy(Comparator)

summingInt, Long, Double()

 

reducing(identity, BinaryOperator

joining(구분자) - 문자열 결합

 

 

 

collect 개략도

collect( 수집기 )

collect( Collectors.groupingBy ( 키, 수집기 ) )

collect( Collectors.groupingBy ( 키, Collectors.mapping ( 매핑, 수집기 ) )

 

 

 


 

반응형

+ Recent posts