java中Map的使用

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

一、Map转为List

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

// ksy List
List keyList = new ArrayList(map.keySet());
// value List
List valueList = new ArrayList(map.valueSet());
// key-value List
List 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 code
public class Test {
  private static final Map map;
  static {
    map = new HashMap();
    map.put(1, "one");
    map.put(2, "two");
  }
}  

// right code
public 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。

 HashMapHashTableTreeMap
Iterator ordernonoyes
null key-valueyes-yesno-nono-yes
synchronizednoyesno
time 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值