概述
java.util包中提供了一些集合类,这些集合类又被称为容器。对象用于封装特有数据,对象多了需要存储,但是如果对象的个数不确定,就使用集合容器进行存储。
集合类的特点(与数组的区别)
1.用于存储对象的容器,所有存储的对象在存入的时候会自动提升为Object类型;
2.集合的长度是可变的;
3.集合中不可以存储基本数据类型,但是在jdk1.5版本之后,基本数据类型会自动装箱为对象。
集合容器因为内部的数据结构不同,有多种具体容器。将它们不断向上抽取,就形成了集合体系。该框架的顶层之一就是Collection接口。最终使用的时候,其实使用的是该框架最子类的对象。
Collection接口
Collection接口中的常见方法:
1.添加
boolean add(Object e)
boolean addAll(Collection coll);
2.删除
boolean remove(Object obj)
boolean removeAll(Collection coll)
void clear(); 清空
3.判断
boolean contains(Object obj)
boolean ContainsAll(Collection coll)
boolean isEmpty();判断是否有元素size=0
4.获取
int size();
取出集合中元素的方式:迭代器
Iterator iterator();
5.其他
boolean retainAll(Collection coll);取交集
Object toArray();将集合转为数组
public class CollectionDemo {
public static void main(String[] args) {
Collection coll=new ArrayList();
Collection c1=new ArrayList();
Collection c2=new ArrayList();
show(c1,c2);
}
public static void show(Collection c1,Collection c2){
//给c1添加元素
c1.add("a1");
c1.add("a2");
c1.add("a3");
c1.add("a4");
//给c2添加元素
c2.add("a1");
c2.add("a2");
c2.add("b3");
c2.add("b4");
System.out.println("c1:"+c1);//c1:[a1, a2, a3, a4]
System.out.println("c2:"+c2);//c2:[a1, a2, b3, b4]
//演示addAll
c1.addAll(c2);
System.out.println("c1:"+c1);//c1:[a1, a2, a3, a4, a1, a2, b3, b4]
//演示removeAll
boolean b=c1.removeAll(c2);
System.out.println("removeAll:"+b);//removeAll:true
System.out.println(c1);//[a3, a4]
//演示containsAll
boolean d=c1.containsAll(c2);
System.out.println("containsAll:"+d);//containsAll:false
//演示retainAll
c1.add("a2");
boolean e=c1.retainAll(c2);//取交集,保留和指定的集合相同的元素,而删除不同的元素
//和removeAll功能相反
System.out.println("c1:"+c1);//c1:[a2]
}
}
迭代器Iterator
Iterator接口将每一个容器中的取出方式进行了封装,并对外暴露。只要内部取出方式实现了Iterator接口,无论是什么容器或者数据结构都可以通过该接口取出这些容器中的元素(取出的是对象元素的引用)。通过iterator()方法获取到迭代器迭代器对象。迭代器将容器的取出方式和容器的数据结构分离,降低了耦合性。
public class IteratorDemo {
public static void main(String[] args) {
Collection coll =new ArrayList();
coll.add("abc1");
coll.add("abc2");
coll.add("abc3");
coll.add("abc4");
//使用了Collection中的Iterator()方法。调用集合中的迭代器方法,是为了获取集合中的迭代器对象
Iterator it=coll.iterator();//这个对象不用new,本身内置于该接口中。
while(it.hasNext()){
System.out.println(it.next());
}
//将while改成for结构,这种方式for循环结束it对象消失,可以不占内存
/* for(Iterator it = coll.iterator(); it.hasNext(); ){
System.out.println(it.next());
}*/
}
}
List集合
List集合包括List接口以及List接口的所有实现类。List集合中的元素允许重复,各元素就是对象插入的顺序。类似于Java数组,用户可以通过索引(元素在集合中的位置)来访问集合中的元素。
List接口继承了Collection接口,因此也包含了Collection中的所有方法。此外,List接口还有以下特有的方法(特有方法有一个共性特点就是都可以操作角标):
1.添加
void add(index,element);
void add(index,collection);
2.删除
Object remove(index);
3.修改
Object set(index,element);
4.获取
Object get(index);
int indexOf(object)
int lastIndexOf(object);
List subList(intfrom,intto);包含头不包含尾
List接口的常见实现类:
Vector:内部是数组数据结构(可变),是同步的。增删查询都很慢。(可变数组,延长100%)
ArrayList:内部是数组数据结构,是不同步的,替代了Vector。允许保存所有元素,包括null。查询速度很快。(可变数组,延长50%)
LinkedList:内部是链表数据结构,是不同步的。增删元素的速度很快。
List接口方法的演示:
public class ListDemo {
public static void main(String[] args) {
List list=new ArrayList();
show(list);
}
public static void show(List list) {
//添加元素
list.add("abc1");
list.add("abc2");
list.add("abc3");
System.out.println(list);//[abc1, abc2, abc3]
//插入元素
list.add(1,"abc9");
System.out.println(list);//[abc1, abc9, abc2, abc3]
//删除元素
System.out.println("remove:"+list.remove(2));//remove:abc2
System.out.println(list);//[abc1, abc9, abc3]
//修改元素
System.out.println("set:"+list.set(1,"avc8"));//set:abc9
System.out.println(list);//[abc1, avc8, abc3]
//获取元素
System.out.println("get:"+list.get(0));//get:abc1
System.out.println(list);//[abc1, avc8, abc3]
//获取子列表
System.out.println("sublist:"+list.subList(1,3));//sublist:[avc8, abc3]
System.out.println(list);//[abc1, avc8, abc3]
Iterator it=list.iterator();
while(it.hasNext()){
System.out.println("next:"+it.next());
}
//List特有的取出方式
for(int x=0;x<list.size();x++){
System.out.println("get:"+list.get(x));
}
}
}
列表迭代器ListIterator
注意:集合和迭代器同时(并发)在操作数据(迭代器获取元素,集合在添加元素),就会引发异常。因此在迭代过程中,不要使用集合操作元素。可以使用Iterator接口的子接口ListIterator来完成在迭代中对元素进行更多的操作。
举例说明:
public class ListDemo_2 {
public static void main(String[] args) {
List list=new ArrayList();
list.add("abc1");
list.add("abc2");
list.add("abc3");
/* Iterator it=list.iterator();
while(it.hasNext()){//--集合和迭代器同时(并发)在操作数据(迭代器获取元素,集合在添加元素),就会引发异常
//在迭代过程中,不要使用集合操作元素。
//可以使用Iterator接口的子接口ListIterator来完成在迭代中对元素进行更多的操作
//java.util.ConcurrentModificationException
Objectobj=it.next();
if(obj.equals("abc2")){
list.add("abc9");
}
else
System.out.println("next:"+obj);
}
System.out.println(list); */
System.out.println(list);//[abc1, abc2, abc3]
ListIterator it =list.listIterator();//获取列表迭代器
//它可以实现在迭代过程中对元素的增删改查
//注意:只有list结合具备该功能
while(it.hasNext()){
Object obj=it.next();
if(obj.equals("abc2")){
it.add("abc4");
//it.set("abc9");
}
}
System.out.println(list);//[abc1, abc2, abc4, abc3]
System.out.println("hasNext:"+it.hasNext());//hasNext:false
System.out.println("hasPrevious:"+it.hasPrevious());//hasPrevious:true
while(it.hasPrevious()){
System.out.println("previous:"+it.previous());
}
//previous:abc3
//previous:abc4
//previous:abc2
//previous:abc1
}
}
vector类代码演示:
public class VectorDemo {
public static void main(String[] args) {
Vector v=new Vector();
v.addElement("abc1");
v.addElement("abc2");
v.addElement("abc3");
//此接口的功能与Iterator接口的功能是重复的。
//此外,Iterator接口添加了一个可选的移除操作,并使用较短的方法名。
//优先考虑使用Iterator接口。
Enumeration en=v.elements();
while(en.hasMoreElements()){
System.out.println("nextelement:"+en.nextElement());
}
Iterator it=v.iterator();
while(it.hasNext()){
System.out.println("next:"+it.next());
}
}
}
LinkedList类的常见方法:
addFirst();
addLast();
jdk1.6后
offerFirst();
offerLast();
getFirst();//获取但不移除,如果链表为空,抛出NoSuchElementException异常
getLast();
jdk1.6后
peekFirst(); //获取但不移除,链表为空时不抛出异常而是返回null
peekLast();
removeFirst();//获取并移除,如果链表为空,抛出NoSuchElementException异常
removeLast();
jdk1.6后
pollFirst();//获取并移除,链表为空时不抛出异常而是返回null
pollLast()
LinkedList类方法的代码演示:
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList link=new LinkedList();
link.addFirst("abc1");
link.addFirst("abc2");
link.addFirst("abc3");
link.addFirst("abc4");
link.addLast("abc5");
System.out.println(link);//[abc4, abc3, abc2, abc1, abc5]
// Iterator it=link.iterator();
// while(it.hasNext()){
// System.out.println(it.next());
// }
System.out.println(link.getFirst());//获取第一个但不删除
System.out.println(link.getLast());
System.out.println(link.removeFirst());//获取元素且删除
System.out.println(link.removeFirst());
System.out.println(link);
while(!link.isEmpty()){
System.out.println(link.removeFirst());
}
System.out.println(link);
}
}
LinkedList类示例二:使用LinkedList来模拟一个堆栈或者队列数据结构。
/*
请使用LinkedList来模拟一个堆栈或者队列数据结构
堆栈:先进后出First In Last Out FILO
队列:先进先出First In Last Out FIFO
我们应该描述这样一个容器,给使用者提供一个容器对象完成这两种结构其中的一种。
*/
/*LinkedTest.java*/
public class LinkedTest {
public static void main(String[] args) {
MyQueue q1=new MyQueue();
q1.myAdd("abc1");
q1.myAdd("abc2");
q1.myAdd("abc3");
q1.myAdd("abc4");
while(!q1.isNull()){
System.out.println(q1.myGet());
}
}
}
/*MyQueue.java*/
public class MyQueue {
private LinkedList link;
public MyQueue(){
link=new LinkedList();
}
/*队列的添加元素的功能*/
public void myAdd(Object obj){
link.addLast(obj);
}
/*获取*/
public Object myGet(){
return link.removeFirst();//堆栈改成removeLast
}
public boolean isNull(){
return link.isEmpty();
}
}