java中Map的使用

来源:互联网 发布:mysql函数大全 编辑:程序博客网 时间:2024/04/30 05:29

Map是一个包含key-value对集合的数据结构,并且key唯一。下面是map的常用方式:

一、Map转为List

Map接口提供了三个集合视图:key集合、value集合、key-value集合。它们都可以通过一个构造函数或者调用addAll()方法转换为List。

// ksy ListList keyList = new ArrayList(map.keySet());// value ListList valueList = new ArrayList(map.valueSet());// key-value ListList entryList = new ArrayList(map.entrySet());

二、遍历Map中的Entry

遍历Map即遍历kye-value对,这些pairs存储在Map.Entry中,Map.entrySet()返回一个key-value集合,以下是最有效的遍历entry的方式

for(Entry entry : map.entrySet()){  // get key  K key = entry.getKey();  // get value  V value = entry.getValue();}

也可以使用迭代器,尤其是在JDK1.5以前的版本

Iterator itr = map.entrySet().iterator();while(itr.hasNext()){  Entry entry = itr.next();  // get key  K key = entry.getKey();  // get value  V value = netry.getValue();}

三、按key值排序Map

常用方法是将Map.Entry放在一个List里,然后使用一个Comparator排序这些值

List list = new ArrayList(map.entrySet());Collections.sort(list,new Comparator()) {  @Override  public int compare(Entry e1, Entry e2){     return e1.getKey().compareTo(e2.getKey());  }}

另一种方法是使用SortedMap,提供了keys上的全排序,因此所有的keys或者实现了Comparable或者可以作为被comparator接收。

TreeMap是SortedMap的一个实现类,他的构造函数可以接收comparator。

下面代码实现了普通Map到SortedMap的转换。

SortedMap sortedMap  = new TreeMap(new Comparator()) {  // @Override  public int compare(K k1, K k2) {    return k1.compareTo(k2);  }}

四、按values排序Map

将Map放入List然后排序它,不过这次我们比较的是Entry.getValue()。

List list = new ArrayList(map.entrySet());Collections.sort(list,new Comparator()) {  @Override  public int compare(Entry e1, Entry e2){     return e1.getValue().compareTo(e2.getValue());  }}

我们也可以使用sorted map解决这个问题,前提是values也是唯一的。满足了这个条件,就可以将key=value转换为value=key,这中方法有很大局限性,因此不建议使用。

五、static/immutable Map的初始化

如果希望一个Map是constant的,最好的方法是将它copy给一个immutable map
初始化一个static/immutable map,可以使用一个static的initializer(如下代码)。但是这段代码是有问题的,尽管map被声明为static final,但是仍然可以对它进行操作,因此不没有真正实现immutable。使用一个static的initializer创建immutable map,我们还需要一个额外的anonymous class,并在初始化的最后一步将它copy到一个unmodifiable map里。这样如果在对m该ap进行操作就会抛出UnsupportedOperationException错误。

// wrong codepublic class Test {  private static final Map map;  static {    map = new HashMap();    map.put(1, "one");    map.put(2, "two");  }}  // right codepublic class Test {  private static final Map map;  static {    Map aMap = new HashMap();    aMap.put(1, "one");    aMap.put(2, "two");    map = collections.unmodifiableMap(aMap);  }}

六、HashMap、TreeMap、HashTable的比较

1. 迭代顺序:HashMap和HashTable不能保证原来map的顺序,TreeMap根据key的自然序或者comparator遍历整个entry;

2. key-value权限:HashMap允许可以key和value都为null(只有key为null也可以)。HashTable不允许key或value为null;如果HashTable使用自然徐序或它的comparator时不允许key为null,会抛出异常;

3.同步:只用HashTable是同步的,其它都不同步。所以如果不需要考虑线程安全的话,推荐使用HashMap,代替HashTable。

 HashMapHashTableTreeMapIterator ordernonoyesnull key-valueyes-yesno-nono-yessynchronizednoyesnotime performanceo(1)o(1)o(log n)implementationbucketsbuckets

red-black

tree        

七、反向Map

有时候我们需要map的value是唯一的,也就是说one-to-one Map,可以通过value找到key,这种数据结构叫做bidirectional map,不过JDK现在还不支持这种数据结构。

Apache Common Collection和Guava 提供了这种数据结构,分别叫BidiMap和BiMap。

八、Map的浅拷贝

java中大部分Map的实现都提供了一个拷贝构造函数,但是这个拷贝过程不是同步的,为了避免这种不同步拷贝,可以使用Collections.synchronizedMap()。

Map copiedMap = Collections.synchronizedMap(map);

另一个有趣的方法是使用clone()方法,但是不推荐使用,引用Josh Bloch(Java Collection框架的设计者)在“Copy construct versus cloning”中的以一句话:

     I often provide a public clone method on concrete classes because people expect it....It's a shame that Cloneable is broken,but it happens....Cloneable is a weak spot, and I think people should be aware of its limitations.

既然大牛不建议了,这里也就不讲了。呵呵。。。

九、创建一个空Map

如果map是静态的,使用:

map = Collections.emptyMap();

否则,使用任何一个实现均可,如:

map = new HashMap();
0 0
原创粉丝点击