Lists.transform 메서드에서 사용하는 구덩이 - 구덩이 16개 요약(일주일에 한 번 업데이트됨)

계속 만들고 성장을 가속화하십시오! "너겟 데일리 뉴플랜 · 6월 업데이트 챌린지" 참여 6일차입니다. 클릭하시면 이벤트 내용을 보실 수 있습니다.

배경

Google에서 제공하는 Lists.transform 메소드는 특정 로직을 통해 엔터티 클래스의 목록을 다른 엔터티 클래스의 목록으로 변환하는 데 사용할 수 있습니다. 예를 들어 다음 예제에서는 문자열 목록을 정수 목록으로 변환합니다.

예: List<String>A는 List<Integer>B로 변환됩니다. 보여진 바와 같이

public static void main(String[] args) {
    List<String> tests = Stream.of("haha", "hehe").collect(Collectors.toList());
    List<Integer> integers = Lists.transform(tests, t -> {
        return t;
    });
}
复制代码

의문

컬렉션 ID는 Lists.transform 메서드에 값을 추가하지만 결국 추가되지는 않습니다.

public static void main(String[] args) {
    List<Long> ids=new ArrayList<>();
    List<Integer> tests = Stream.of("123", "321").collect(Collectors.toList());
    List<Integer> integers = Lists.transform(tests, t -> {
        ids.add(1L);
        return Integer.parseInt(t);
     });
    System.out.println("结果:"+JSON.toJSON(ids));
}
复制代码

인쇄 결과는 다음과 같습니다.

이미지.png

중단점을 눌러 실행되는지 확인합시다.

첫 번째 중단점이 들어가지 않고 두 번째 중단점이 바로 들어간 것을 볼 수 있습니다.이미지.png

이유

위의 현상으로부터 알 수 있는 것은

  • Lists.transform 메서드는 실제로 즉시 변환을 수행하지 않지만 변환을 지연시킵니다.
  • 소스 코드를 쿼리하면 Lists.transform을 실행한 직후 sourceList에 값이 할당되지 않고 TransformingRandomAccessList 유형으로 변환되어 반복자를 다시 작성하는 것으로 나타났습니다. userFormList를 반복할 때마다 할당을 위해 함수가 호출됩니다.
  • 그리고 foreach에 전달된 함수가 한 번 실행될 때마다 함수의 메서드가 더 효율적이어야 합니다. 따라서 잘못 사용하면 문제가 발생합니다. 원리는 하위 목록과 약간 비슷하며 실제로 내부 클래스를 반환합니다.

이미지.png

이미지.png

해결책

첫 번째 방법: 래퍼 클래스를 사용하여 반환된 내부 개체를 래핑합니다.

  public static void main(String[] args) {
        List<Long> ids = new ArrayList<>();
        List<String> tests = Stream.of("123", "321").collect(Collectors.toList());
//        List<Integer> integers = Lists.transform(tests, t -> {
//            ids.add(1L);
//            return Integer.parseInt(t);
//        });
        List<Integer> integers = new ArrayList<>(Lists.transform(tests, t -> {
            ids.add(1L);
            return Integer.parseInt(t);
        }));

        System.out.println("结果:" + JSON.toJSON(ids));
    }
复制代码

결과:

이미지.png

두 번째 방법: Google에서 제공하는 방법 없이 간단한 변환 구현

public static <F, T> List<T> transformList(List<F> fromList, Function<F, T> fuction) {
    if (fromList == null) {
        return new ArrayList<>();
    }
    List<T> lists = new ArrayList<>();
    for (F from : fromList) {
        lists.add(fuction.apply(from));
    }
    return lists;
}
复制代码

사용법을 테스트하는 메인 메소드를 작성하세요:

  public static void main(String[] args) {
        List<Long> ids = new ArrayList<>();
        List<String> tests = Stream.of("123", "321").collect(Collectors.toList());
//        List<Integer> integers = Lists.transform(tests, t -> {
//            ids.add(1L);
//            return Integer.parseInt(t);
//        });
//        List<Integer> integers = new ArrayList<>(Lists.transform(tests, t -> {
//            ids.add(1L);
//            return Integer.parseInt(t);
//        }));
        List<Tet2> tet2List=new ArrayList<>();
        Tet2 tet2=new Tet2(1L,"haha");
        tet2List.add(tet2);
        List<Tet1> tet1List = transformList(tet2List, m -> {
            Tet1 tet1 = new Tet1();
            tet1.setId(m.getId());
            tet1.setName(m.getName());
            return tet1;
        });
        System.out.println("结果:" + JSON.toJSON(tet1List));
    }
复制代码

인쇄 결과는 다음과 같습니다.

이미지.png

요약하다

타사 오픈 소스 프레임워크를 사용할 때 타사 프레임워크 사용 시 숨겨진 구덩이를 방지하기 위한 원칙을 반드시 이해해야 합니다.

추천

출처juejin.im/post/7105581965503365127