티스토리 뷰
프로젝트를 진행하다 겪은 문제다.
람다식을 사용할 때, 특히 stream을 해 map으로 구조 변경 시 자기 자신을 인자로 넘겨주는 경우가 있는데, 이때 i -> i로 나는 그대로 넘겼다.
하지만 리펙토링을 하면서 Function.identity()와 i -> i 를 사용하는것의 차이가 무엇인지 궁금했다.
@Override
public Page<EventPageInfo> findAllEventPages(Long userId, Pageable pageable) {
Page<Event> eventPages = eventUserRepository.findAllByUserId(userId, pageable);
List<Long> eventIds = eventPages.stream()
.map(Event::getId)
.toList();
Map<Long, EventUser> eventUsers = eventUserRepository.findAllByUserIdAndEvent_IdIn(userId, eventIds).stream()
.collect(toMap(EventUser::getEventId, Function.identity()));
List<EventPageInfo> eventPageInfos = eventPages.getContent().stream()
.map(event -> EventPageInfo.from(event, eventUsers.get(event.getId())))
.toList();
return new PageImpl<>(eventPageInfos, eventPages.getPageable(), eventPages.getTotalElements());
}
기존에는 아래와 같이 동일한 값을 넘길때 i → i 같이 그대로 값을 넘겼다.
Map<Long, EventUser> eventUsers = eventUserRepository.findAllByUserIdAndEvent_IdIn(userId, eventIds).stream()
.collect(toMap(EventUser::getEventId, i -> i));
하지만 리팩토링을 하면서 아래와 같이 Function.identity() 로 변경을 했다.
Map<Long, EventUser> eventUsers = eventUserRepository.findAllByUserIdAndEvent_IdIn(userId, eventIds).stream()
.collect(toMap(EventUser::getEventId, Function.identity()));
둘의 차이는 뭘까?
Function 인터페이스는 자바에서 제공하는 input과 output이 있는 함수형 인터페이스다.
그 중 자기 자신을 반환하는 identity() 메서드는 위와 같다.
위 Function.identity()와 identifier -> identifier를 사용하는것은 로직상 똑같다. Function을 거치냐 안거치냐의 차이인 것이다.
하지만 동일하지는 않다.
Function.identity()을 사용하는 것은 항상 같은 instance를 넘기지만 identifier -> identifier 를 사용하는 것은 인스턴스를 새로 생성할 뿐 아니라 별개의 implementation class를 가진다.
따라서 Function.identity()를 사용하는 것은 메모리를 좀 더 아낄 수 있다.
Does a lambda expression create an object on the heap every time it's executed?
위 stackoverflow 질문에서도 Consumer Function을 사용하는 것과 사용하지 않는
것의 차이가 무엇인지 다루고 있다.
위 결과를 보면 차이를 느낄 수 있다.
결론 :
Function.identity()는 항상 같은 인스턴스를 반환하지만 identifier -> identifier 는 인스턴스를 새로 생성할 뿐 아니라 별도의 구현 클래스가 있기 때문에 Function.identity() 를 사용하는것이 메모리 측면에서 더 효율적이다.
'Programming > Java' 카테고리의 다른 글
🔎 Optional 제대로 사용하고 있는걸까? (1) | 2024.01.30 |
---|---|
Scanner와 BufferedReader / BufferedWriter의 차이점과 사용법 (0) | 2023.06.05 |
try-with-resources 적용 후기 (0) | 2023.03.17 |
Java Exception: Checked vs Unchecked, @SneakyThrows (0) | 2023.02.28 |
@SafeVarargs Annotation (추가 학습 필요) (0) | 2022.12.19 |
- Total
- Today
- Yesterday