Java复习笔记第二篇----集合学习之下篇

image

映射表集合关系图

引言:list是一个集合,它可以快速的查找现有的元素。但是要查看一个元素,我们需要有想要查找元素的精确的副本;这并不是一种非常通用的查找方式;

映射表的概念就由此而来;我们知道某些键的信息;并想要查找与之对应的元素;映射表数据结构就是为此设计的;键值对!;

1:Map:映射表集合的顶级父类:它是一种键值对的形式存储数据的集合,根据键值我们就可准确查询我们想要查询的值;

  • <1>:HashMap:一种对键进行散列的映射表。散列或者函数只能作用于键,对键对应的值不能散列也不能进行比较;

  • <2>:TreeMap:树映射表是使用键的正顺序对值进行排列,并将其组织成搜索树;和集合一样如果集合中的元素必须要按照顺序访问我们最好采用散列映射表;查询元素时;散列表相对而言要更快一点

  • <3>:WeakHashMap:主要是用来删除没用其他引用的集合中的元素;配合Java的垃圾回收机制;
    如果有一个值对应的键已经不再使用了,由于程序中的任何部分没有再出现这个键;所以这个键/值便无法从映射表中删除;此时就要由WeakHashMap去完成这件事情了;当某个键的唯一引用来自于散列表条目时,这张数据结构将和垃圾回收器协作工作一起删除键/值对。
    具体机制:WeakHashMap使用弱引用(weak references)保存键;WeakReference对象将引用保存到另外一个对象中,即使是散列表键;如果某个对象仅仅使用WeakReference引用,就将这个对象的弱引用放入到队列中;WeakHashMap将周期性地检查队列;以便查找新添加的弱引用;

  • <4>:LinkedHashMap:连接映射表:主要使用来记住插入元素的顺序;每次插入元素时,该集合都会为待插入元素找到合适位置;使得表面上看该集合中的元素是无序的;没当调用get或者put时受影响的条目都会从当前位置删除,并将该条目放大链表的尾部;只有条目在链表中的位置会受影响;而散列表中的桶并不会受影响;一个条目总是位于散列码对应的桶中;

    • 链接散列映射表将用访问顺序,而不是插入顺序;对映射表的条目进行迭代;
    • 访问顺序对于实现高速缓存的“最近最少使用”原则十分重要。例如:可能希望将访问频率高的元素放在内存中;而访问频率低的元素就从数据库中读取;当在表中找不到元素项目并且表有已经满时,就可以将迭代器加入到表中;并将枚举的前几个匀速删除,这些就是最近最少使用的几个元素;
  • <5>:EnumMap:枚举集合映射表:是一个键类型为枚举类型的映射表。它可以直接高效的使用一个值数组实现;使用时需要在构造器中指定键类型;
    EnumMap<Weekday,Employee> personIncharge = new EnumMap<>(Weekday.class)

  • <6>:表示散列集映射表:IdentityHashMap,在这个类中,键的散列值不是用hashCode函数计算而来的,而是使用System.identityHashCode方法计算的;这种方式是Object.hashCode方法根据兑现的内存地址来计算散列码时所使用的方式;而且在对两个对象进行比较时,IdentityHashMap类使用==而不是equals;
    也就是说不同的键对象,即使内容相同,也被视为是不同的对象;在实现对象遍历算法时(如对象序列化),这个类十分有用;可以用来跟踪每个对象的遍历情况;

  • <7>:SortedMap:是一个集合接口,暴露了用于排除的比较器对象;并且定义方法可以获取集合中的子视图;

  • <8>:HashTable:和hashMap基本上差不多,以键值对形式存储数据;这里我们主要讲他和HashMap的区别:

    • A:HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行)。
    • B:HashMap是非synchronized,而Hashtable是synchronized,这意味着Hashtable是线程安全的,多个线程可以共享一个Hashtable;而如果没有正确的同步的话,多个线程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。
    • C:另一个区别是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。这条同样也是Enumeration和Iterator的区别。
    • D:由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。
    • E:HashMap不能保证随着时间的推移Map中的元素次序是不变的

<9>:Properties:Java.util.Properties是对properties这类配置文件的映射。支持key-value类型和xml类型两种。

总结:Java集合框架的本身并没有将映射表本身视为一个集合;然而却可以获得映射表的视图;这是实现了一组Collection接口的对象;或者它的子接口视图;

有三个视图:分别为键集合,值集合,和键值对集合;(键和键值对形成了一个集合),这是因为在映射表中一个键只能有一个副本;下面的三种方法将返回3个视图:

  • Set keySet();获取映射表中所有的键

  • Collection values();获取映射表中所有的值集合

  • Set<Map.Entry<K,V>> entrySet();获取映射表中所有的键集合和键值对集合;

当然还有其他返回视图的方法此处不再赘述!

推荐阅读更多精彩内容