발견되지 않은 키의 기본값을 반환하는 HashMap?
HashMap
세트에서 찾을 수없는 모든 키에 대해 기본값을 반환 할 수 있습니까?
[최신 정보]
다른 답변과 의견 작성자가 언급했듯이 Java 8부터 간단히 전화 할 수 있습니다 Map#getOrDefault(...)
.
[실물]
이 작업을 정확히 수행하는 Map 구현은 없지만 HashMap을 확장하여 직접 구현하는 것은 쉽지 않습니다.
public class DefaultHashMap<K,V> extends HashMap<K,V> {
protected V defaultValue;
public DefaultHashMap(V defaultValue) {
this.defaultValue = defaultValue;
}
@Override
public V get(Object k) {
return containsKey(k) ? super.get(k) : defaultValue;
}
}
Java 8에서는 Map.getOrDefault를 사용 하십시오 . 일치하는 키가 없으면 키를 반환하고 값을 반환합니다.
바퀴를 재발견하고 싶지 않다면 Commons의 DefaultedMap을 사용하십시오 .
Map<String, String> map = new DefaultedMap<>("[NO ENTRY FOUND]");
String surname = map.get("Surname");
// surname == "[NO ENTRY FOUND]"
처음에지도 작성을 담당하지 않는 경우 기존지도를 전달할 수도 있습니다.
Java 8 은 게으른 계산 값을 저장하고 맵 계약을 위반하지 않는 인터페이스에 멋진 computeIfAbsent 기본 메소드를 도입했습니다 Map
.
Map<Key, Graph> map = new HashMap<>();
map.computeIfAbsent(aKey, key -> createExpensiveGraph(key));
출처 : http://blog.javabien.net/2014/02/20/loadingcache-in-java-8-without-guava/
Disclamer : 이 답변은 OP가 요청한 것과 정확히 일치하지 않지만 키 번호가 제한되어 있고 다른 값의 캐싱이 수익성이있는 경우 질문 제목과 일치하는 경우에 유용 할 수 있습니다. 메모리가 불필요하게 낭비되는 것과 같이 많은 키와 동일한 기본값으로 반대의 경우에는 사용해서는 안됩니다.
정확히 이것을 수행하는 정적 메소드를 작성할 수 없습니까?
private static <K, V> V getOrDefault(Map<K,V> map, K key, V defaultValue) {
return map.containsKey(key) ? map.get(key) : defaultValue;
}
HashMap을 상속하는 새 클래스를 작성하고 getDefault 메소드를 추가하면됩니다. 다음은 샘플 코드입니다.
public class DefaultHashMap<K,V> extends HashMap<K,V> {
public V getDefault(K key, V defaultValue) {
if (containsKey(key)) {
return get(key);
}
return defaultValue;
}
}
Ed Staub가 언급 한 이유와 Map 인터페이스 계약 을 위반하기 때문에 구현에서 get (K key) 메소드를 재정의해서는 안된다고 생각합니다 (이는 잠재적으로 찾기 어려운 결과를 초래할 수 있습니다) 버그).
사용하다:
myHashMap.getOrDefault(key, defaultValue);
기본적으로이 작업을 수행합니다. 를 반환합니다 null
.
맵에 존재하지 않는 키로 get (Object) 메소드를 호출하면 팩토리가 오브젝트를 작성하는 데 사용됩니다. 생성 된 객체는 요청 된 키를 사용하여 맵에 추가됩니다.
이를 통해 다음과 같은 작업을 수행 할 수 있습니다.
Map<String, AtomicInteger> map = LazyMap.lazyMap(new HashMap<>(), ()->new AtomicInteger(0));
map.get(notExistingKey).incrementAndGet();
The call to get
creates a default value for the given key. You specify how to create the default value with the factory argument to LazyMap.lazyMap(map, factory)
. In the example above, the map is initialized to a new AtomicInteger
with value 0.
On java 8+
Map.getOrDefault(Object key,V defaultValue)
Not directly, but you can extend the class to modify its get method. Here is a ready to use example: http://www.java2s.com/Code/Java/Collections-Data-Structure/ExtendedVersionofjavautilHashMapthatprovidesanextendedgetmethodaccpetingadefaultvalue.htm
/**
* Extension of TreeMap to provide default value getter/creator.
*
* NOTE: This class performs no null key or value checking.
*
* @author N David Brown
*
* @param <K> Key type
* @param <V> Value type
*/
public abstract class Hash<K, V> extends TreeMap<K, V> {
private static final long serialVersionUID = 1905150272531272505L;
/**
* Same as {@link #get(Object)} but first stores result of
* {@link #create(Object)} under given key if key doesn't exist.
*
* @param k
* @return
*/
public V getOrCreate(final K k) {
V v = get(k);
if (v == null) {
v = create(k);
put(k, v);
}
return v;
}
/**
* Same as {@link #get(Object)} but returns specified default value
* if key doesn't exist. Note that default value isn't automatically
* stored under the given key.
*
* @param k
* @param _default
* @return
*/
public V getDefault(final K k, final V _default) {
V v = get(k);
return v == null ? _default : v;
}
/**
* Creates a default value for the specified key.
*
* @param k
* @return
*/
abstract protected V create(final K k);
}
Example Usage:
protected class HashList extends Hash<String, ArrayList<String>> {
private static final long serialVersionUID = 6658900478219817746L;
@Override
public ArrayList<Short> create(Short key) {
return new ArrayList<Short>();
}
}
final HashList haystack = new HashList();
final String needle = "hide and";
haystack.getOrCreate(needle).add("seek")
System.out.println(haystack.get(needle).get(0));
I needed to read the results returned from a server in JSON where I couldn't guarantee the fields would be present. I'm using class org.json.simple.JSONObject which is derived from HashMap. Here are some helper functions I employed:
public static String getString( final JSONObject response,
final String key )
{ return getString( response, key, "" ); }
public static String getString( final JSONObject response,
final String key, final String defVal )
{ return response.containsKey( key ) ? (String)response.get( key ) : defVal; }
public static long getLong( final JSONObject response,
final String key )
{ return getLong( response, key, 0 ); }
public static long getLong( final JSONObject response,
final String key, final long defVal )
{ return response.containsKey( key ) ? (long)response.get( key ) : defVal; }
public static float getFloat( final JSONObject response,
final String key )
{ return getFloat( response, key, 0.0f ); }
public static float getFloat( final JSONObject response,
final String key, final float defVal )
{ return response.containsKey( key ) ? (float)response.get( key ) : defVal; }
public static List<JSONObject> getList( final JSONObject response,
final String key )
{ return getList( response, key, new ArrayList<JSONObject>() ); }
public static List<JSONObject> getList( final JSONObject response,
final String key, final List<JSONObject> defVal ) {
try { return response.containsKey( key ) ? (List<JSONObject>) response.get( key ) : defVal; }
catch( ClassCastException e ) { return defVal; }
}
In mixed Java/Kotlin projects also consider Kotlin's Map.withDefault.
참고URL : https://stackoverflow.com/questions/7519339/hashmap-to-return-default-value-for-non-found-keys
'development' 카테고리의 다른 글
zlib에서 우분투 레일 설치 실패 (0) | 2020.07.02 |
---|---|
Rails에서 Active Record의 기본 시간대를 변경하는 방법은 무엇입니까? (0) | 2020.07.02 |
설치된 보석 목록? (0) | 2020.07.02 |
파이썬에서 반복 건너 뛰기 (0) | 2020.07.02 |
힘내 로그 날짜 형식을 변경하는 방법 (0) | 2020.07.02 |