GitHub

https://github.com/Backcoder-June

BackCoder 기록 그리고 숙달

Back to the Java

[ Stream] 기본 문법

Backcoder 2023. 1. 13. 09:05

- 기본적으로 Lambda 식과 함께 이용됩니다.

- JavaScript 에서는 '화살표 함수' 로 함수를 전달 할 수 있는 기능과 유사합니다. 

https://backcoder.tistory.com/48

 

Lambda 식 ( ) -> { };

< Lambda 식 > 사용조건 1. 인터페이스 일때만 가능하고 2. 인터페이스에 메소드가 하나만 있을때 가능하다. 람다식은 포켓몬 진화 완전체 같은거다. ( 기본 인터페이스 사용 ) - 이상해씨 interface A{ v

backcoder.tistory.com

 

[ 점점 더 간단하게 ] 

 

직접 '클래스' 를 만들고 interface 를 상속해서 사용 

=> 내부 클래스로 사용 

=> 익명객체로 사용 

=> Lambda 식 

 

 

[ Stream ] 

자료구조들에서 특정 조건에 해당하는 데이터만 필터링 하고, 

데이터들을 특정 순서로 정렬하고 

데이터들을 연산하는 등 다양한 기능을 짧은 문법으로 제공 

 

.stream ( 펴기 )

.filter ( 필터링 ) : 10개의 데이터 중 해당되는 x 개를 필터링

.map ( 특정 필드값만 가져오기 : 10개의 데이터 중 10개 데이터의 특정값 만 가져옴) 

=> a -> a.getName( )  이렇게 특정 필드값 가져오는 용도로 사용할 수도 있고 
=> a -> a / 100  이렇게 데이터를 조작해서 리턴시키는 요도로 사용할 때도 map 사용 

 

.mapToInt
: 기존 map 에 추가기능(연산) 제공
int 타입으로 확실히 mapping해줬기 때문에 
.sum / .average /.max 등 int 다루는 기능들 제공 

=> 최소/ 최대값 등에 대한 객체 정보 전체를 가져올 때는 
바로 .stream().min() 땡기고 이후에 Comparator 로 비교값 줘서 가져와서 사용 

- .sorted ( 정렬 ) 

=> String / 숫자 는 자동정렬 ( .sorted()  ) 
=> Comparator.comparing( a-> a.비교대상 )

 

.distinct ( 중복제거 )
.limit ( 순서대로 몇개 ) 
.collect ( 최종 자료구조로 모으기 ) 
.forEach ( 하나하나 흩뿌려서 작업 ) 

.ifPresent 
=> 존재하면 진행시키고 / 존재안하면 안함 


[[ Match - boolean ]] 

: - filter 등 돌리고, 거기서 match 찾는 식으로 사용

[ .anyMatch ]  
: 주어진 Stream 에서 적어도 한 요소라도 일치하는게 있는지 확인 

[ .allMatch ] 
: 모두 조건에 통과하는가 

[ .nonMatch ] 
: 하나도 없는가 

 

 

( 예시 코드 )

package stream.practice;

import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.stream.Collectors;

public class TradeMain {
    public static void main(String[] args) {

        Trader raoul = new Trader("Raoul", "Cambridge");
        Trader mario = new Trader("Mario", "Milan");
        Trader alan = new Trader("Alan", "Cambridge");
        Trader brian = new Trader("Brian", "Cambridge");

        List<Trading> tradings = List.of(
                new Trading(brian, 2021, 300),
                new Trading(raoul, 2022, 1000),
                new Trading(raoul, 2021, 400),
                new Trading(mario, 2021, 710),
                new Trading(mario, 2022, 700),
                new Trading(alan, 2022, 950)
        );

        // 2021 발생 모든 거래 찾아 거래액 오름차 정렬
        List<Trading> collect2 = tradings.stream()
                .filter(trading -> trading.getYear() == 2021)
                .sorted(Comparator.comparing(t -> t.getValue()))
                .collect(Collectors.toList());
//                .forEach(a -> System.out.println(a));

        // 거래자가 근무하는 모든 도시이름을 중복 없이 나열
        List<String> collect1 = tradings.stream()
                /*.map(c -> c.getTrader())
                .map(tradername -> tradername.getCity())*/ // 이렇게 두번에 나눠서 하는걸
                .map(c -> c.getTrader().getCity()) // 바로 한방에 하면 된다.
                .distinct()
                .collect(Collectors.toList());
//                .forEach(a -> System.out.println(a));

        System.out.println("---------------------------------");

        // cambridge 에 근무하는 모든 거래자를 찾아 이름순 오름차 정렬
        List<Trader> collect = tradings.stream()
                .map(trading -> trading.getTrader())
                .filter(trader -> trader.getCity().equals("Cambridge"))
                .sorted(Comparator.comparing(tr -> tr.getName()))
                .collect(Collectors.toList());
//                .forEach(a -> System.out.println(a));

        System.out.println("------------------------");

        // 모든 거래자 이름을 리스트에 모아서 알파벳 순으로 오름차 정렬
        List<String> collect3 = tradings.stream()
                .map(trading -> trading.getTrader().getName())
                .sorted() // String 이나 숫자 타입이면 자동정렬 ( Comparator 필요없음 )
                .collect(Collectors.toList());
//                .forEach(a-> System.out.println(a));


        // 거래액 500 초과 큰 거래액 순서로 정렬
        tradings.stream()
                .filter(trading -> trading.getValue() > 500)
                .sorted(Comparator.comparing(Trading::getValue).reversed())
                .collect(Collectors.toList())
                .forEach(b -> System.out.println(b));



        System.out.println("==================");
        // 연습 5: Milan에 거주하는 거래자가 한명이라도 있는지 여부 확인?
        boolean milanbln = tradings.stream()
                .anyMatch(t -> t.getTrader().getCity() == "Milan");
                /*.map(a -> a.getTrader())
                .anyMatch(b -> b.getCity() == "Milan");*/ // map 으로 안돌리고 바로 anyMatch 에서 두번 뽑으면 된다.

        System.out.println(milanbln);


        System.out.println("==================");
        // 연습 6: Cambridge에 사는 거래자의 모든 거래액의 총합 출력.

        int cambridgeTotalSum = tradings.stream()
                .filter(f -> f.getTrader().getCity().equalsIgnoreCase("Cambridge"))
                .mapToInt(a -> a.getValue())
                .sum();

        System.out.println(cambridgeTotalSum);


        System.out.println("==================");
        // 연습 7: 모든 거래에서 최고거래액은 얼마인가?
        OptionalInt maxTradeValue = tradings.stream()
                .mapToInt(a -> a.getValue())
                .max();

        maxTradeValue.ifPresent(mtv -> System.out.println(mtv));

        System.out.println("====================");
        // 가장 작은 거래액 가진 거래정보 탐색 => min 을 바로 쓰고 Comparator 로 나중에 비교 값 주기
        Optional<Trading> min = tradings.stream()
                .min(Comparator.comparing(a -> a.getValue()));

        min.ifPresent(mv -> System.out.println(mv));



    }
}