programing

찾을 수 없는 키에 대한 기본값을 반환하려면 HashMap을 선택하십시오.

goodcopy 2022. 8. 28. 18:54
반응형

찾을 수 없는 키에 대한 기본값을 반환하려면 HashMap을 선택하십시오.

가능한가?HashMap세트에 없는 모든 키에 대해 기본값을 반환하시겠습니까?

Java 8에서는 Map.getOrDefault를 사용합니다.일치하는 키를 찾을 수 없는 경우 키를 사용하고 값을 반환합니다.

[갱신]

다른 답변이나 코멘트에서 알 수 있듯이 Java 8에서는 단순히 에 문의할 수 있습니다.

[오리지널]

정확히 이를 수행하는 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;
  }
}

바퀴를 다시 만들고 싶지 않다면 Commons의 DefaultedMap을 사용하십시오.

Map<String, String> map = new DefaultedMap<>("[NO ENTRY FOUND]");
String surname = map.get("Surname"); 
// surname == "[NO ENTRY FOUND]"

처음부터 지도 작성을 담당하지 않아도 기존 지도를 전달할 수 있습니다.

Java 8은 computeIfAbsent 기본 메서드를 도입하여Maplazy-param 값을 저장하기 때문에 맵 계약을 파기하지 않습니다.

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/

디스클러머:이 답변은 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;
    }
}

구현에서 get(K키) 메서드를 덮어쓰면 안 된다고 생각합니다.이는 Ed Staub가 코멘트한 이유와 Map 인터페이스의 계약을 위반하기 때문입니다(이를 통해 발견하기 어려운 버그가 발생할 수 있습니다).

용도:

myHashMap.getOrDefault(key, defaultValue);

Java 8 이상

Map.getOrDefault(Object key,V defaultValue)

기본적으로는 이렇게 되어 있습니다.다시 돌아오다null.

는 LazyMap이 꽤 도움이 된다는 것을 알았습니다.

get(Object) 메서드가 맵에 존재하지 않는 키로 호출되면 팩토리를 사용하여 오브젝트를 만듭니다.생성된 객체는 요청된 키를 사용하여 맵에 추가됩니다.

이를 통해 다음과 같은 작업을 수행할 수 있습니다.

    Map<String, AtomicInteger> map = LazyMap.lazyMap(new HashMap<>(), ()->new AtomicInteger(0));
    map.get(notExistingKey).incrementAndGet();

문의처get는 지정된 키의 기본값을 만듭니다.기본값을 작성하는 방법은 factory 인수를 사용하여 지정합니다.LazyMap.lazyMap(map, factory) 맵으로 AtomicInteger0으로 하다

직접은 아니지만 클래스를 확장하여 get 메서드를 수정할 수 있습니다.다음은 바로 사용할 수 있는 예입니다.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);
}

사용 예:

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));

필드가 존재한다고 보장할 수 없는 JSON의 서버에서 반환된 결과를 읽어야 했습니다.저는 org.json.simple 클래스를 사용하고 있습니다.HashMap에서 파생된 JSONObject.제가 채용한 도우미 기능은 다음과 같습니다.

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; }
}   
    public final Map<String, List<String>> stringMap = new ConcurrentHashMap<String, List<String>>() {
        @Nullable
        @Override
        public List<String> get(@NonNull Object key) {
            return computeIfAbsent((String) key, s -> new ArrayList<String>());
        }
    };

HashMap은 데드루프를 일으키므로 HashMap 대신 ConcurrentHashMap을 사용합니다.

Java/Kotlin 혼합 프로젝트에서는 Kotlin의 Map.withDefault도 고려합니다.

Java에서 Kotlin 확장 기능 액세스를 참조하십시오.

언급URL : https://stackoverflow.com/questions/7519339/hashmap-to-return-default-value-for-non-found-keys

반응형