계속 만들고 성장을 가속화하십시오! "너겟 데일리 뉴플랜 · 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));
}
复制代码
인쇄 결과는 다음과 같습니다.
중단점을 눌러 실행되는지 확인합시다.
첫 번째 중단점이 들어가지 않고 두 번째 중단점이 바로 들어간 것을 볼 수 있습니다.
이유
위의 현상으로부터 알 수 있는 것은
- Lists.transform 메서드는 실제로 즉시 변환을 수행하지 않지만 변환을 지연시킵니다.
- 소스 코드를 쿼리하면 Lists.transform을 실행한 직후 sourceList에 값이 할당되지 않고 TransformingRandomAccessList 유형으로 변환되어 반복자를 다시 작성하는 것으로 나타났습니다. userFormList를 반복할 때마다 할당을 위해 함수가 호출됩니다.
- 그리고 foreach에 전달된 함수가 한 번 실행될 때마다 함수의 메서드가 더 효율적이어야 합니다. 따라서 잘못 사용하면 문제가 발생합니다. 원리는 하위 목록과 약간 비슷하며 실제로 내부 클래스를 반환합니다.
해결책
첫 번째 방법: 래퍼 클래스를 사용하여 반환된 내부 개체를 래핑합니다.
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));
}
复制代码
결과:
두 번째 방법: 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));
}
复制代码
인쇄 결과는 다음과 같습니다.
요약하다
타사 오픈 소스 프레임워크를 사용할 때 타사 프레임워크 사용 시 숨겨진 구덩이를 방지하기 위한 원칙을 반드시 이해해야 합니다.