集合的总结

List

List:有序(存入和取出的顺序一致),元素都有索引值,元素可以重复。
* Set:元素不能重复,无序。
*
**** List:特有的常见方法:有一个共性的特点就是可以操作角标。
*1.添加
* void add();
*
* 2.删除
* Object remove(index)
*
* 3.修改
* Object set (index,element)
*
* 4.获取
* Object get(index)
* int indexOf(object)
* List subList(from,to)
* List:
* 1.Vector 内部是数组数据结构,是同步的。增删,查询都很慢。
* 2.ArrayList:内部是数组数据结构,是不同步的。替代了Vector。查询的速度快。
* 3.LinkedList:内部是链表数据结构,是不同步的。增删元素的速度是很快的。
除了实现 List 接口外,LinkedList 类还为在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法。
这些操作允许将链接列表用作堆栈、队列或双端队列。

 Vector & ArrayList

 Vector的方法都是同步的(Synchronized),是线程安全的(thread-safe),而ArrayList的方法不是,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好。虽然Vector是安全的,也不推荐使用,同样不推荐使用Collections工具,而是使用JUC的并发容器。

ArrayList & LinkedList

ArrayList的内部实现是基于内部数组Object[],所以从概念上讲,它更象数组,但LinkedList的内部实现是基于一组连接的记录,所以,它更象一个链表结构,所以,它们在性能上有很大的差别: 
从上面的分析可知,在ArrayList的前面或中间插入数据时,你必须将其后的所有数据相应的后移,这样必然要花费较多时间,所以,当你的操作是在一列 数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能; 而访问链表中的某个元素时,就必须从链表的一端开始沿着连接方向一个一个元素地去查找,直到找到所需的元素为止,所以,当你的操作是在一列数据的前面或中 间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。 

 

Set
Set:元素不可以重复,是无序,并且最多包含一个 null 元素
  |--TreeSet:可以对Set集合中的元素进行排序,是不同步的
  判断元素唯一性的方法:就是根据比较方法返回是否是0。

TreeSet对元素进行排序的方式之一:
让元素自身具备比较功能,元 素就需要实现Comparable接口。覆盖compareTo方法。
如果不要按照对象中具备的自然顺序进行排序。如果对象中不具备自然顺序,可以使用
TreeSet集合的第二种排序方式之二:
TreeSet不能直接对元素进行比较,它是根据元素的比较结果排序,如果元素不具备比较功能,让集合自身具备比较功能。
定义一个类实现Comparator接口,覆盖compare方法。
将该类对象作为参数传递给TreeSet集合的构造函数。

HashSet的性能总是比TreeSet好(特别是最常用的添加、查询等操作),因为TreeSet需要额外的红黑树算法来维护元素的次序。只有当需要一个保持顺序的Set时,才应该使用TreeSet,否则都应该使用HashSet。

对于普通的插入、删除操作,LinkedHashSet比HashSet要稍微慢一点,这是维护链表带来的开销造成的,但是由于有了链表,遍历会更快。

集合的一些技巧:
需要唯一吗?
需要:Set
  需要制定顺序:
  需要:TreeSet
  不需要:HashSet
但是想要一个和存储一致的顺序:LinkedHashSet


不需要:List
List有着和存储一致的顺序
  需要频繁增删吗?
  需要:LinkedList
  不需要:ArrayList

 

Queue

Queue和PriorityQueue

PriorityQueue是Queue的实现类,但是不遵循FIFO,

可以作为最小堆使用(默认),也可以构造比较器作为最大堆使用

Deque和ArrayDeque

Deque是一个双端队列,既可以做队列使用也可以做栈使用

LinkedList

这是一个非常强悍的类,可以作为List集合、双端队列、栈

 

Map
Map:一次添加一对元素。Collection一次添加一个元素
Map也称为双列集合,Collection集合称为单列集合
其实map集合中存储的就是键值对。

map集合中必须保证键的唯一性。
常用方法:
1.添加
  value put (key,value):返回前一个和key关联的值,如果没有返回null
2.删除
  void clear():清空map集合
  value remove():根据指定的key翻出这个键值对
3.判断
  boolean containsKey(key)
  Boolean contiansValue(value)
  Boolean isEmpty()
4.获取
  value get(key):通过键获取值,如果没有该键返回null
  当然可以通过返回null,来判断是否包含指定键,

5.获取大小

  int size():获取键值对的个数。

Map常用的子类:
  |---Hashtable:内部结构是哈希表,是同步的。不允许null作为键,null作为值。

  |--Properties:用来存储键值对的配置文件的信息,可以和io技术相结合。

  |---HashMap:内部结构是哈希表,不是同步的。允许null作为键,null作为值。

  |---LinkdedHashMap:内部结构是哈希表和链表,迭代顺序和存储数据一致,不是同步的。

  |---TreeMap:内部结构是红黑树,不同步,可以对Map集合中的键进行排序。

编程技巧:当TreeMap被填充后,就可以调用keySet(),取得key组成的Set,然后使用toArray()方法生成key的数组(集合collection中的类都有toArray()方法),接下来使用Array的binarySearch()方法在已排序的数组中快速查找对象。

HashMap比Treemap和HashTable都要快。


如何记录每个容器的结构和所属体系?
看名字:
List
ArrayList
LinkedList

Set
HashSet
TreeSet
后缀名即是该集合的体系。
前缀名即是该集合的数据结构。
看到array就要想到数组,就要想到查询快,有角标。
看到link就要想到链表,就要想到增删快,就要 add remove
看到hash就要想到哈希表,就要想到唯一性,就要想到元素覆盖hashcode和equals方法
看到tree就要想到二叉树,就要想到排序,就要想到两个接口Comparator,Comparable
而且通常这些常用的集合容器都是不同步的。

 

HashMap和HashSet分析:

对于同意HashSet机器子类而言,他们采用hash算法来决定稽核中元素的存储位置,并通过hash算法来控制集合的大小 ;

对于HashMap、HashTable及其子类而言,他们采用hash算法那来决定Map中的key的存储,并通过hash算法来控制集合的大小 ;

Hash表中又一个负载极限,负载极限决定了hash表的最大填满程度,当hash表中的负载因子达到负载极限的时候,hash表会自动成倍的增加容量,将原来对象重新分配,这称为rehashing。

默认是0.75,这是折中的结果。较高的负载极限可以降低hash表所占用的内存空间,但是会增加查询数据的时间开销。较低的负载极限反之。

 

posted @ 2018-07-11 22:38  开拖拉机的蜡笔小新  阅读(258)  评论(0编辑  收藏  举报