集合工具类之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操作。但是可以间接迭代:
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的唯一名称。
HashMap和TreeMap以及LinkedHashMap都是线程不安全的,但是性能极高。
解决方案:Map map = Collections.sysnchronizedMap(Map对象);
Hashtable类是线程安全的,但是性能较低。
哈希表算法:做等值查询最快;
数组结构算法:做范围查询最快->应用到索引上。
来看看一个很有意思的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中的方法可以间接转换)。
设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的唯一名称。
HashMap和TreeMap以及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中的方法可以间接转换)。
相关文章推荐
- 集合工具类之Set特点和实现类的详解
- 集合工具类之List特点和实现类的详解
- Javascript实现的Map集合工具类完整实例
- Javascript实现的Map集合工具类完整实例
- 【JAVA】java中实现map集合的数据存取详解三种方法。Android程序员也是要会写的
- [置顶] 【JAVA】java中实现map集合的数据存取详解三种方法。Android程序员也是要会写的
- Javascript实现Map集合工具类
- 【JAVA】java中实现map集合的数据存取详解三种方法。Android程序员也是要会写的
- java 集合(list、set、map)的特点 集合相关的类有一大堆
- JavaSE学习实战完全笔记--集合的实现细节--Set和Map
- JAVA三种集合LIST、SET、MAP ——详解
- 黑马程序员——JAVA基础——集合---概述、Collection中共性方法、List、Map、工具类Collections和Arrays
- 黑马程序员——java基础知识之泛型、集合(Map、工具类等)
- Java实现过滤掉map集合中key或value为空的值示例
- Map、Set、Iterator迭代详解与Java平台的集合框架
- [重磅,建议收藏]JAVA集合框架中的常用集合及其特点、适用场景、实现原理简介
- java如何对map进行排序详解(map集合的使用)
- map集合详解
- 常见Java集合实现细节——List集合与Map集合
- 深入Java集合学习之HashMap的实现原理详解