Как эффективно перебрать каждую запись на карте Java? - PullRequest
2938 голосов
/ 06 сентября 2008

Если у меня есть объект, реализующий интерфейс Map в Java, и я хочу перебрать каждую содержащуюся в нем пару, каков наиболее эффективный способ прохождения карты?

Будет ли порядок элементов зависеть от конкретной реализации карты, которую я имею для интерфейса?

Ответы [ 38 ]

4 голосов
/ 13 мая 2015

Вот общий типобезопасный метод, который может быть вызван для выгрузки любого заданного Map.

import java.util.Iterator;
import java.util.Map;

public class MapUtils {
    static interface ItemCallback<K, V> {
        void handler(K key, V value, Map<K, V> map);
    }

    public static <K, V> void forEach(Map<K, V> map, ItemCallback<K, V> callback) {
        Iterator<Map.Entry<K, V>> it = map.entrySet().iterator();

        while (it.hasNext()) {
            Map.Entry<K, V> entry = it.next();

            callback.handler(entry.getKey(), entry.getValue(), map);
        }
    }

    public static <K, V> void printMap(Map<K, V> map) {
        forEach(map, new ItemCallback<K, V>() {
            @Override
            public void handler(K key, V value, Map<K, V> map) {
                System.out.println(key + " = " + value);
            }
        });
    }
}

Пример

Вот пример его использования. Обратите внимание, что тип Map определяется методом.

import java.util.*;

public class MapPrinter {
    public static void main(String[] args) {
        List<Map<?, ?>> maps = new ArrayList<Map<?, ?>>() {
            private static final long serialVersionUID = 1L;
            {
                add(new LinkedHashMap<String, Integer>() {
                    private static final long serialVersionUID = 1L;
                    {
                        put("One", 0);
                        put("Two", 1);
                        put("Three", 3);
                    }
                });

                add(new LinkedHashMap<String, Object>() {
                    private static final long serialVersionUID = 1L;
                    {
                        put("Object", new Object());
                        put("Integer", new Integer(0));
                        put("Double", new Double(0.0));
                    }
                });
            }
        };

        for (Map<?, ?> map : maps) {
            MapUtils.printMap(map);
            System.out.println();
        }
    }
}

выход

One = 0
Two = 1
Three = 3

Object = java.lang.Object@15db9742
Integer = 0
Double = 0.0
4 голосов
/ 29 августа 2015

Если ваша причина для итерации через Map, это выполнить операцию над значением и записать полученное значение Map. Я рекомендую использовать transform -методы в Google Guava Maps классе.

import com.google.common.collect.Maps;

После того, как вы добавили Maps в свой импорт, вы можете использовать Maps.transformValues и Maps.transformEntries на своих картах, например:

public void transformMap(){
    Map<String, Integer> map = new HashMap<>();
    map.put("a", 2);
    map.put("b", 4);

    Map<String, Integer> result = Maps.transformValues(map, num -> num * 2);
    result.forEach((key, val) -> print(key, Integer.toString(val)));
    // key=a,value=4
    // key=b,value=8

    Map<String, String> result2 = Maps.transformEntries(map, (key, value) -> value + "[" + key + "]");
    result2.forEach(this::print);
    // key=a,value=2[a]
    // key=b,value=4[b]
}

private void print(String key, String val){
    System.out.println("key=" + key + ",value=" + val);
}
2 голосов
/ 03 января 2014

Существует несколько способов итерации карты. Пожалуйста, обратитесь к следующему коду.

Когда вы выполняете итерацию карты с помощью интерфейса итератора, вы должны использовать Entry или entrySet ()

Это выглядит так:

import java.util.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class IteratMapDemo{

    public static void main(String arg[]){
        Map<String, String> mapOne = new HashMap<String, String>();
        mapOne.put("1", "January");
        mapOne.put("2", "February");
        mapOne.put("3", "March");
        mapOne.put("4", "April");
        mapOne.put("5", "May");
        mapOne.put("6", "June");
        mapOne.put("7", "July");
        mapOne.put("8", "August");
        mapOne.put("9", "September");
        mapOne.put("10", "Octomber");
        mapOne.put("11", "November");
        mapOne.put("12", "December");

        Iterator it = mapOne.entrySet().iterator();
        while(it.hasNext())
        {
            Map.Entry me = (Map.Entry) it.next();
            //System.out.println("Get Key through While loop = " + me.getKey());
        }
        for(Map.Entry<String, String> entry:mapOne.entrySet()){
            //System.out.println(entry.getKey() + "=" + entry.getValue());
        }

        for (Object key : mapOne.keySet()) {
            System.out.println("Key: " + key.toString() + " Value: " +
                               mapOne.get(key));
        }
    }
}
2 голосов
/ 10 января 2015

Это не совсем отвечает на вопрос ОП, но может быть полезно для других, кто находит эту страницу:

Если вам нужны только значения, а не ключи, вы можете сделать это:

Map<Ktype, Vtype> myMap = [...];
for (Vtype v: myMap.values()) {
  System.out.println("value: " + v);
}

Ktype, Vtype - псевдокод.

1 голос
/ 22 августа 2014

Я скопировал данные карты в другую с помощью этого кода:

HashMap product =(HashMap)shopping_truck.get(i);
HashMap tmp = new HashMap();
for (Iterator it = product.entrySet().iterator(); it.hasNext();) {
    Map.Entry thisEntry = (Map.Entry) it.next();
    tmp.put(thisEntry.getKey(), thisEntry.getValue());
}
1 голос
/ 30 мая 2015

Я считаю, что это самый простой способ сделать это ...

/* For example, this could be a map object */
Map<String, Integer> MAP = new Map<>();

// Do something like put keys/value pairs into the map, etc...
MAP.put("Denver", 35);
MAP.put("Patriots", 14);

/* Then, simply use a for each loop like this to iterate */
for (Object o : MAP.entrySet()) {
    Map.Entry pair = (Map.Entry) o;
    // Do whatever with the pair here (i.e. pair.getKey(), or pair.getValue();
}
0 голосов
/ 05 ноября 2017

Итерировать карту очень легко.

for(Object key: map.keySet()){
   Object value= map.get(key);
   //Do your stuff
}

Например, у вас есть Map<String, int> data;

for(Object key: data.keySet()){
  int value= data.get(key);
}

Счастливое кодирование ...

0 голосов
/ 27 октября 2015

Если вы хотите перебрать карту в порядке добавления элементов, используйте LinkedHashMap вместо Map.

Этот подход работал для меня в прошлом:

LinkedHashMap<String,Integer> test=new LinkedHashMap();

test.put("foo",69);
test.put("bar",1337);

for(int i=0;i<test.size();i++){
    System.out.println(test.get(test.keySet().toArray()[i]));
}

Выход:

69
1337
...