bir kerede bir HashMap'e birden çok giriş ekleme


138

Sabit bir HashMap başlatmak gerekir ve bunu bir satır ifadesinde yapmak istiyorum. Böyle bir şeyden kaçınmak:

  hashMap.put("One", new Integer(1)); // adding value into HashMap
  hashMap.put("Two", new Integer(2));      
  hashMap.put("Three", new Integer(3));

Hedef C'de buna benzer:

[NSDictionary dictionaryWithObjectsAndKeys:
@"w",[NSNumber numberWithInt:1],
@"K",[NSNumber numberWithInt:2],
@"e",[NSNumber numberWithInt:4],
@"z",[NSNumber numberWithInt:5],
@"l",[NSNumber numberWithInt:6],
nil] 

Ben bu kadar çok baktı bunu nasıl gösteren herhangi bir örnek bulamadık.

Yanıtlar:


259

Bunu yapabilirsiniz:

Map<String, Integer> hashMap = new HashMap<String, Integer>()
{{
     put("One", 1);
     put("Two", 2);
     put("Three", 3);
}};

11
@ user387184 Evet, buna "çift ayraç başlatıcısı" diyorlar. Bu konuya bakın: stackoverflow.com/questions/924285/…
Eng.Fouad

2
Ben sadece benim kod koymak ve bu uyarı / mesaj satırında: "serileştirilebilir sınıf uzun bir statik son serialVersionUID alanı bildirmez". Bunu görmezden gelebilir miyim? Ne anlama geliyor? Teşekkürler
user387184 24:11

31
Bu yöntemi kullanmamalısınız. Her kullandığınızda yeni bir sınıf oluşturur, bu da sadece bir harita oluşturmaktan çok daha kötü performansa sahiptir. Bkz. Stackoverflow.com/questions/924285/…
Timo Türschmann

7
Bunu reddetmemizin nedeni, bunu her kullandığınızda bunun yeni bir sınıf oluşturduğunu açıklamamasıdır. İnsanların bu şekilde yapmanın geleneklerinin farkında olmaları gerektiğini düşünüyorum.
idungotnosn

6
@ TimoTürschmann Böyle bir haritanın statik olarak başlatılmasına ihtiyaç duysaydım, statik olacağını ve performans cezasını her kullandığınızda ortadan kaldıracağını görürsünüz - bu cezayı bir kez alırsınız. Değişken statik olmadan bir başlatma bu tür isteyeceğini başka bir zaman göremiyorum (örneğin, hiç kimse bu bir döngüde kullanmak?). Yine de yanılıyor olabilirim, programcılar yaratıcı.
Chris Cirefice

65

Google Guava'nın ImmutableMap'ini kullanabilirsiniz. Bu, Harita'yı daha sonra değiştirmeyi umursadığınız sürece çalışır (bu yöntemi kullanarak haritayı oluşturduktan sonra .put () yöntemini çağıramazsınız):

import com.google.common.collect.ImmutableMap;

// For up to five entries, use .of()
Map<String, Integer> littleMap = ImmutableMap.of(
    "One", Integer.valueOf(1),
    "Two", Integer.valueOf(2),
    "Three", Integer.valueOf(3)
);

// For more than five entries, use .builder()
Map<String, Integer> bigMap = ImmutableMap.<String, Integer>builder()
    .put("One", Integer.valueOf(1))
    .put("Two", Integer.valueOf(2))
    .put("Three", Integer.valueOf(3))
    .put("Four", Integer.valueOf(4))
    .put("Five", Integer.valueOf(5))
    .put("Six", Integer.valueOf(6))
    .build();

Ayrıca bkz: http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableMap.html

Biraz ilgili bir soru: Haritalar'daki HashMap için ImmutableMap.of () çözümü?


Guava çok büyük, kesinlikle gerekli olmadıkça Android uygulamam için kullanmazdım
ericn

4
Anahtarları veya değerleri ImmutableMapkabul etmediğine dikkat edin null.
Vadzim

@ericn ProGuard , kitaplığın kullanmadığınız bölümlerini hariç tutmanıza olanak tanır.
dimo414

55

Java 9'dan beri, aşağıdakileri kullanmak mümkündür Map.of(...):

Map<String, Integer> immutableMap = Map.of("One", 1, 
                                           "Two", 2, 
                                           "Three", 3);

Bu harita değişmez. Haritanın değiştirilebilir olmasını istiyorsanız, şunu eklemeniz gerekir:

Map<String, Integer> hashMap = new HashMap<>(immutableMap);

Java 9'u kullanamıyorsanız, kendiniz için benzer bir yardımcı yöntem yazmanız veya bu işlevselliği sizin için eklemek için üçüncü taraf bir kitaplık ( Guava gibi ) kullanmanız gerekir.


10 giriş ekledikten sonra garip bir hata atar "yöntemi çözemez", bu yöntemle bu hata mı?
vikramvi

2
@vikramvi evet Belgelere bakarsanız Map.of, oldukça zahmetli olduğundan sadece 10 girişe kadar yapılır
jolivier

8

Java'nın harita hazır bilgisi yoktur, bu yüzden tam olarak sorduğunuz şeyi yapmanın güzel bir yolu yoktur.

Bu tür bir sözdizimine ihtiyacınız varsa, Java uyumlu ve yapmanıza olanak tanıyan bir Groovy düşünün:

def map = [name:"Gromit", likes:"cheese", id:1234]

8

Haritalar'da da Java 9'da fabrika yöntemleri eklenmiştir. 10 girişe kadar Haritalar, anahtar ve değer çiftlerini alan yapıcılara aşırı yük bindirmiştir. Örneğin, çeşitli şehirlerin ve nüfuslarının (Ekim 2016'da Google'a göre) aşağıdaki gibi bir harita oluşturabiliriz:

Map<String, Integer> cities = Map.of("Brussels", 1_139000, "Cardiff", 341_000);

Harita için var-args durumu biraz daha zordur, hem anahtarlara hem de değerlere sahip olmanız gerekir, ancak Java'da yöntemlerin iki var-args parametresi olamaz. Bu nedenle, genel durum, Map.Entry<K, V>nesnelerin var-args yöntemini entry()alıp bunları oluşturan statik bir yöntem ekleyerek ele alınır . Örneğin:

Map<String, Integer> cities = Map.ofEntries(
    entry("Brussels", 1139000), 
    entry("Cardiff", 341000)
);

Java 9'da Toplama Fabrikası Yöntemleri


Java 9+ kullanabiliyorsanız mükemmel. Ayrıca bu fabrika yöntemi değişmez haritayı döndürür.
Sourabh

6

İşte istediğinizi başaracak basit bir sınıf

import java.util.HashMap;

public class QuickHash extends HashMap<String,String> {
    public QuickHash(String...KeyValuePairs) {
        super(KeyValuePairs.length/2);
        for(int i=0;i<KeyValuePairs.length;i+=2)
            put(KeyValuePairs[i], KeyValuePairs[i+1]);
    }
}

Ve sonra kullanmak için

Map<String, String> Foo=QuickHash(
    "a", "1",
    "b", "2"
);

Bu, {a:1, b:2}


4
    boolean x;
    for (x = false, 
        map.put("One", new Integer(1)), 
        map.put("Two", new Integer(2)),      
        map.put("Three", new Integer(3)); x;);

x("Ulaşılamayan bir ifade" tanısından kaçınmak için gerekli) deklarasyonunu göz ardı ederek , teknik olarak sadece bir ifadedir.


14
Bu iğrenç bir hileli.
Micah Merdivenleri

1
@MicahStairs - Ama bu sadece bir açıklama.
Hot Licks

2
Doğru, ama bu üretimde rastlamak hiç ummadığım bir kod.
Micah Merdivenleri

@MicahStairs - Daha kötü gördüm.
Hot Licks

1
Aman tanrım bugün bunu aradım, bu kod nasıl çalışır? Test için koda ekledim ama dahili olarak nasıl çalıştığını
anlayamıyorum

1

Bu yardımcı program işlevini bir yardımcı program sınıfına ekleyebilirsiniz:

public static <K, V> Map<K, V> mapOf(Object... keyValues) {
    Map<K, V> map = new HashMap<>();

    for (int index = 0; index < keyValues.length / 2; index++) {
        map.put((K)keyValues[index * 2], (V)keyValues[index * 2 + 1]);
    }

    return map;
}

Map<Integer, String> map1 = YourClass.mapOf(1, "value1", 2, "value2");
Map<String, String> map2 = YourClass.mapOf("key1", "value1", "key2", "value2");

Not: içinde Map.ofJava 9 kullanabilirsiniz


-1

Başka bir yaklaşım, normal ifadeyle bir dizeden tüm öğe değerlerini ayıklamak için özel işlev yazmak olabilir:

import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Example {
    public static void main (String[] args){
        HashMap<String,Integer> hashMapStringInteger = createHashMapStringIntegerInOneStat("'one' => '1', 'two' => '2' , 'three'=>'3'  ");

        System.out.println(hashMapStringInteger); // {one=1, two=2, three=3}
    }

    private static HashMap<String, Integer> createHashMapStringIntegerInOneStat(String str) {
        HashMap<String, Integer> returnVar = new HashMap<String, Integer>();

        String currentStr = str;
        Pattern pattern1 = Pattern.compile("^\\s*'([^']*)'\\s*=\\s*>\\s*'([^']*)'\\s*,?\\s*(.*)$");

        // Parse all elements in the given string.
        boolean thereIsMore = true;
        while (thereIsMore){
            Matcher matcher = pattern1.matcher(currentStr);
            if (matcher.find()) {
                returnVar.put(matcher.group(1),Integer.valueOf(matcher.group(2)));
                currentStr = matcher.group(3);
            }
            else{
                thereIsMore = false;
            }
        }

        // Validate that all elements in the given string were parsed properly
        if (currentStr.length() > 0){
            System.out.println("WARNING: Problematic string format. given String: " + str);
        }

        return returnVar;
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.