Java: jak przekonwertować HashMap <String, Object> na tablicę

116

Muszę przekonwertować a HashMap<String, Object>na tablicę; czy ktoś mógłby mi pokazać, jak to się robi?

spalony cukier
źródło
4
chcesz klucze, wartości czy jedno i drugie?
harto

Odpowiedzi:

191
hashMap.keySet().toArray(); // returns an array of keys
hashMap.values().toArray(); // returns an array of values

Edytować

Należy zauważyć, że kolejność obu tablic może nie być taka sama. Zobacz odpowiedź oxbow_lakes, aby uzyskać lepsze podejście do iteracji, gdy potrzebna jest para klucz / wartość.

Landon Kuhn
źródło
9
W rzeczywistości ten kod nie gwarantuje, że hashMap.keySet (). ToArray () [0] będzie oryginalnym kluczem dla hashMap.values ​​(). ToArray () [0] z oryginalnej mapy. Jest to więc niezwykle niebezpieczne
CrackerJack9
2
@ CrackerJack9 czy możesz wyjaśnić?
Jake Wilson
12
Klucze nie będą odpowiadać swoim wartościom w dwóch tablicach.
Landon Kuhn
5
@Jakobud landon9720 jest poprawna ... kolejność jest pseudolosowa i nie można zagwarantować, że klucz [0] będzie odpowiadał wartości [0] po przekonwertowaniu kluczy na a, Seta wartości na a Collection. Chociaż są one technicznie konwertowane na tablice (i odpowiadają na twoje pytanie), koncepcja pary klucz-wartość została utracona - dlatego jest to bardzo myląca (i niebezpieczna) odpowiedź ...
CrackerJack9
Mogę zaświadczyć o niebezpieczeństwie tego fragmentu kodu. Kiedy to napisałem, mój terminal wyciągnął rękę i uderzył mnie. Ekstremalnie niebezpieczne! Strzec się!
artburkart
65

Jeśli chcesz klucze i wartości, zawsze możesz to zrobić za pomocą entrySet:

hashMap.entrySet().toArray(); // returns a Map.Entry<K,V>[]

Z każdego wpisu możesz (oczywiście) uzyskać zarówno klucz, jak i wartość za pomocą metod getKeyigetValue

oxbow_lakes
źródło
@ CrackerJack9 Nie, to działa. W przeciwieństwie do przyjętego rozwiązania, to zachowuje pary klucz-wartość. Dostajesz {key, value}[]w przeciwieństwie dokey[], value[]
Tobiq
51

Jeśli masz HashMap<String, SomeObject> hashMapwtedy:

hashMap.values().toArray();

Zwróci plik Object[]. Jeśli zamiast tego chcesz mieć tablicę tego typu SomeObject, możesz użyć:

hashMap.values().toArray(new SomeObject[0]);
kmccoy
źródło
3
Myślę, że masz na myśli values()zamiast keySet()tablicy SomeObject.
Paul Bellora,
4
Możesz również poprawić wydajność, określając rozmiar tablicy z góry zamiast używać 0. Zobacz przykład tutaj: stackoverflow.com/a/5061692/265877
Alex
@Alex "W starszych wersjach Javy zalecane było używanie tablic o wstępnie ustalonym rozmiarze (...) Jednak od późnych aktualizacji OpenJDK 6 wywołanie to było zintensyfikowane, sprawiając, że wydajność pustej wersji tablicy była taka sama, a czasem nawet lepsza, w porównaniu z poprzednią wersją Wersja -sized. Przekazywanie tablicy o wstępnie ustalonym rozmiarze jest również niebezpieczne dla kolekcji współbieżnej lub zsynchronizowanej, ponieważ wyścig danych jest możliwy między rozmiarem a wywołaniem toArray, co może skutkować dodatkowymi wartościami zerowymi na końcu tablicy, jeśli kolekcja została jednocześnie zmniejszona podczas operacja." - intellij
Hamburg jest fajny
30

Aby zagwarantować prawidłową kolejność dla każdej tablicy kluczy i wartości, użyj tego (pozostałe odpowiedzi używają indywidualnych, Setktóre nie dają gwarancji co do zamówienia.

Map<String, Object> map = new HashMap<String, Object>();
String[] keys = new String[map.size()];
Object[] values = new Object[map.size()];
int index = 0;
for (Map.Entry<String, Object> mapEntry : map.entrySet()) {
    keys[index] = mapEntry.getKey();
    values[index] = mapEntry.getValue();
    index++;
}
CrackerJack9
źródło
idealny! otrzymujemy zarówno klucz, jak i wartość, z typami automatycznymi wypełniającymi zaćmienie, długo tego szukałem, thx!
Aquarius Power
12

Alternatywa dla sugestii CrackerJacks, jeśli chcesz, aby HashMap utrzymywała porządek, możesz zamiast tego rozważyć użycie LinkedHashMap. O ile wiem, jego funkcjonalność jest identyczna z HashMap, ale jest to FIFO, więc zachowuje kolejność, w jakiej zostały dodane elementy.

Dean Wild
źródło
7

Użyłem prawie tego samego co @kmccoy, ale zamiast tego keySet()zrobiłem to

hashMap.values().toArray(new MyObject[0]);
Hugo Tavares
źródło
6
Map<String, String> map = new HashMap<String, String>();
map.put("key1", "value1");
map.put("key2", "value2");

Object[][] twoDarray = new Object[map.size()][2];

Object[] keys = map.keySet().toArray();
Object[] values = map.values().toArray();

for (int row = 0; row < twoDarray.length; row++) {
    twoDarray[row][0] = keys[row];
    twoDarray[row][1] = values[row];
}

// Print out the new 2D array
for (int i = 0; i < twoDarray.length; i++) {
    for (int j = 0; j < twoDarray[i].length; j++) {
        System.out.println(twoDarray[i][j]);
    }
}
waleriana
źródło
3

Aby uzyskać dostęp do jednej tablicy wymiarów.

    String[] arr1 = new String[hashmap.size()];
    String[] arr2 = new String[hashmap.size()];
    Set entries = hashmap.entrySet();
    Iterator entriesIterator = entries.iterator();

    int i = 0;
    while(entriesIterator.hasNext()){

        Map.Entry mapping = (Map.Entry) entriesIterator.next();

        arr1[i] = mapping.getKey().toString();
        arr2[i] = mapping.getValue().toString();

        i++;
    }


Aby dostać się do tablicy dwuwymiarowej.

   String[][] arr = new String[hashmap.size()][2];
   Set entries = hashmap.entrySet();
   Iterator entriesIterator = entries.iterator();

   int i = 0;
   while(entriesIterator.hasNext()){

    Map.Entry mapping = (Map.Entry) entriesIterator.next();

    arr[i][0] = mapping.getKey().toString();
    arr[i][1] = mapping.getValue().toString();

    i++;
}
Mitul Maheshwari
źródło
2

Jeśli używasz Java 8+ i potrzebujesz dwuwymiarowego Array, być może dla dostawców danych TestNG, możesz spróbować:

map.entrySet()
    .stream()
    .map(e -> new Object[]{e.getKey(), e.getValue()})
    .toArray(Object[][]::new);

Jeśli twoje ObjectStringsi i potrzebujesz String[][], spróbuj:

map.entrySet()
    .stream()
    .map(e -> new String[]{e.getKey(), e.getValue().toString()})
    .toArray(String[][]::new);
Graham Russell
źródło
0

Ty też możesz spróbować.

public static String[][] getArrayFromHash(Hashtable<String,String> data){
        String[][] str = null;
        {
            Object[] keys = data.keySet().toArray();
            Object[] values = data.values().toArray();
            str = new String[keys.length][values.length];
            for(int i=0;i<keys.length;i++) {
                str[0][i] = (String)keys[i];
                str[1][i] = (String)values[i];
            }
        }
        return str;
    }

Tutaj używam String jako typu zwracanego. Możesz zmienić go na wymagany przez siebie typ zwrotu.

Mayur
źródło
1
pytanie dotyczy, HashMap()ale twoje rozwiązanie dotyczy Hashtable()... Są między nimi pewne różnice
Choletski
0
@SuppressWarnings("unchecked")
    public static <E,T> E[] hashMapKeysToArray(HashMap<E,T> map)
    {
        int s;
        if(map == null || (s = map.size())<1)
            return null;

        E[] temp;
        E typeHelper;
        try
        {
            Iterator<Entry<E, T>> iterator = map.entrySet().iterator();
            Entry<E, T> iK = iterator.next();
            typeHelper = iK.getKey();

            Object o = Array.newInstance(typeHelper.getClass(), s);
            temp = (E[]) o;

            int index = 0;
            for (Map.Entry<E,T> mapEntry : map.entrySet())
            {
                temp[index++] = mapEntry.getKey();
            }
        }
        catch (Exception e)
        {
            return null;
        }
        return temp;
    }
//--------------------------------------------------------
    @SuppressWarnings("unchecked")
    public static <E,T> T[] hashMapValuesToArray(HashMap<E,T> map)
    {
        int s;
        if(map == null || (s = map.size())<1)
            return null;

        T[] temp;
        T typeHelper;
        try
        {
            Iterator<Entry<E, T>> iterator = map.entrySet().iterator();
            Entry<E, T> iK = iterator.next();
            typeHelper = iK.getValue();

            Object o = Array.newInstance(typeHelper.getClass(), s);
            temp = (T[]) o;

            int index = 0;
            for (Map.Entry<E,T> mapEntry : map.entrySet())
            {
                temp[index++] = mapEntry.getValue();
            }
        }
        catch (Exception e)
        {return null;}

        return temp;
    }
Ali Bagheri
źródło
0
HashMap<String, String> hashMap = new HashMap<>();
String[] stringValues= new String[hashMap.values().size()];
hashMap.values().toArray(stringValues);
Рома Иртов
źródło