Java 容器综述

来源:互联网 发布:怎么做好网络宣传 编辑:程序博客网 时间:2024/06/01 23:45

在Java的util包中有两个所有容器的父接口CollectionMap

容器特点:
1. 用于存储对象
2. 长度是可变的
3. 不可以存储基本数据类型值

这里写图片描述

这里写图片描述


Array/Arrays

Java所有“存储及随机访问一连串对象”的操作,Array是最有效率的一种。
1. 效率高,但容量固定且无法动态改变。
2. Array还有一个缺点是,无法判断其中实际存有多少元素,length只是告诉我们array的容量。
3. Java中有一个Arrays类,专门用来操作array。

Arrays中拥有一组static函数:

  • equals():比较两个array是否相等。array拥有相同元素个数,且所有对应元素两两相等。
  • fill():将值填入array中。
  • sort():用来对array进行排序。
  • binarySearch():在排好序的array中寻找元素。
  • System.arraycopy():array的复制。

若写程序时不知道究竟需要存储多少元素,在空间不足时希望能自动扩增容量,则要使用容器类库,Array数组不适用。


Java容器类库用途是保存对象,分为2类:

  • Collection
    一个独立元素的序列,每个位置只有一个元素,这些元素都服从一条或多条规则。List必须按照插入的顺序保存元素,Set不能有重复元素。Queue按照排队规则来确定对象产生的顺序(通常与插入的顺序相同)。
  • Map
    存储成对的键值对对象,使用键来查找值。映射表允许使用一个对象来查找某个对象,也被称为关联数组或字典。
    另外,Map可以返回其所有组成的Set 和 其所有组成的Collection,或其键值对组成的Set,并且还可以像数组一样扩展多维Map,只需让Map中键值对的每个“值”是一个Map。

Iterator

迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列容器的底层实现结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。

Java中的Iterator功能比较简单,并且只能单向移动:

  • 使用iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法属于java.lang.Iterable接口,被Collection继承。
  • 使用next()获得序列中的下一个元素。
  • 使用hasNext()检查序列中是否还有元素。
  • 使用remove()将迭代器新返回的元素删除。

Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。

List

List接口在Collection的基础上添加了大量的方法,使得可以在List中间插入和移除元素。
ArrayListLinkedList都按照被插入的顺序保存元素,区别在于执行某些操作时的性能。此外,LinkedList包含的操作也多于ArrayList。

  • ArrayList:由数组实现的List,随机访问元素比较快,有连续的数组空间,但是在List的中间插入和移除元素时较慢,需要大量移动内部的元素。ListIterator只应用来由后向前遍历ArrayList,而不是用来插入和删除元素,因为这比LinkedList开销要大很多。
    可以把ArrayList当做“可以自动扩充自身的数组”来看待,使用ArrayList也相当简单:创建一个实例,用add()插入对象;然后用get()访问这些对象,此时需要索引,就像数组一样,但是不需要方括号。ArrayList还有一个size()方法,使你知道有多少个元素添加进来,从而不会不小心因索引越界而引发错误。
  • LinkedList:在LinkedList中间插入、删除较快,提供优化的顺序访问,随机访问时较慢。方法比ArrayList多,如队列以及栈的行为,由LinkedList提供支持。如方法addFirst()、addLast()、getFirst()、getLast()、removeFirst()、removeLast(),这些方法(没有在任何接口或基类中定义过)使得LinkedList可以当作堆栈、队列和双向队列使用。

Set

HashSet TreeSet LinkedHashSet

每个相同的项只保存一次,即存入Set的每个元素必须是唯一的。加入Set的Object必须重写equals()方法以确保对象的唯一性。Set与Collection有完全一样的接口。

  1. Hashset 存储方式复杂,能快速定位一个元素,保证了最快的获取速度。存入HashSet的对象必须实现hashCode()
  2. TreeSet 底层为树结构,按照升序保存对象,使用它可以从Set中提取有序的序列。
  3. LinkedHashSet 按照添加的顺序保存对象。具有HashSet的查询速度,并且内部使用链表维护元素的顺序(插入的次序)。在使用迭代器遍历Set时,结果会按元素插入的次序显示。

HashSet采用散列函数对元素进行排序,这是专门为快速查询而设计的;
TreeSet采用红黑树的数据结构进行排序元素;
LinkedHashSet内部使用散列以加快查询速度,同时使用链表维护元素的次序,使得看起来元素是以插入的顺序保存的。

Map

Map主要用于存储健值对,根据键得到值,因此不允许键重复,但允许值重复。Map.put(key,value)插入数据,Map.get(key)查找数据。不必指定Map的尺寸,因为它会自动的调整。

Map有四个实现类,分别是HashMap Hashtable LinkedHashMap 和 TreeMap

  • Hashmap 是一个最常用的Map,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。HashMap最多只允许一条记录的键为Null;允许多条记录的值为 Null;HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致。如果需要同步,可以用Collections的synchronizedMap方法使HashMap具有同步的能力。
    HashMap要比较自定义对象必须重写equals()方法和hashCode()方法。
  • Hashtable 与 HashMap类似,不同的是:它不允许记录的键或者值为空;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtale在写入时会比较慢。
  • LinkedHashMap 保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的。在遍历的时候会比HashMap慢。
  • TreeMap能够把它保存的记录根据键排序,默认是按升序排序,也可以指定排序比较器,当用Iterator遍历TreeMap时,得到的记录是排过序的。

容器类和Array的区别

  • 容器类仅能持有对象引用(指向对象的指针),而不是将对象信息copy一份至数列某位置。
  • 一旦将对象置入容器内,便损失了该对象的型别信息。

转自:http://seaizon.iteye.com/blog/571101#comments