ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • java stream Util 만들기
    개발/java 2024. 9. 4. 10:14

    java에서 제공하는 stream을 이용하여 코드를 단축할 수 있다 

    아래와 같이 Map을 통해 그룹핑을 하는 과정이다 

    Map<String, List<OrderInfo>> collect = orderInfoList.stream()
            .collect(Collectors.groupingBy(t -> t.getTrNo()+"-"+ t.getLrtrNo()));
    
    Map<String, OrderInfo> collect1 = orderInfoList.stream()
            .collect(Collectors.toMap(t -> t.getTrNo() + "-" + t.getLrtrNo(), Function.identity(), (t1, t2) -> t1));

     

    우선 그룹핑을 하기 위한 조건을 보면 변수 사이를 "-"를 묶어서 키로 만드는 과정을 볼 수 있다 

    이를 코드화하면 아래와 같다  

    //키를 사용할 변수를 args로 받아서 이를 하나의 string으로 변환해준다 
    //예를 들면 주문번호-상품번호로 변환한다
    public static String createKey(String... args) {
        return Arrays.stream(args).filter(StringUtils::isNotEmpty)
        .collect(Collectors.joining("-"));
    }

     

    이제 이를 공통으로 사용하여 아래와 같이 변환할 수 있다 

    Map<String, List<OrderInfo>> collect = orderInfoList.stream()
            .collect(Collectors.groupingBy(t -> createKey(t.getTrNo(), t.getLrtrNo()));

     

    Collectors.groupingBy , Collectors.toMap도 줄여보자 

    우선 두 그룹의 경우 Map을 반환하며 value로 List , Object를 반환하는 방식이다 

    private <K,T>  Map<T,K> convertListToMap(List<K> list, Function<K,T> Key) {
    
        return list.stream().collect(Collectors.toMap(Key,  Function.identity()));
    }
    
    private <K,T>  Map<T,List<K>> convertListToMap(List<K> list, Function<K,T> Key) {
    
        return list.stream().collect(Collectors.groupingBy(Key, Collectors.toList()));
    }

     

     

    이제 이를 활용하여 불필요한 코드를 단축 시킬 수 있다 

    @NoArgsConstructor
    @AllArgsConstructor
    @Getter
    class OrderInfo{
        private String odNo;
        private String trNo;
        private String lrtrNo;
    }
    
    @Test
    public void testStream() {
    
        List<OrderInfo> orderInfoList = new ArrayList<>();
    
        Map<String, OrderInfo> stringOrderInfoMap =
                convertToMap(orderInfoList, t -> createKey(t.getTrNo() , t.getLrtrNo()));
    
    
        Map<String, List<OrderInfo>> stringListMap
                = convertListToMap(orderInfoList, t -> createKey(t.getTrNo(), t.getLrtrNo()));
    
    }

     

    또 하나는 중복제거 기능이다

    예를 들어 주문한 고객에게 배송이 지연되어 지연 관련 양해 알림톡을 발송한다고 하자 

    그럼 해당 발송 시점에 상품 건별로 알림을 보내는것이 아니라 해당 고객에게 보내면 다시 안보내야 고객의 불편함을 감소 시켜 줄 수 있다 

    보통 일반적으로 이 경우는 쿼리 내에서 그룹핑을 해서 하지만 아래와 같이 stream과 HashSet을 결함하여 고객에게 재발송을 방지할 수 있다. 

    public static <T> Predicate<T> distinctByKey(
            Function<? super T, ?> keyExtractor) {
    	//set에 적재를 하고 한번 적재가 된 경우는 false를 return 하여 대상에서 제외를 한다 
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

     

    이를 이제 알림톡 로직에 붙이면 한번 발송된 고객에게는 발송이 되지 않는다 

    orderInfoList.stream()
           .filter(distinctByKey(OrderInfo::getTrNo))
            .forEach(t-> System.out.println("알림톡 발송 로직 수행 "));

    '개발 > java' 카테고리의 다른 글

    enum 활용기  (2) 2024.09.11
    CompletableFuture  (6) 2024.09.05
    mybatis로 jpa 흉내내기  (3) 2024.09.03
    싱글턴 문제점과 해결책  (0) 2024.09.02
    api retry하기  (0) 2024.08.28

    댓글

Designed by Tistory.