您的位置:首页 > 其它

集合工具类之Map特点和实现类的详解

2017-07-25 23:12 351 查看
Map集合:(映射的数学解释)

设A、B是两个非空集合,如果存在一个法则f,使得对A中的每一个元素a,按法则f,在B中有唯一确定的元素b与之对应,则称f为从A到B的映射,记作f:A→B。

映射关系(两个集合):A集合和B集合:

A集合中的每一个元素都可以在B集合中找到唯一的一个值与之对应。

严格上来说Map并不是集合,而是两个集合之间的映射关系(Map接口并没有继承于Collection接口),然而因为Map可以存储数据(每次存储都应该存储A集合中以一个元素(Key),B集合中一个元素(value)),我们还是习惯把Map也称之为集合。

因为Map接口并没有继承于Collection接口,也没有继承于Iterable接口,所以不能直接对Map使用for:each操作。但是可以间接迭代:

public class MapDemo {
public static void main(String[] args) {
Map<String, Object> map = new HashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
map.put("key3", "value3");
map.put("key4", "value4");
map.put("key5", "value5");

//Map不是集合,不能直接做迭代,但是可以间接做迭代,获取Map中所有的Key所组成的集合(key是不能重复,类似Set)
Set<String> set = map.keySet();
for (String key : set) {
System.out.println(key+"->"+map.get(key));
}

System.out.println("--------------------------");

//获取map中所有value所组成的集合(value是可以重复的,类似于List)
Collection<Object> value = map.values();
for (Object val : value) {
System.out.println(val);
}

System.out.println("--------------------------");

//获取map中所有的Entry(key->value)
Set<Map.Entry<String, Object>> entrys = map.entrySet();
for (Map.Entry<String, Object> entry : entrys) {
String key = entry.getKey();  //获取key
Object val = entry.getValue();  //获取value
System.out.println(key+"->"+val);
}
}

}


Map的常用实现类:






HashMap:采用哈希表算法,此时Map中的key不会保证添加的先后顺序,key也不允许重复。(key判断重复的标准:key1和key2是否equals为true,并且hashCode相等)

TreeMap:采用红黑树算法,此时Map中的key会按照自然排序或定制排序进行排序,key也不允许重复。(key判断重复的标准:compareTo/compare的返回值是否为0)

LinkedHashMap:采用链表和哈希表算法,此时Map中的key会保证先后添加的顺序,key也不允许重复。(key判断重复的标准和HashMap中的key的标准相同)

Hashtable:采用哈希表算法,是HashMap的前身。(类似Vector是ArrayList的前身)

在Java的集合框架之前,表示映射关系就是用Hashtable,所有的方法都是用synchronized修饰符,线程安全,但是性能相对HashMap较低

Properties:Hashtable的子类,此时要求key和value都是String类型。

一般的,我们定义Map,key都是用不可改变的类(String),把key作为value的唯一名称。

HashMapTreeMap以及LinkedHashMap都是线程不安全的,但是性能极高。

解决方案:Map map = Collections.sysnchronizedMap(Map对象);

Hashtable类是线程安全的,但是性能较低。

哈希表算法:做等值查询最快;

数组结构算法:做范围查询最快->应用到索引上。

来看看一个很有意思的Map案例:计算一个字符串中,每个字符的出现次数:

public class MapStringDemo {
public static void main(String[] args) {
String str = "asdhlkadsjfhoifhlaksjbvoiuhdf";
//把字符串转换为char数组(字符串本质就是char[])
char[] arr = str.toCharArray();
//key:存储字符名,value:存储出现次数
Map<Character,Integer> map = new TreeMap<>();
//循环得到每一个字符串
for (char ch : arr) {
//判断当前字符是否在Map中的key存在
if(map.containsKey(ch)){
//当前Map的key包含该字符,此时取出该value值递增1,再放进去
Integer old = map.get(ch);
map.put(ch, old+1);
}else{
//当前Map的key不包含该字符,把该字符存储到Map只能怪,设置value为1
map.put(ch, 1);
}

}
System.out.println(map);
}

}


运行结果:



选用哪一种容器取决于每一种容器的存储特点以及当前业务的需求:

List:单一元素集合,允许元素重复,记录元素添加顺序。

Set:单一元素集合,不允许元素重复,不记录元素添加顺序。(既要不重复,又要保证先后顺序:LinkeHashSet)

Map:双元素集合,如果存储数据的时候,还得给数据取唯一的每一个名称,此时考虑使用Map。

List和Set以及Map之间相互转换问题:

List<String> list = new ArrayList<>();

把List装换为Set:

Set<String> set = new HashSet<>(list);//此时会消除重复的元素
把Set装换为List:

List<String> list = new ArrayList<>(set);

Map不能直接转换为List或Set(但是Map中的方法可以间接转换)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Map 集合工具类