Jak przekonwertować mapę na listę w Javie?

674

Jaki jest najlepszy sposób na konwersję Map<key,value>na a List<value>? Wystarczy powtórzyć wszystkie wartości i wstawić je do listy, czy coś przeoczyłem?

Javaa
źródło
1
Myślę, że nie jest to dobry model, jeśli trzeba przekonwertować mapę na listę. Należy napisać kod w taki sposób, aby taka sytuacja się nie pojawiła.
Błędy występowały

Odpowiedzi:

1299
List<Value> list = new ArrayList<Value>(map.values());

zarozumiały:

Map<Key,Value> map;
Cletus
źródło
7
Dzięki! Zakładałem, że obsada od Collectiondo Listzadziała.
asgs
1
Podejrzewam, że przyczyną tego nie jest to, że kolekcja zwrócona przez wartości () jest zależna od podstawowej mapy; wykonując zamiast tego wywołanie konstruktora kopiowania, alokujesz pamięć i kopiujesz wartości do tej pamięci, tym samym przerywając połączenie ...
Sheldon R.,
4
Jeśli mamy LinkedHashMap - czy zamówienie pozostawi to samo?
1
@ user2022068 tak, kolejność powinna być zachowana dzięki LinkedHashMap.
SusanW,
1
@SheldonR. tak - kolekcje zwrócone przez keySet()i values()są ogólnie shim obiektami, które dają widok zestawu lub kolekcji podstawowej struktury ( keySet()zwraca zestaw, aby podkreślić brak duplikatów). Bo values()zwrócony obiekt może być List, ale często nie będzie. Tworzenie prawdziwej listy, jak mówisz, przerywa link, co oznacza, że ​​nie jesteś już zależny od oryginalnej mapy. Czasami jednak potrzebujesz tylko Listy, ponieważ niektóre API jej wymagają - wzmacniając zasadę, że dobry API powinien wymagać tylko najbardziej abstrakcyjnych interfejsów, z
którymi
137

Problem polega na tym, że Mapma dwie wartości (klucz i wartość), podczas gdy Listtylko jedna ma wartość (element).

Dlatego najlepsze, co można zrobić, to uzyskać jeden Listz kluczy lub wartości. (Chyba że stworzymy opakowanie, aby utrzymać parę klucz / wartość).

Powiedzmy, że mamy Map:

Map<String, String> m = new HashMap<String, String>();
m.put("Hello", "World");
m.put("Apple", "3.14");
m.put("Another", "Element");

Klucze jako Listmożna uzyskać, tworząc nowy ArrayListze Setzwracanego przez Map.keySetmetodę:

List<String> list = new ArrayList<String>(m.keySet());

Podczas gdy wartości jako Listmożna uzyskać, tworząc nowy ArrayListze Collectionzwracanego przez Map.valuesmetodę:

List<String> list = new ArrayList<String>(m.values());

Wynik uzyskania Listkluczy:

jabłko
Inne
Witaj

Wynik uzyskania Listwartości:

3.14
Element
Świat
coobird
źródło
3
Należy zauważyć, że kolejność wartości zwracanych tymi metodami nie jest zdefiniowana, a dla HashMappodobnych nieposortowanych Mapimplementacji będzie ona skutecznie losowa.
Joachim Sauer
1
Tak, musisz wiedzieć, że jest to LinkedHashMap lub coś w tym rodzaju. Problem z pierwotnym pytaniem polega na tym, że pytanie jest zniekształcone, tzn. Wymaga edycji. Pytanie nie polega na konwertowaniu mapy na listę, ale raczej na tym, jak uzyskać wartości mapy jako listę. Wartości metod dają kolekcję, ale nie listę, a zatem potrzebę zgrabnej małej sztuczki.
demongolem
Myślę, że możesz dodać do swojej odpowiedzi to, co mówi @ M0les: Że musisz jakoś „przejść przez” SortedMap. Albo zacznij od konkretnej implementacji SortedMap (takiej jak TreeMap), albo wstaw mapę wejściową do SortedMap przed przekształceniem jej w Listę
Ignacio Rubio,
41

Korzystanie z interfejsu API strumieni Java 8.

List<Value> values = map.values().stream().collect(Collectors.toList());
Matej Kormuth
źródło
8
Wolę przyjętą odpowiedź opartą na konstruktorze. Strumienie powinny służyć do uproszczenia kodu.
Aaron
1
@Aaron Tak, dla zadania uzyskania listy wartości z mapy konstruktor wydaje się prostszy. Jednak jeśli używasz Streams intensywnie w bazie kodu, lepiej zachować spójność.
Matej Kormuth
1
kiedy korzystam z tego, pojawia się błąd, jeśli pobieram ogromną ilość danych .. wątek zapętla się na java.util.stream.ReduceOps $ 3.makeSink (nieznane źródło). Jeśli wątki zapętlają się nieskończenie, zużycie procesora zacznie gwałtownie rosnąć. Ślad zapętlenia wątków podano poniżej, zbadaj go
Ganesh Giri
24

map.entrySet()daje kolekcję Map.Entryobiektów zawierających zarówno klucz, jak i wartość. możesz następnie przekształcić to w dowolny obiekt kolekcji, taki jak new ArrayList(map.entrySet());

java koleś
źródło
23

lista czego?

Zakładając, że mapmasz instancjęMap

  • map.values()zwróci wartość Collectionzawierającą wszystkie wartości mapy.
  • map.keySet()zwróci Setzawierające wszystkie klucze mapy.
Diego Amicabile
źródło
14

Chyba chcesz przekonwertować wartości zawartych w MapDo list? Najłatwiej jest wywołać values()metodę Mapinterfejsu. Zwróci to Collectionwartości obiektów zawartych w Map.

Zauważ, że Collectionjest to wspierane przez Mapobiekt, a wszelkie zmiany w Mapobiekcie odzwierciedlą się tutaj. Jeśli więc chcesz, aby oddzielna kopia nie była związana z Twoim Mapobiektem, po prostu utwórz nowy Listobiekt, na przykład ArrayListprzekazując wartość, Collectionjak poniżej.

ArrayList<String> list = new ArrayList<String>(map.values());
maneesh
źródło
6

Możesz to zrobić w ten sposób

List<Value> list = new ArrayList<Value>(map.values());
użytkownik3752441
źródło
1
OP zapytaj, jak przekonwertować na Listę <wartość>. Po udzieleniu odpowiedzi lepiej dołączyć Dobry opis z proponowanym rozwiązaniem. Odpowiedź na to pytanie została już zaakceptowana.
HaveNoDisplayName,
5

Jeśli chcesz się upewnić, że wartości w wynikowym List<Value>są w kolejności wprowadzania danych wejściowych Map<Key, Value>, musisz SortedMapjakoś „przejść przez” .

Albo zacząć z konkretną SortedMaprealizację (np TreeMap) lub włóż wkład Mapdo SortedMapprzed konwersją, że do List. na przykład:

Map<Key,Value> map;
List<Value> list = new ArrayList<Value>( new TreeMap<Key Value>( map ));

W przeciwnym razie otrzymasz dowolną natywną kolejność, jaką Mapzapewnia implementacja, która często może być czymś innym niż naturalna kolejność kluczy (spróbuj Hashtablelub ConcurrentHashMap, dla odmiany).

M0les
źródło
5
    Map<String, Integer> map = new HashMap<String, Integer>();
    map.put("java", 20);
    map.put("C++", 45);

    Set <Entry<String, Integer>> set = map.entrySet();

    List<Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(set);

możemy mieć parę kluczy i wartości na liście. Możemy również uzyskać klucz i wartość za pomocą Map.Entry poprzez iterację po liście.

użytkownik 11
źródło
4
// you can use this
List<Value> list = new ArrayList<Value>(map.values());

// or you may use 
List<Value> list = new ArrayList<Value>();
for (Map.Entry<String, String> entry : map.entrySet())
{
list.add(entry.getValue());    
}
saurabhgoyal795
źródło
1
"Map<String , String > map = new HapshMap<String , String>;
 map.add("one","java");
 map.add("two" ,"spring");
 Set<Entry<String,String>> set =  map.entrySet();
 List<Entry<String , String>> list = new ArrayList<Entry<String , String>>    (set);
 for(Entry<String , String> entry : list ) {
   System.out.println(entry.getKey());
   System.out.println(entry.getValue());
 } "
siva prasad
źródło
1

Oto ogólna metoda uzyskiwania wartości z mapy.

public static <T> List<T> ValueListFromMap(HashMap<String, T> map) {
    List<T> thingList = new ArrayList<>();

    for (Map.Entry<String, T> entry : map.entrySet()) {
        thingList.add(entry.getValue());
    }

    return thingList;
}
Hiral Pancholi
źródło
1
HashMap<Integer, List<String>> map = new HashMap<>(); 
List<String> list = new ArrayList<String>();
list.add("Java");
list.add("Primefaces");
list.add("JSF");
map.put(1,list);
if(map != null){
    return new ArrayList<String>((Collection<? extends String>) map.values());
}
Hakan Anlamaz
źródło