java集合框架

来源:互联网 发布:ubuntu怎样设置中文 编辑:程序博客网 时间:2024/06/03 15:29

java集合框架

集合的概念

通常情况下,把具有相同性质的一类东西,汇聚成一个整体,就可以称为集合。比如,用Java编程的所有程序员,全体中国人等。通常集合有两种表示法,一种是列举法,比如集合A={1,2,3,4},另一种是性质描述法,比如集合B={X|0<X<100X属于整数}

集合框架的概念

那么有了集合的概念,什么是集合框架呢?集合框架是为表示和操作集合而规定的一种统一的标准的体系结构。任何集合框架都包含三大块内容:对外的接口、接口的实现和对集合运算的算法。

接口:即表示集合的抽象数据类型。接口提供了让我们对集合中所表示的内容进行单独操作的可能。

实现:也就是集合框架中接口的具体实现。实际它们就是那些可复用的数据结构。

算法:在一个实现了某个集合框架中的接口的对象身上完成某种有用的计算的方法,例如查找、排序等。这些算法通常是多态的,因为相同的方法可以在同一个接口被多个类实现时有不同的表现。事实上,算法是可复用的函数。如果你学过C++,那C++中的标准模版库(STL)你应该不陌生,它是众所周知的集合框架的绝好例子。

集合框架体系

常用集合接口及其描述

Java 集合框架提供了一套性能优良,使用方便的接口和类,java集合框架位于java.util包中,所以当使用集合框架的时候需要进行导包。

1.Collection 接口: 是最基本的集合接口,一个 Collection代表一组 ObjectJava不提供直接继承自Collection的类,只提供继承于的子接口(Listset)

2. List 接口:是一个有序的Collection,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,而且允许有相同的元素。

3. SetSet具有与 Collection完全一样的接口,只是行为上不同,Set不保存重复的元素。

4. Map:将唯一的键映射到值。

注意:SetList的区别

1.     Set接口实例存储的是无序的,不重复的数据。List接口实例存储的是有序的,可以重复的元素

2.     Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>

3.     List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector> 

常用集合实现类

Java提供了一套实现了Collection接口的标准集合类。其中一些是具体类,这些类可以直接拿来使用,而另外一些是抽象类,提供了接口的部分实现。

 

1.     LinkedList:该类实现了List接口,允许有null(空)元素。主要用于创建链表数据结构,该类没有同步方法,如果多个线程同时访问一个List,则必须自己实现访问同步,解决方法就是在创建List时候构造一个同步的ListLinkedList数据查找效率低,但在数据的插入和删除效率高。

2.     ArrayList:该类也是实现了List的接口,实现了可变大小的数组,随机访问和遍历元素时,提供更好的性能。该类是非同步的,在多线程的情况下不要使用。ArrayList增长当前长度的50%,插入删除效率低。

3.     Vector :该类和ArrayList非常相似,但是该类是同步的,可以用在多线程的情况,该类允许设置默认的增长长度,默认扩容方式为原来的2倍。

注:ArrayListVector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许直接序号索引元素,但是插入数据要设计到数组元素移动等内存操作,所以索引数据快插入数据慢,Vector由于使用了synchronized方法(线程安全)所以性能上比ArrayList要差,LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可,所以插入数度较快!

可以这样说:当操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能;当你的操作是在一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。

 

ArrayListLinkedList的区别:

(1)    数据结构方面:ArrayList基于动态数组,LinkedList基于链表。

(2)    随记访问方面:ArrayList优于LInkedList

(3)    数据的新增和删除方面:在ArrayList的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList的中间插入或删除一个元素的开销是固定的。

(4)    存储空间:ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间。

 

ArrayList Vector的区别:

(1)         同步性方面:Vector是线程安全的,也就是说它的方法之间是线程同步的,而ArrayList是线程不安全的,它的方法之间不同步的。如果只有一个线程会访问到集合,那最好是使用ArrayList因为它不考虑线程安全,效率高。如果有多个线程会访问到集合,那最好是使用Vector,因为不需要我们自己再去考虑和编写线程安全的代码。

(2)         数据增长方面:ArrayListVector初始的容量大小为10,当存储进他们里面的元素个数超过了容量时,就需要增加ArrayListVector的存储空间,每次要增加存储空间时,不是只增加一个存储单元,而是增加多个存储单元,每次增加的存储单元的个数在内存空间利用与程序效率之间要取的一定的平衡。Vector默认增加为原来的两倍,而ArrayList默认为 1.5倍,ArrayListVector都可以设置初始的空间大小,Vector还可以设置增长的空间大小,而Arraylist没有设置增长空间的方法。

4.     TreeSet:该类实现了Set接口,引用了红黑树的数据结构,在存放时按照元素的自然顺序进行存放,元素不允许重复,在进行对象存放时会进行比较。

 

5.     HashSet:该类实现了Set接口,不允许出现重复元素,不保证集合中元素的顺序,允许包含值为null的元素,但最多只能一个。HashSet在存入数据时会对存入的数据进行比较,它会先使用hashcode方法(hashCode方法继承自Object类。每个对象在创建的时候会被分配一个唯一的hashcode值(一个整形的值)。所以不重写hashCode方法的话,两个对象的hashcode值是不会相同的),在使用equels方法。Hashcode值不等则元素不重复。hashcode相等,equels不等则元素不重复。hashcode相等,equels也相等则元素重复。只能在相等元素里面存进去一个元素。如果两元素重写了hashcodeequels方法则两元素一定相等,在重写equels时,一定要重写hashcode方法,否则会报错。

6.     HashMap :HashMap实现了Map接口,根据键的HashCode值存储数据,具有很快的访问速度,最多允许一条记录的键为null,不支持线程同步。HashMap是一个散列表,它存储的内容是键值对(key-value)映射。K值不能重复,V值可以重复,若K值重复,后面的数据会把前面的数据覆盖掉。在使用时可以通过set <数据类型> keyset = Hashmap.keyset();来得到键的集合。通过collection <数据类型> values = Hashmap.values();来得到值得集合。

HashMapHashSet的区别:

(1)    实现方面:HashMap实现了Map接口而HashSet实现了Set接口。

(2)    存储方面:HashMap存入的是键值对而HashSet仅仅存入值。

(3)    添加元素的方法:HashMap使用put()方法存入元素而HashSetadd()方法存入元素。

(4)    判断重复的方式:HashMap中使用键对象来计算hashcode值。HashSet使用成员对象来计算hashcode值,对于两个对象来说hashcode可能相同,所以equals()方法用来判断对象的相等性,如果两个对象不同的话,那么返回false

(5)    获取数据的速度:HashMap比较快,因为是使用唯一的键来获取对象。HashSetHashMap来说比较慢。

ArrayList的遍历

ArrayList的遍历有三种方式

1.      加强for循环(foreach)


2.      迭代器(iterator)


3.      把链表变为数组相关的内容进行遍历


Map的遍历

Map的遍历方式有四种

1.      通过Map.keySet遍历key和value


2.      通过Map.entrySet使用iterator遍历keyvalue


3.      通过Map.entrySet遍历keyvalue


4.      通过Map.values()遍历所有的value,但不能遍历key


迭代器模式

提供一种方法顺序访问一个集合对象的各个元素,而又不暴露对象的内部结构,实现Collection接口的所有集合都可以有一个指向它自己的迭代器,实现Collection接口的所有集合都可以使用迭代器进行遍历。