黑马程序员-- 八、集合之概述

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

一、体系概述

Java集合类是一个很有用的工具类,可以用于存储数量不等的多个对象,并可以实现常用数据结构,如栈、队列等。除此之外,Java集合还可用于保存具有映射关系的关联数组。Java集合大致可分为SetListMap三种体系,其中Set代表无序、不可重复的集合;List代表有序、可重复的集合;而Map则代表具有映射关系的的集合。从Java5以后,Java又增加了Queue体系集合,代表一种队列集合实现。

Java集合就像一种容器,可以存储多个对象。Java5之前,Java集合会丢失容器中所有对象的数据类型,把所有对象都当成Object类型处理;从Java5引进泛型以后,Java集合可以记住容器中对象的类型,从而可以简化代码编写。

集合与数组的不同:

1、 数组虽可以存储对象,但长度是固定的;集合长度可变。

2、 数组可以存储基本数据类型;而集合只能存储对象。

3、 数组只能存储同一类型对象,而集合可以存储不同类型对象。


二、CollectionIterator接口

1Collection接口

Collection接口是ListSet、和Queue接口的父接口。Collection接口里面定义了如下操作结合元素的方法:

——boolean add(Object o)向集合里添加一个元素。添加成功则返回true

——boolean addAll(Collection c)c里面所有元素添加到指定集合。添加成功返回true

——void clear()清除集合里面的所有元素。

——boolean contains(Object o)返回集合是否包含指定元素o

——boolean containsAll(Collection c)返回集合是否包含集合成c里面的所有元素。

——boolean isEmpty()返回集合是否为空。

——Iterator iterator()返回一个Iterator对象。

——boolean remove(Object o)删除指定元素o,当集合中包含一个或多个元素o时,o将被删除,并返回true

——boolean removeAll(Collection c)从集合里删除集合c所包含的所有元素,如果删除了一个或一个以上元素,返回true

——boolean retainAll(Collection c)从集合中删除集合c不包含的所有元素,如果改变了原集合,则返回true

——int size()返回集合元素个数。

——Object[] toArray()将集合转成数组。

2Iterator接口

该接口主要用于遍历集合中的元素,也被称为迭代器。该接口定义了如下三个方法:

——boolean hasNext()如果被迭代的集合元素还没有被遍历,则返回true

——Object next()返回集合里的限一个元素。

——void remove()删除集合里上一次next方法返回的元素。

三、List集合

1List接口和ListIterator接口

List集合相对于Coolection接口增加了一些根据索引来操作集合元素的方法:

——void add(int index, Object element)将元素element插入到集合的index处。

——boolean addAll(int index, Collection c)将集合c中的所有元素添加到Index处。

——Object get(int index)返回集合index索引处的元素。

——int indexOf(Object o)返回o对象第一次出现在集合中的位置。

——Object remove(int index)删除并返回index处的元素。

——Object set(int index , Object element)index处的对象替换成element,并返回新元素。

——List subList(int fromIndex,int toIndex)返回从索引fromIndex(包含)到toIndex(不包含)处所有集合元素组成的子集合。

 

ListIterator接口:

List提供了一个listIterator()方法,返回一个ListIterator对象,ListIterator接口继承了Iterator接口,它额外提供了如下方法:

——boolean hasPrevious()返回集合是否还有上一个元素。

——Object previous()返回上一个元素。

——void add()在指定位置插入一个新元素。

 

2ArrayListVector实现类

List接口有三个典型实现类:ArrayListVectorLinkedList

其中,ArrayListVector底层数据结构都是数组,因而查询速度快,增删慢;而LinkedList底层是链表数据结构,它的查询速度慢但增删速度较快。另对于ArrayListVector而言也有不同,前者线程不安全,但效率高,后者线程安全但效率低,现在已基本被ArrayList取代。

LinkedList既实现了List接口,也实现了Deque接口,由于后者,因此可以作为栈来使用。

3Array.ArrayList内部类

操作数组的工具类Arrays提供了一个asList(Object… a)方法,该方法可以把一个数组或指定数量的对象转成一个List集合,这个List集合既不是ArrayList实现类的实例,也不是Vector的实例,而是Arrays的内部类ArrayList的实例。

Arrays.ArrayList是一个固定长度的List集合,程序只能遍历访问该集合里的元素,不可增加、删除操作。如果试图进行增删操作,则会引发UnsupportedOperationException异常。

 

四、Queue集合

Queue用于模拟队列这种数据结构。新元素插入(offer)到队列尾部,访问元素(poll)操作会返回队列头部元素。通常,队列不允许随机访问队列中的元素。Queue接口定义了如下几个方法:

——void add(Object e)将指定元素添加到队列尾部。

——Object element()获取队列头部的元素,但不删除。

——boolean offer(Object o)将指定元素添加到队列尾部。当使用有容量限制的队列时,此种方法较add方法更好。

——Object peek()获取队列头部的元素,但不删除。如果队列空,返回null

——Object poll()获取队列头部的元素,并删除。如果队列空,返回null

——Object remove()获取队列头部的元素,并删除。

1PriorityQueue实现类

PriorityQueue实现类保存队列的顺序并不是按加入队列的顺序,而是按队列元素大小进行重新排序。因此,当调用peek()方法或poll()方法取出元素时,并不是取出最先进入队列的元素,而是取出最小的元素。

Tips

如果直接输出整个队列,会发现并不是按从小到大的顺序排列,那是因为受到toString方法的返回值影响。

PriorityQueue不允许插入null元素,它还需要对队列元素进行排序,有两种方式:

——自然排序:采用此种方式排序的集合必须实现了Comparable接口,而且应该是同一个类的多个实例,否则可能导致ClassCastException异常。

——定制排序:创建队列时,传入一个Comparator对象,该对象负责对队列中元素进行排序。此时不要求队列实现Comparable接口。

2Deque接口与ArrayDeque实现类

Deque接口是Queue的字接口,它代表一个双端队列,主要方法有如下一些:

——void addFirst(Object e):将元素插入到双端队列开头。

——void addLast(Object e):将元素插入到双端队列结尾。

——Iterator descendingIterator():返回一个迭代器,该迭代器将以逆向顺序来迭代队列元素。

——Object getFirst():获取但不删除第一个元素。

——Object getLast():获取但不删除最后一个元素。

——boolean offerFirst(Object e)将元素插入到双端队列开头。

——boolean offerLast(Object e)将元素插入到双端队列结尾。

……

Deque接口提供了一个典型的实现类:ArrayDeque,它是一个基于数组实现的双端队列,创建Deque时可以指定一个numElements参数,该参数用于指定Object[] 数组的长度;如果不指定numElements参数,Deque底层数组长度为16

3LinkedList实现类

LinkedListList集合的实现类,意味着它可以根据索引来随机访问集合中的元素。除此之外,它还实现了Deque接口,意味着它可以被当作双端队列来使用,自然也可以被当作栈来使用。

例:

import java.util.LinkedList;

 

public class LinkedListDemo {

public static void main (String[] args)

{

LinkedList<String> books = new LinkedList<String>();

//将字符串添加到队列尾部

books.offer("三国演义");

//将字符串添加到栈的顶部

books.push("水浒传");

//将字符串添加到队列头部(相当于栈的顶部)

books.offerFirst("红楼梦");

for(int i = 0; i < books.size(); i++)

{

System.out.println(books.get(i));

}

//访问但不删除栈顶元素

System.out.println(books.peekFirst());

//访问但不删除队列的最后一个元素

System.out.println(books.peekLast());

//将栈顶的元素弹出栈

System.out.println(books.pop());

//访问并删除队列的最后一个元素

System.out.println(books.pollLast());

//此时队列中只剩下一个元素水浒传

System.out.println(books);

}

}

4各种线性表的性能分析

Java提供的List就是一个线性表接口,而ArrayListLinkedList又是线性表的两种典型实现类:基于数组的线性表和基于链的线性表。

下面对各种实现类性能进行分析:

 

实现机制 

随机访问排名

迭代操作排名

插入操作排名

删除操作排名

数组

连续内存区保存

1

不支持

不支持

不支持

ArrayList/ArrayDeque

以数组保存

2

2

2

2

Vector

以数组保存

3

3

3

3

LinkedList

以链表保存

4

1

1

1

 

Tips

如果运行程序时,JVM默认的存储空间不足以运行,可以采用如下命令改变JVM内存大小:

java –Xms128m –Xmx512m java源文件名.java

//-Xms是设置JVM的堆内存初始大小

//-Xmx 是设置JVM的堆内存最大大小

 

Tips

关于使用List集合有如下建议:

——如需遍历List集合,对于ArrayListVector集合,应该采用随机访问方法get()来遍历,这样性能更好;对于LinkedList集合,则应该采用迭代器Iterator来遍历集合元素。

——如果需要经常执行插入、删除操作来改变List集合大小,则应该使用LinkedList集合。

——如果有多个线程需要同时访问List集合中的元素,可考虑使用Collections将集合包装成线程安全的集合。



---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值