如果我有一个用Java实现Map接口的对象,并且我希望对其中包含的每一对进行迭代,那么最有效的方法是什么?
元素的顺序是否取决于我对接口的特定映射实现?
如果我有一个用Java实现Map接口的对象,并且我希望对其中包含的每一对进行迭代,那么最有效的方法是什么?
元素的顺序是否取决于我对接口的特定映射实现?
当前回答
Java 8
我们得到了接受lambda表达式的forEach方法。我们也有流API。考虑一张地图:
Map<String,String> sample = new HashMap<>();
sample.put("A","Apple");
sample.put("B", "Ball");
在关键点上重复:
sample.keySet().forEach((k) -> System.out.println(k));
遍历值:
sample.values().forEach((v) -> System.out.println(v));
遍历条目(使用forEach和Streams):
sample.forEach((k,v) -> System.out.println(k + ":" + v));
sample.entrySet().stream().forEach((entry) -> {
Object currentKey = entry.getKey();
Object currentValue = entry.getValue();
System.out.println(currentKey + ":" + currentValue);
});
流的优点是,如果我们需要,它们可以很容易地并行化。我们只需要使用parallelStream()代替上面的stream()。
forEachOrdered与forEach的流?forEach不遵循遭遇顺序(如果已定义),本质上是非确定性的,正如forEachOrdered一样。因此forEach不保证订单会被保留。还要查看此项了解更多信息。
其他回答
在Java 8中,您可以使用新的lambdas功能快速、干净地完成任务:
Map<String,String> map = new HashMap<>();
map.put("SomeKey", "SomeValue");
map.forEach( (k,v) -> [do something with key and value] );
// such as
map.forEach( (k,v) -> System.out.println("Key: " + k + ": Value: " + v));
k和v的类型将由编译器推断,不再需要使用Map.Entry。
小菜一碟
在Java 1.4中尝试:
for( Iterator entries = myMap.entrySet().iterator(); entries.hasNext();){
Entry entry = (Entry) entries.next();
System.out.println(entry.getKey() + "/" + entry.getValue());
//...
}
排序将始终取决于特定的映射实现。使用Java 8,您可以使用以下任一选项:
map.forEach((k,v) -> { System.out.println(k + ":" + v); });
Or:
map.entrySet().forEach((e) -> {
System.out.println(e.getKey() + " : " + e.getValue());
});
结果相同(顺序相同)。entrySet由地图支持,因此您可以获得相同的顺序。第二个很方便,因为它允许您使用lambdas,例如,如果您只想打印大于5的Integer对象:
map.entrySet()
.stream()
.filter(e-> e.getValue() > 5)
.forEach(System.out::println);
下面的代码显示了通过LinkedHashMap和普通HashMap的迭代(示例)。您将看到顺序的不同:
public class HMIteration {
public static void main(String[] args) {
Map<Object, Object> linkedHashMap = new LinkedHashMap<>();
Map<Object, Object> hashMap = new HashMap<>();
for (int i=10; i>=0; i--) {
linkedHashMap.put(i, i);
hashMap.put(i, i);
}
System.out.println("LinkedHashMap (1): ");
linkedHashMap.forEach((k,v) -> { System.out.print(k + " (#="+k.hashCode() + "):" + v + ", "); });
System.out.println("\nLinkedHashMap (2): ");
linkedHashMap.entrySet().forEach((e) -> {
System.out.print(e.getKey() + " : " + e.getValue() + ", ");
});
System.out.println("\n\nHashMap (1): ");
hashMap.forEach((k,v) -> { System.out.print(k + " (#:"+k.hashCode() + "):" + v + ", "); });
System.out.println("\nHashMap (2): ");
hashMap.entrySet().forEach((e) -> {
System.out.print(e.getKey() + " : " + e.getValue() + ", ");
});
}
}
输出:
LinkedHashMap (1):
10 (#=10):10, 9 (#=9):9, 8 (#=8):8, 7 (#=7):7, 6 (#=6):6, 5 (#=5):5, 4 (#=4):4, 3 (#=3):3, 2 (#=2):2, 1 (#=1):1, 0 (#=0):0,
LinkedHashMap (2):
10 : 10, 9 : 9, 8 : 8, 7 : 7, 6 : 6, 5 : 5, 4 : 4, 3 : 3, 2 : 2, 1 : 1, 0 : 0,
HashMap (1):
0 (#:0):0, 1 (#:1):1, 2 (#:2):2, 3 (#:3):3, 4 (#:4):4, 5 (#:5):5, 6 (#:6):6, 7 (#:7):7, 8 (#:8):8, 9 (#:9):9, 10 (#:10):10,
HashMap (2):
0 : 0, 1 : 1, 2 : 2, 3 : 3, 4 : 4, 5 : 5, 6 : 6, 7 : 7, 8 : 8, 9 : 9, 10 : 10,
有几种方法可以迭代地图。请参考以下代码。
使用迭代器接口迭代地图时,必须使用Entry<K,V>或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));
}
}
}
Map上的一个有效迭代解决方案是从Java5到Java7的for循环。这里是:
for (String key : phnMap.keySet()) {
System.out.println("Key: " + key + " Value: " + phnMap.get(key));
}
在Java8中,可以使用lambda表达式对Map进行迭代。这是一个增强的forEach
phnMap.forEach((k,v) -> System.out.println("Key: " + k + " Value: " + v));
如果要为lambda编写条件,可以这样编写:
phnMap.forEach((k,v)->{
System.out.println("Key: " + k + " Value: " + v);
if("abc".equals(k)){
System.out.println("Hello abc");
}
});