W Pythonie mogę wykonać następujące czynności:

d = { 'a': True, 'b': False }
print d.get('x', True)

To się wydrukuje

True

W Javie metoda HashMap.get nie ma drugiego argumentu za określanie wartości domyślnej. Co to jest poprawny, tchany i czytelny sposób osiągnięcia tego? Poniższy wyrażenie wydaje się dla mnie zbyt zbędny:

map.containsKey("x") ? map.get("x") : true
3
utapyngo 28 listopad 2011, 13:43

7 odpowiedzi

Najlepsza odpowiedź

Oba są złe, ponieważ zrobią 2 wyszukiwanie. Ogólnie chcesz zrobić:

Boolean ret = map.get("x");
if (ret == null) {
    return true
}
return ret;

Możesz to owinąć w funkcji

public static <K,V> V mapGet(Map<K, V> map, K key, V defaultValue) {
    V ret = map.get(key);
    if (ret == null) {
        return defaultValue;
    }
    return ret;
}

Jeśli chcesz, możesz uczynić go niezmiennym statycznym. Jeśli jesteś osobą instancją instancji obiektu mapy (nie rozumiesz go od External Code), możesz podklasy Hashmap. Jeśli API zwraca instancję mapy, nie możesz używać podklasy.

public class MyHashMap<K,V> extends HashMap<K,V> {
    public V get(K key, V default) {
        V ret = get(key);
        if (ret == null) {
            return defaultValue;
        }
        return ret;
    }
}
0
RokL 28 listopad 2012, 14:15

Myślę, że ...

Object o = map.get("x");
if(o == null)
    o = BOOLEAN.TRUE;

... jest prawie najbardziej czytelny i skuteczny sposób na to. Robisz tylko jeden wygląd mapy w ten sposób. Niestety "Java" i "Terse" nie pasują do tego samego zdania, chyba że jest negatywny.

2
G_H 28 listopad 2011, 09:48

Op edytowałem jego pytanie, ale zostawię odpowiedź na wszelki wypadek.

Powinieneś użyć

map.containsKey("x") 

Zamiast

map.get("x") != null

Aby sprawdzić, czy mapa ma mapowanie dla klucza.

Mapy mogą zawierać NULL jako prawidłową wartość w mapowaniu.

To samo dotyczy Pythona. Nie wystarczy przetestować, jeśli naczynia [klawisz] == nie wiedzieć, czy klucz jest mapowany do czegoś.

Szybki test:

d = {'a': None}

# returns True
d['a'] == None

# raises KeyError
d['b'] 

# returns 'Whatever'
d.get('b', 'Whatever')

Więc Java odpowiednik Pythona Dict.get () jest

map.containsKey("x") ? map.get("x") : default_value

Jak powiedział op

6
soulcheck 28 listopad 2011, 11:11

Oba są ważnymi rozwiązaniami (chociaż wprowadzenie zmiennej lokalnej byłoby prawdopodobnie lepsze ... wydajność), ale nie jest to dobry pomysł, aby zrobić to wszędzie w swoim kodzie. Rozważmy napisanie adaptera do HashMap, który zapewnia maksymalną metodę {X1}}, która umożliwia określenie wartości domyślnej. To najlepszy sposób na zwiększenie funkcjonalności klasy.

1
Till Helge 28 listopad 2011, 09:48

map.get("x") == null ? true : map.get("x")

To brzmi dobrze, ale jeśli będziesz potrzebować intensywnie, możesz wdrożyć własne wdrożenie, aby obsłużyć to w get()

0
jmj 28 listopad 2011, 09:48

Rozszerzyłbym mapę, aby odsłonić get(String key, Boolean defaultValue) ... Jeśli nie, że przynajmniej umieściłbym realię w sposób, naciskając wynik get.("x") na stosie, zamiast go zdobyć dwa razy. .. coś takiego jak IfNull(map.get("x"), True)

Jeśli chcesz dostarczyć domyślnie, prawdopodobnie masz "wyspecjalizowane" użytkowanie na mapie, dlatego myślę, że klasa owijki byłaby droga do pójścia, nie tylko dla tego zachowania, ale dla innych (bieżących i przyszłych) zachowań specjalistycznych /obowiązki.

Właśnie w jakiś sposób waliłbym ... Nie jestem jednak projektem orientacyjnym ;-)

Twoje zdrowie. Keith.

0
corlettk 28 listopad 2011, 09:52

W Java 8, jest metoda getOrDefault na mapie, która powinna działać jak Pythona dict S 'get S' get Metoda: https://docs.Oracle.com/javase/8/docs/api /java/util/map.html#getordefault-java.lang.object-v- .

0
Solomon Ucko 9 listopad 2017, 20:09