Jak bezpośrednio zainicjować Hashmapę (w dosłowny sposób)? [duplikat]

To pytanie ma już odpowiedź tutaj:

Czy Jest jakiś sposób na zainicjowanie takiej Hashmapy w Javie?:

Map<String,String> test = 
    new HashMap<String, String>{"test":"test","test":"test"};

Jaka byłaby prawidłowa składnia? Nie znalazłem nic na ten temat. Czy to możliwe? Szukam najkrótszego / najszybszego sposobu, aby umieścić jakieś "końcowe / statyczne" wartości na mapie, które nigdy się nie zmieniają i są znane z góry podczas tworzenia mapy.

Author: Freedom_Ben, 2011-07-23

6 answers

Nie, musisz dodać wszystkie elementy ręcznie. Można jednak użyć statycznego inicjalizatora:

public class Demo
{
    private static final Map<String, String> myMap;
    static
    {
        myMap = new HashMap<String, String>();
        myMap.put("a", "b");
        myMap.put("c", "d");
    }
}

Zauważ, że użycie funkcji do inicjalizacji zrobi to samo, ale może poprawić czytelność kodu:

public class Demo
{
    private static final Map<String, String> myMap = createMap();
    private static Map<String, String> createMap()
    {
        Map<String,String> myMap = new HashMap<String,String>();
        myMap.put("a", "b");
        myMap.put("c", "d");
        return myMap;
    }
}

Java 9

W Javie 9 dodano kilka fabrycznych metod, które można również wykorzystać do uproszczenia tworzenia map:

public class Demo {
    private static final Map<String, String> test = Map.of("a", "b", "c", "d");
    private static final Map<String, String> test2 = Map.ofEntries(
        entry("a", "b"),
        entry("c", "d")
    );
}

W powyższym przykładzie zarówno test jak i test2 będą takie same, tylko z różnymi sposobami wyrażania Mapy. Na Metoda Map.of jest zdefiniowana dla maksymalnie dziesięciu elementów na mapie, podczas gdy metoda Map.ofEntries nie będzie miała takiego limitu.

Zauważ, że w tym przypadku Mapa wynikowa będzie niezmienna. Jeśli chcesz, aby mapa była zmienna, możesz ją skopiować ponownie, np. używając mutableMap = new HashMap<>(Map.of("a", "b"));

(Zobacz także JEP 269 i Javadoc)

 909
Author: yankee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-14 19:37:43

To jest jeden sposób.

HashMap<String, String> h = new HashMap<String, String>() {{
    put("a","b");
}};

Jednak powinieneś być ostrożny i upewnić się, że rozumiesz powyższy kod(tworzy on nową klasę, która dziedziczy z HashMap). Dlatego warto przeczytać więcej tutaj: http://www.c2.com/cgi/wiki?DoubleBraceInitialization , lub po prostu użyć guawa:

Map<String, Integer> left = ImmutableMap.of("a", 1, "b", 2, "c", 3);
 919
Author: gregory561,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-23 13:51:38

Jeśli zezwalasz na Biblioteki stron trzecich, możesz użyć Guava 'S ImmutableMap aby osiągnąć zwięzłość dosłowną:

Map<String, String> test = ImmutableMap.of("k1", "v1", "k2", "v2");

To działa dla maksymalnie 5 par klucz/wartość , w przeciwnym razie możesz użyć jego builder :

Map<String, String> test = ImmutableMap.<String, String>builder()
    .put("k1", "v1")
    .put("k2", "v2")
    ...
    .build();


    W przeciwieństwie do Javy, Java nie może być używana do tworzenia kopii zapasowych (np. kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych, kopii zapasowych itp.)]}
  • aby uzyskać więcej informacji, zobacz Guava ' s user guide article on its immutable collection types
 284
Author: Jens Hoffmann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-25 06:43:35

Nie ma na to bezpośredniego sposobu-Java nie ma literałów Map (jeszcze-myślę, że zostały zaproponowane dla Javy 8).

Niektórzy ludzie lubią to:

Map<String,String> test = new HashMap<String, String>(){{
       put("test","test"); put("test","test");}};

Tworzy to anonimową podklasę HashMap, której inicjalizator instancji umieszcza te wartości. (Nawiasem mówiąc, mapa nie może zawierać dwukrotnie tej samej wartości, twoje drugie put nadpisze pierwszą. W następnych przykładach użyję różnych wartości.)

Normalnym sposobem byłoby to (dla lokalnego zmienna):

Map<String,String> test = new HashMap<String, String>();
test.put("test","test");
test.put("test1","test2");

Jeśli Twoja mapa test jest zmienną instancji, umieść inicjalizację w konstruktorze lub inicjalizatorze instancji:

Map<String,String> test = new HashMap<String, String>();
{
    test.put("test","test");
    test.put("test1","test2");
}

Jeśli Twoja mapa test jest zmienną klasy, umieść inicjalizację w statycznym inicjalizatorze:

static Map<String,String> test = new HashMap<String, String>();
static {
    test.put("test","test");
    test.put("test1","test2");
}

Jeśli chcesz, aby Mapa nigdy się nie zmieniała, powinieneś po inicjalizacji zawinąć Mapę przez Collections.unmodifiableMap(...). Możesz to zrobić również w statycznym inicjalizatorze:

static Map<String,String> test;
{
    Map<String,String> temp = new HashMap<String, String>();
    temp.put("test","test");
    temp.put("test1","test2");
    test = Collections.unmodifiableMap(temp);
}

(nie jestem pewien, czy możesz teraz zrobić test finał ... wypróbuj i zgłoś proszę.)

 88
Author: Paŭlo Ebermann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-28 21:21:27
Map<String,String> test = new HashMap<String, String>()
{
    {
        put(key1, value1);
        put(key2, value2);
    }
};
 56
Author: Shaggy Frog,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-23 18:47:06

Alternatywa, używając zwykłych klas Java 7 i varargs: Utwórz klasę HashMapBuilder za pomocą tej metody:

public static HashMap<String, String> build(String... data){
    HashMap<String, String> result = new HashMap<String, String>();

    if(data.length % 2 != 0) 
        throw new IllegalArgumentException("Odd number of arguments");      

    String key = null;
    Integer step = -1;

    for(String value : data){
        step++;
        switch(step % 2){
        case 0: 
            if(value == null)
                throw new IllegalArgumentException("Null key value"); 
            key = value;
            continue;
        case 1:             
            result.put(key, value);
            break;
        }
    }

    return result;
}

Użyj metody w ten sposób:

HashMap<String,String> data = HashMapBuilder.build("key1","value1","key2","value2");
 40
Author: Aerthel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-04 16:10:23