Java Map.get 및 Map.containsKey

Java의 Map 구현을 사용할 때 Map의 get (Object) 메소드 를 호출하고 반환 된 값이 null인지 여부에 따라 다르게 반응 하는 것이 일반적 입니다. Map.get (Object)에서 반환 된 null이 맵에 제공된 키가있는 항목이 없음을 나타내는 일반적인 가정을 할 수 있지만 항상 그런 것은 아닙니다. 실제로 Java Map구현이 null 값을 허용하면 Map에서 주어진 키에 대한 값을 반환 할 수 있지만 해당 값은 null 일 수 있습니다. 종종 이것은 중요하지 않지만 만약 그렇다면 Map.containsKey ()를 사용하여 Map항목에 키 항목이 있는지 확인할 수 있습니다 . 그럴 경우 동일한 키에 대한 get 호출 이 Map반환 null되면 키가null값. 즉, " "를 반환하는 동시에 Map"true"를 반환 할 수 있습니다 . 몇 가지가 있습니다 허용하지 않는 구현 값은. 이러한 경우 "get"호출의 호출은 "containsKey"메소드의 "false"반환과 일관되게 일치해야합니다.containsKey(Object)nullget(Object)Mapnullnull

이 블로그 게시물에서는 Map.get(Object)및의 이러한 측면을 보여줍니다  Map.containsKey(Object). 데모를 시작하기 전에 먼저 Map.get (Object)에 대한 Javadoc 문서가 Map.get(Object)와 사이의 미묘한 차이점에 대해 명시 적으로 경고하고 있음을 지적 할 것입니다 Map.containsKey(Object).

이 맵이 null 값을 허용하는 경우 반환 값이  null 반드시 맵에 키에 대한 매핑이 없음을 나타내는 것은 아닙니다. 지도가 명시 적으로 키를에 매핑 할 수도 있습니다  nullcontainsKey 작업은이 두 경우를 구별 할 수 있습니다.

게시물의 예에서는 다음에 정의 된 States 열거 형을 사용합니다.

States.java

package dustin.examples; /** * Enum representing select western states in the United Sates. */ public enum States { ARIZONA("Arizona"), CALIFORNIA("California"), COLORADO("Colorado"), IDAHO("Idaho"), KANSAS("Kansas"), MONTANA("Montana"), NEVADA("Nevada"), NEW_MEXICO("New Mexico"), NORTH_DAKOTA("North Dakota"), OREGON("Oregon"), SOUTH_DAKOTA("South Dakota"), UTAH("Utah"), WASHINGTON("Washington"), WYOMING("Wyoming"); /** State name. */ private String stateName; /** * Parameterized enum constructor accepting a state name. * * @param newStateName Name of the state. */ States(final String newStateName) { this.stateName = newStateName; } /** * Provide the name of the state. * * @return Name of the state */ public String getStateName() { return this.stateName; } } 

다음 코드 목록은 위의 열거 형을 사용하고 주지도를 수도로 채 웁니다. 이 메소드는 생성되고 채워질 Map의 특정 구현이어야하는 클래스를 허용합니다.

generateStatesMap (클래스)

/** * Generate and populate a Map of states to capitals with provided Map type. * This method also logs any Map implementations for which null values are * not allowed. * * @param mapClass Type of Map to be generated. * @return Map of states to capitals. */ private static Map generateStatesMap(Class mapClass) { Map mapToPopulate = null; if (Map.class.isAssignableFrom(mapClass)) { try { mapToPopulate = mapClass != EnumMap.class ? (Map) mapClass.newInstance() : getEnumMap(); mapToPopulate.put(States.ARIZONA, "Phoenix"); mapToPopulate.put(States.CALIFORNIA, "Sacramento"); mapToPopulate.put(States.COLORADO, "Denver"); mapToPopulate.put(States.IDAHO, "Boise"); mapToPopulate.put(States.NEVADA, "Carson City"); mapToPopulate.put(States.NEW_MEXICO, "Sante Fe"); mapToPopulate.put(States.NORTH_DAKOTA, "Bismark"); mapToPopulate.put(States.OREGON, "Salem"); mapToPopulate.put(States.SOUTH_DAKOTA, "Pierre"); mapToPopulate.put(States.UTAH, "Salt Lake City"); mapToPopulate.put(States.WASHINGTON, "Olympia"); mapToPopulate.put(States.WYOMING, "Cheyenne"); try { mapToPopulate.put(States.MONTANA, null); } catch (NullPointerException npe) { LOGGER.severe( mapToPopulate.getClass().getCanonicalName() + " does not allow for null values - " + npe.toString()); } } catch (InstantiationException instantiationException) { LOGGER.log( Level.SEVERE, "Unable to instantiate Map of type " + mapClass.getName() + instantiationException.toString(), instantiationException); } catch (IllegalAccessException illegalAccessException) { LOGGER.log( Level.SEVERE, "Unable to access Map of type " + mapClass.getName() + illegalAccessException.toString(), illegalAccessException); } } else { LOGGER.warning("Provided data type " + mapClass.getName() + " is not a Map."); } return mapToPopulate; } 

위의 방법을 사용하여 다양한 종류의 맵을 생성 할 수 있습니다. 지금은 코드를 표시하지 않지만 예제에서는 HashMap, LinkedHashMap, ConcurrentHashMap 및 EnumMap의 네 가지 특정 구현으로 이러한 맵을 만듭니다. 이러한 네 가지 구현 각각은 다음 demonstrateGetAndContains(Map)에 표시된 메소드를 통해 실행됩니다 .

demoGetAndContains (지도)

/** * Demonstrate Map.get(States) and Map.containsKey(States). * * @param map Map upon which demonstration should be conducted. */ private static void demonstrateGetAndContains(final Map map) { final StringBuilder demoResults = new StringBuilder(); final String mapType = map.getClass().getCanonicalName(); final States montana = States.MONTANA; demoResults.append(NEW_LINE); demoResults.append( "Map of type " + mapType + " returns " + (map.get(montana)) + " for Map.get() using " + montana.getStateName()); demoResults.append(NEW_LINE); demoResults.append( "Map of type " + mapType + " returns " + (map.containsKey(montana)) + " for Map.containsKey() using " + montana.getStateName()); demoResults.append(NEW_LINE); final States kansas = States.KANSAS; demoResults.append( "Map of type " + mapType + " returns " + (map.get(kansas)) + " for Map.get() using " + kansas.getStateName()); demoResults.append(NEW_LINE); demoResults.append( "Map of type " + mapType + " returns " + (map.containsKey(kansas)) + " for Map.containsKey() using " + kansas.getStateName()); demoResults.append(NEW_LINE); LOGGER.info(demoResults.toString()); } 

이 데모에서는 Kansas에 대한 항목이 전혀 없도록 Montana에 대해 null 대문자 값을 갖도록 의도적으로 Maps를 설정했습니다. 이는 Map.get(Object)및 의 차이점을 보여주는 데 도움이됩니다 Map.containsKey(Object). 모든 Map 구현 유형이 null 값을 허용하는 것은 아니기 때문에, 나는 try / catch 블록 안에 대문자없이 Montana를 넣는 부분을 둘러 쌌습니다.

코드를 통해 네 가지 유형의지도를 실행 한 결과가 다음에 나타납니다.

Aug 17, 2010 11:23:26 PM dustin.examples.MapContainsGet logMapInfo INFO: HashMap: {MONTANA=null, WASHINGTON=Olympia, ARIZONA=Phoenix, CALIFORNIA=Sacramento, WYOMING=Cheyenne, SOUTH_DAKOTA=Pierre, COLORADO=Denver, NEW_MEXICO=Sante Fe, NORTH_DAKOTA=Bismark, NEVADA=Carson City, OREGON=Salem, UTAH=Salt Lake City, IDAHO=Boise} Aug 17, 2010 11:23:26 PM dustin.examples.MapContainsGet demonstrateGetAndContains INFO: Map of type java.util.HashMap returns null for Map.get() using Montana Map of type java.util.HashMap returns true for Map.containsKey() using Montana Map of type java.util.HashMap returns null for Map.get() using Kansas Map of type java.util.HashMap returns false for Map.containsKey() using Kansas Aug 17, 2010 11:23:26 PM dustin.examples.MapContainsGet logMapInfo INFO: LinkedHashMap: {ARIZONA=Phoenix, CALIFORNIA=Sacramento, COLORADO=Denver, IDAHO=Boise, NEVADA=Carson City, NEW_MEXICO=Sante Fe, NORTH_DAKOTA=Bismark, OREGON=Salem, SOUTH_DAKOTA=Pierre, UTAH=Salt Lake City, WASHINGTON=Olympia, WYOMING=Cheyenne, MONTANA=null} Aug 17, 2010 11:23:26 PM dustin.examples.MapContainsGet demonstrateGetAndContains INFO: Map of type java.util.LinkedHashMap returns null for Map.get() using Montana Map of type java.util.LinkedHashMap returns true for Map.containsKey() using Montana Map of type java.util.LinkedHashMap returns null for Map.get() using Kansas Map of type java.util.LinkedHashMap returns false for Map.containsKey() using Kansas Aug 17, 2010 11:23:26 PM dustin.examples.MapContainsGet generateStatesMap SEVERE: java.util.concurrent.ConcurrentHashMap does not allow for null values - java.lang.NullPointerException Aug 17, 2010 11:23:26 PM dustin.examples.MapContainsGet logMapInfo INFO: ConcurrentHashMap: {SOUTH_DAKOTA=Pierre, ARIZONA=Phoenix, WYOMING=Cheyenne, UTAH=Salt Lake City, OREGON=Salem, CALIFORNIA=Sacramento, IDAHO=Boise, NEW_MEXICO=Sante Fe, COLORADO=Denver, NORTH_DAKOTA=Bismark, WASHINGTON=Olympia, NEVADA=Carson City} Aug 17, 2010 11:23:26 PM dustin.examples.MapContainsGet demonstrateGetAndContains INFO: Map of type java.util.concurrent.ConcurrentHashMap returns null for Map.get() using Montana Map of type java.util.concurrent.ConcurrentHashMap returns false for Map.containsKey() using Montana Map of type java.util.concurrent.ConcurrentHashMap returns null for Map.get() using Kansas Map of type java.util.concurrent.ConcurrentHashMap returns false for Map.containsKey() using Kansas Aug 17, 2010 11:23:26 PM dustin.examples.MapContainsGet logMapInfo INFO: EnumMap: {ARIZONA=Phoenix, CALIFORNIA=Sacramento, COLORADO=Denver, IDAHO=Boise, MONTANA=null, NEVADA=Carson City, NEW_MEXICO=Sante Fe, NORTH_DAKOTA=Bismark, OREGON=Salem, SOUTH_DAKOTA=Pierre, UTAH=Salt Lake City, WASHINGTON=Olympia, WYOMING=Cheyenne} Aug 17, 2010 11:23:26 PM dustin.examples.MapContainsGet demonstrateGetAndContains INFO: Map of type java.util.EnumMap returns null for Map.get() using Montana Map of type java.util.EnumMap returns true for Map.containsKey() using Montana Map of type java.util.EnumMap returns null for Map.get() using Kansas Map of type java.util.EnumMap returns false for Map.containsKey() using Kansas 

null 값을 입력 할 수 있었던 세 가지 Map 유형의 경우 Map.get (Object) 호출은 몬태나에 대해 containsKey (Object) 메서드가 "true"를 반환하더라도 null을 반환합니다. 값. Kansas의 경우 결과는 일관되게 Map.get ()은 null을 반환하고 Map.containsKey ()는 Maps for Kansas에 항목이 전혀 없기 때문에 "false"를 반환합니다.

위의 출력은 또한 Montana의 자본에 대한 null 값을 ConcurrentHashMap구현에 넣을 수 없음을 보여줍니다 (NullPointerException이 발생했습니다).

2010 년 8 월 17 일 오후 11:23:26 dustin.examples.MapContainsGet generateStatesMapSEVERE : java.util.concurrent.ConcurrentHashMap은 null 값을 허용하지 않습니다.-java.lang.NullPointerException

이것은 유지의 부작용 Map.get(Object)Map.containsKey(Object)더 일관된 각각의 null 및 false 반환 값을 가졌습니다 . 즉, 해당하는 null이 아닌 값이 없으면 맵에 키가있을 수 없습니다.

대부분의 경우, 사용 Map.get(Object)일 손의 특정 요구에 필요한,하지만 차이가 있다는 것을 기억하는 것이 좋습니다로 Map.get(Object)하고 Map.containsKey(Object)있는지 해당 하나가 항상 사용하게 할 수 있습니다. Map이 유사한 containsValue(Object)방법을 제공한다는 점도 흥미 롭습니다 .

완전성을 위해 여기에 MapContainsGet 클래스에 대한 전체 코드 목록을 나열합니다.

MapContainsGet.java