Skip to content

Commit 35a7e63

Browse files
committed
Merge pull request giantray#22 from mahongliang/master
HashMap遍历
2 parents 0fa06f8 + 7a9b59a commit 35a7e63

File tree

5 files changed

+560
-24
lines changed

5 files changed

+560
-24
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# 初始化静态map #
2+
3+
## 问题 ##
4+
5+
怎么在Java中初始化一个静态的map
6+
7+
**方法一**:静态初始化器
8+
9+
**方法二**:实例初始化(匿名子类)
10+
11+
下面是描述上面两种方法的例子
12+
13+
import java.util.HashMap;
14+
import java.util.Map;
15+
public class Test{
16+
private static final Map<Integer, String> myMap = new HashMap<Integer, String>();
17+
static {
18+
myMap.put(1, "one");
19+
myMap.put(2, "two");
20+
}
21+
22+
private static final Map<Integer, String> myMap2 = new HashMap<Integer, String>(){
23+
{
24+
put(1, "one");
25+
put(2, "two");
26+
}
27+
};
28+
}
29+
30+
## 答案 ##
31+
32+
### 答案1 ###
33+
34+
匿名子类初始化器是java的语法糖,我搞不明白为什么匿名类来初始化,而且如果create的类是final的话,它将不起作用
35+
36+
我创建固定大小图的时候使用static初始化器
37+
38+
public class Test{
39+
private static final Map<Integer, String> myMap;
40+
static{
41+
Map<Integer, String> aMap = ...;
42+
aMap.put(1,"one");
43+
aMap.put(2,"two");
44+
myMap = Collections.unmodifiableMap(aMap);
45+
}
46+
}
47+
48+
49+
### 答案2 ###
50+
51+
我喜欢用Guava(是 Collection 框架的增强和扩张)的方法初始化一个静态的,不可改变的map
52+
53+
static fianl Map<Integer, String> myMap = ImmutablMap.of(
54+
1,"one",
55+
2, "two"
56+
)
57+
·
58+
当你的图entry的个数超过5个时候你就不能使用`ImmutableMap.of`可以试试`ImmutableMap.bulider()`
59+
60+
static fianl Map<Integer, String> myMap = ImmutableMap.<Integer, String>builder()
61+
{
62+
.put(1, "one")
63+
.put(2, "two")
64+
65+
.put(15, "fifteen")
66+
.build();
67+
}
68+
69+
70+
# 原文链接 #
71+
72+
http://stackoverflow.com/questions/507602/how-can-i-initialize-a-static-map

contents/create-arraylist-arraylistt-from-array-t.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,24 @@
55
```java
66
Element[] array = {new Element(1),new Element(2),new Element(3)};
77
```
8-
如何将其转换为ArrayList`<Element>` arraylist呢?
8+
如何将其转换为ArrayList`<Element>` arraylist = ???
9+
10+
### 回答1 ###
11+
12+
`new ArrayList<Element>(Arrays.asList(array))`
13+
14+
###回答2
915

10-
###回答
1116
Arrays.asList(array)或者Arrays.asList(new Element(1),new Element(2),new Element(3))
1217

1318
不过,这样做有些坑要注意:
1419

1520
1. 这样做生成的list,是定长的。也就是说,如果你对它做add或者remove,都会抛UnsupportedOperationException。
1621
2. 如果修改数组的值,list中的对应值也会改变!
1722

23+
**Arrays.asList() 返回的是Arrays内部静态类,而不是Java.util.ArrayList的类。这个java.util.Arrays.ArrayList有set(),get(),contains()方法,但是没有任何add() 方法,所以它是固定大小的**
24+
25+
1826
如果希望避免这两个坑,请改用这个方式
1927
```java
2028
Collections.addAll(arraylist, array);

contents/iterate-through-a-hashmap.md

Lines changed: 74 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,74 @@
1-
##如何遍历map对象(如HashMap)
2-
3-
###jdk1.5以上版本
4-
```java
5-
for (Entry<String, String> entry : map.entrySet()){
6-
System.out.println(entry.getKey() + "/" + entry.getValue());
7-
}
8-
```
9-
需要 import java.util.Map.Entry;
10-
11-
###jdk1.4以下版本
12-
```java
13-
Iterator entries = myMap.entrySet().iterator();
14-
while (entries.hasNext()) {
15-
Entry thisEntry = (Entry) entries.next();
16-
Object key = thisEntry.getKey();
17-
Object value = thisEntry.getValue();
18-
}
19-
```
20-
21-
stackoverflow链接:
22-
http://stackoverflow.com/questions/1066589/iterate-through-a-hashmap
1+
# HashMap遍历 #
2+
3+
在Java中有多种遍历HashMAp的方法。让我们回顾一下最常见的方法和它们各自的优缺点。由于所有的Map都实现了Map接口,所以接下来方法适用于所有Map接口的图的实现(如:HaspMap,TreeMap,LinkedMap,HashTable,etc)
4+
5+
## 方法#1 使用For-Each迭代entries ##
6+
7+
这是最常见的方法,并在大多数情况下更可取的。当你在循环中需要使用Map的键和值时,就可以使用这个方法
8+
9+
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
10+
for(Map.Entry<Integer, Integer> entry : map.entrySet()){
11+
System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue())
12+
}
13+
14+
注意:For-Each循环是Java5新引入的,所以只能在Java5以上的版本中使用。如果你遍历的map是null的话,For-Each循环会抛出NullPointerException异常,所以在遍历之前你应该判断是否为空引用。
15+
16+
## 方法#2 使用For-Each迭代keys和values ##
17+
18+
如果你只需要用到map的keys或values时,你可以遍历KeySet或者values代替entrySet
19+
20+
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
21+
22+
//iterating over keys only
23+
for (Integer key : map.keySet()) {
24+
System.out.println("Key = " + key);
25+
}
26+
27+
//iterating over values only
28+
for (Integer value : map.values()) {
29+
System.out.println("Value = " + value);
30+
}
31+
32+
这个方法比entrySet迭代具有轻微的性能优势(大约快10%)并且代码更简洁
33+
34+
## 方法#3 使用Iterator迭代 ##
35+
36+
使用泛型
37+
38+
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
39+
Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator();
40+
while (entries.hasNext()) {
41+
Map.Entry<Integer, Integer> entry = entries.next();
42+
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
43+
}
44+
45+
不适用泛型
46+
47+
Map map = new HashMap();
48+
Iterator entries = map.entrySet().iterator();
49+
while (entries.hasNext()) {
50+
Map.Entry entry = (Map.Entry) entries.next();
51+
Integer key = (Integer)entry.getKey();
52+
Integer value = (Integer)entry.getValue();
53+
System.out.println("Key = " + key + ", Value = " + value);
54+
}
55+
56+
你可以使用同样的技术迭代keyset或者values
57+
58+
这个似乎有点多余但它具有自己的优势。首先,它是遍历老java版本map的唯一方法。另外一个重要的特性是可以让你在迭代的时候从map中删除entries的(通过调用iterator.remover())唯一方法.如果你试图在For-Each迭代的时候删除entries,你将会得到unpredictable resultes 异常。
59+
60+
从性能方法看,这个方法等价于使用For-Each迭代
61+
62+
## 方法#4 迭代keys并搜索values(低效的) ##
63+
64+
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
65+
for (Integer key : map.keySet()) {
66+
Integer value = map.get(key);
67+
System.out.println("Key = " + key + ", Value = " + value);
68+
}
69+
70+
这个方法看上去比方法#1更简洁,但是实际上它更慢更低效,通过key得到value值更耗时(这个方法在所有实现map接口的map中比方法#1慢20%-200%)。如果你安装了FindBugs,它将检测并警告你这是一个低效的迭代。这个方法应该避免
71+
72+
## 总结 ##
73+
74+
如果你只需要使用key或者value使用方法#2,如果你坚持使用java的老版本(java 5 以前的版本)或者打算在迭代的时候移除entries使用方法#3,另外的话使用方法#1,尽量避免出现方法#1的情况

0 commit comments

Comments
 (0)