본문 바로가기

프로그래밍 언어(must-have skills)/JAVA

[자바]Collections.emptyMap() vs new HashMap()

배경

클래스로딩에 대해서 간단한 게시글을 읽던 도중

https://engkimbs.tistory.com/606

저 ext 경로에 있는 소스들이 뭐가있는지 궁금해졌다. 

다 낯설다. 

이 중에 zlpfs.jar를 역컴파일해서 소스를 보았다. 

(그 중에서도 ZipInfo)

 public class ZipInfo {
   public static void main(String[] paramArrayOfString) throws Throwable {
     if (paramArrayOfString.length < 1) {
       print("Usage: java ZipInfo zfname", new Object[0]);
     } else {
       Map<?, ?> map = Collections.emptyMap();
       ZipFileSystem zipFileSystem = (ZipFileSystem)(new ZipFileSystemProvider()).newFileSystem(Paths.get(paramArrayOfString[0], new String[0]), (Map)map);
       byte[] arrayOfByte1 = zipFileSystem.cen;
       if (arrayOfByte1 == null) {
         print("zip file is empty%n", new Object[0]);
         return;
       } 
       int i = 0;
       byte[] arrayOfByte2 = new byte[1024];
       byte b = 1;
       while (i + 46 < arrayOfByte1.length) {
         print("----------------#%d--------------------%n", new Object[] { Integer.valueOf(b++) });
         printCEN(arrayOfByte1, i);
         long l = (30 + ZipConstants.CENNAM(arrayOfByte1, i) + ZipConstants.CENEXT(arrayOfByte1, i) + 46);
         if (zipFileSystem.readFullyAt(arrayOfByte2, 0, l, locoff(arrayOfByte1, i)) != l)
           ZipFileSystem.zerror("read loc header failed"); 
         if (ZipConstants.LOCEXT(arrayOfByte2) > ZipConstants.CENEXT(arrayOfByte1, i) + 46) {
           l = (30 + ZipConstants.LOCNAM(arrayOfByte2) + ZipConstants.LOCEXT(arrayOfByte2));
           if (zipFileSystem.readFullyAt(arrayOfByte2, 0, l, locoff(arrayOfByte1, i)) != l)
             ZipFileSystem.zerror("read loc header failed"); 
         } 
         printLOC(arrayOfByte2);
         i += 46 + ZipConstants.CENNAM(arrayOfByte1, i) + ZipConstants.CENEXT(arrayOfByte1, i) + ZipConstants.CENCOM(arrayOfByte1, i);
       } 
       zipFileSystem.close();
     }
     //java version "1.8.0_74"

?? 제네릭에 물음표를 집어넣는 방식도 처음이고, 해쉬맵을 만들때 Collection.emptyMap()을 보는 것도 처음이다. 

Collections.emptyMap()이 권장되는 이유

빨간 네모가 차이를 가리키는 단서가 될 것 같다. 

스택오버플로에 자바 개발자들이 알아야할 관습들에 대해서 설명해놓은 저서 [이펙티브 자바 15장과 54장]을 인용한 답변이 있다. 

https://stackoverflow.com/questions/14846920/collections-emptymap-vs-new-hashmap

 

"변경 가능성을 최소화하라","null이 아닌, 빈 컬렉션이나 배열을 반환하라"

private final List<Cheese> cheesesInStock = ...;
/** * @return 매장 안의 모든 치즈 목록을 반환한다. 
* 단, 재고가 하나도 없다면 null을 반환한다.
*/ 
public List<Cheese> getCheese(){ return cheesesInStock.isEmpty() ? null : new ArrayList<>(cheesesInStock); }

getCheese()메서드를 사용할 경우 null처리를 따로 해줘야 하는 경우가 생긴다. 

 

빈 컨테이너를 할당하는 비용이 있어 안좋은 것 아니냐는 주장은 2가지 이유에서 틀린 주장이다. 
    1. 이 할당이 성능 저하의 주범이라고 확인되지 않는 한, 이 정도의 성능 차이는 신경 쓸 수준이 못 된다.

    2. 빈 컬렉션과 배열은 굳이 새로 할당하지 않고도 반환할 수 있다.

보완요소

불변객체를 선호해야 하는 이유와 빈컬렉션을 반환하는 게 null값을 반환하는 문제를 각각 차분하게 생각해보자.  

                                                                참고

https://madplay.github.io/post/effectivejava-chapter8-methods#%EC%95%84%EC%9D%B4%ED%85%9C-54-null%EC%9D%B4-%EC%95%84%EB%8B%8C-%EB%B9%88-%EC%BB%AC%EB%A0%89%EC%85%98%EC%9D%B4%EB%82%98-%EB%B0%B0%EC%97%B4%EC%9D%84-%EB%B0%98%ED%99%98%ED%95%98%EB%9D%BC

https://cornswrold.tistory.com/386

https://stackoverflow.com/questions/1969993/is-it-better-to-return-null-or-empty-collection/1970001#1970001

 

'프로그래밍 언어(must-have skills) > JAVA' 카테고리의 다른 글

정규표현식 -java.util.regex.Pattern  (0) 2023.01.07
@vaild에 관하여  (0) 2022.12.28
if/else문과 swich문의 성능 비교 .  (0) 2022.05.31
log4j취약점 패치  (0) 2021.12.13
Garbage Collection  (0) 2021.09.08