您的位置:首页 > 其它

集合一:Collection、Iterator、List、ArrayList、Vector、LinkedList

2014-02-21 13:00 337 查看

1  集合

1.1  集合概述

    集合是用来存储对象,并对多个对象进行操作的容器。

    集合和数组都可以存储对象,但集合长度是可变的,而数组长度是固定的。

    数组还可以存储基本数据类型,而集合只能存储对象。

    实际上存放的是对象的引用(内存地址)。

 

Java中的集合框架:



       

Collection接口有两个子接口:List和Set。

 

Collection

    |--List:元素是有序的,元素可以重复。因为该集合体系有索引。

        |--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度快,但是增删很慢。线程不同步

        |--LinkedList:底层使用的链表数据结构。特点:查询速度很慢,增删速度快。

        |--Vector:底层是数组数据结构。功能与ArrayList相同,但是线程同步。被ArrayList替代(多线程加锁)

    |--Set:元素是无序的,元素不可以重复。无序:存入和取出的顺序不一定一致。

        |--HashSet:数据结构是哈希表,线程是非同步的。保证元素唯一性的原理:判断元素的hashCode值是否相同。如果相同,还会继续判断元素的equals()方法,是否为true。

        |--TreeSet:可以对Set集合中的元素进行排序,底层数据结构是二叉树。保证元素唯一性的依据:compareTo()方法的return 返回值是0,即: return 0;

 

1.2  集合Collection共性方法

    1,boolean add(e):

        将指定的元素添加到此列表的尾部,即添加一个对象到集合尾部,e是要添加到此列表中的元素(任意类型),返回true。

    2,boolean remove(Object o):

        移除此列表中首次出现的指定元素(如果存在)。如果此列表包含指定的元素,则返回true。

    3,void clear():

        移除此列表中的所有元素。

    4,int size():

        返回此列表中的元素数,即集合中对象的个数。

    5,boolean contains(Object o):

        如果此列表中包含指定元素,则返回true,即如果此集合中包含o这个元素,则返回true。

    6,boolean isEmpty():

        如果此列表没有元素,返回true,即是个空的集合,返回true。

    7,boolean retainAll(Collection c):

        移除当前集合中未包含在集合c中的所有元素,取交集。如果当前集合因为调用发生更改,则返回true。

    8,boolean removeAll(Collection c):

        移除当前集合中,两个集合的交集,即去掉交集。如果当前集合因为调用发生更改,则返回true。

    9,boolean containsAll(Collection c):

        如果当前集合包含集合c中的所有元素,则返回true。

    10,boolean addAll(Collection c):

        将集合c添加到当前集合的尾部,如果当前集合因为调用发生更改,则返回true。

 

1.3  迭代器Iterator

    什么是迭代器呢?

    其实就是集合的取出元素的方式,用来操作集合。

    Iterator<T> iterator();

    Iterator接口:把取出方式定义在集合的内部,这样取出方式就可以直接访问集合内容的元素,那么取出方式就被定义成了内部类。

    而每一个容器的数据结构不同,所以取出的动作细节也不一样,但是都有共性内容(判断和取出),把共性内容封装为Iterator接口。

    那么如何获取集合的取出对象呢? 通过一个对外提供的方法 iterator();

    Iterator it = collection.iterator();

    boolean hasNext();

    Object next();

    void remove();

 

     集合共性方法和迭代器示例:

import java.util.*;

class CollectionDemo{
public static void main(String[] args){
method_3();
}

public static void sop(Object obj){
System.out.println(obj);
}

public static void method_1(){
//创建一个集合容器,使用Collection接口的子类。ArrayList
ArrayList al = new ArrayList();

//1,添加元素
al.add("java01"); //add(Object obj);
al.add("java02");
al.add("java03");
al.add("java04");

//打印原集合
sop(al);

//3,删除元素
al.remove("java02");
al.clear(); //清空集合

//4,判断元素
sop("java03是否存在:"+al.contains("java03"));
sop("集合是否为空:"+al.isEmpty());

//2,获取个数,集合长度。
sop("size=:"+al.size()); //集合的size()代替了length(),获取长度

sop(al);
}

public static void method_2(){
ArrayList al1 = new ArrayList();
al1.add("java01");
al1.add("java02");
al1.add("java03");
al1.add("java04");

ArrayList al2 = new ArrayList();
al2.add("java03");
al2.add("java04");
al2.add("java05");
al2.add("java06");

al1.retainAll(al2); //取交集,al1中只会保留和al2中相同的元素。
sop("al1:"+al1);
sop("al2:"+al2);
}

public static void method_3(){  //迭代器
ArrayList al3 = new ArrayList();
al3.add("java01");
al3.add("java02");
al3.add("java03");
al3.add("java04");

Iterator it = al3.iterator();
while(it.hasNext()){
sop(it.next());
}
/* 节约内存的写法,循环结束 it对象即消亡
for(Iterator it = al3.iterator(); it.hasNext(); ){
sop(it.next());
} */
}
}

2  List集合

    List是Collection接口的一个子接口,List集合也是集合的一种。

 

    |--List:元素是有序的,元素可以重复。因为该集合体系有索引。

        |--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度快,但是增删很慢。线程不同步。

        |--LinkedList:底层使用的链表数据结构。特点:查询速度很慢,增删速度快。

        |--Vector:底层是数组数据结构。功能与ArrayList相同,但是线程同步。被ArrayList替代(多线程加锁)。

 

2.1  List集合的特有方法

    List集合特有方法:凡是可以操作脚标index的方法都是该体系特有的方法。

 

    增:

    add(index,element):在集合的index位置(脚标)添加元素。

    addAll(index,Collection):在集合的index位置(脚标)添加一个集合。

    删:

    remove(index):删除集合中位置index上的元素。

    改:

    set(index,element):修改集合index位置上的元素为element。

    查:

    get(index):获取指定位置上的元素。

    subList(from,to):获取从from位置到(to-1)位置上的子集合,包括首不包括尾。

    listIterator():获取ListIterator迭代器,ListIterator是Iterator的子接口,是List集合特有的迭代器。

 

2.2  List集合特有迭代器ListIterator

    List集合特有的迭代器,ListIterator是Iterator的子接口。

    在迭代时,不可以通过集合对象的方法操作集合中的元素,因为会发生并发修改异常:ConcurrentModificationException。

    所以在迭代时,只能用迭代器的方法操作元素,可是Iterator的方法是有限的,只能对元素进行判断、取出、删除的操作。

    如果想要其他的操作如添加、修改等,就需要使用其子接口,ListIterator。

    该接口只能通过List集合的listIterator方法获取。

 

     List集合特有方法的代码示例:

import java.util.*;
class ListDemo{
public static void main(String[] args){
method_ListIterator();
}

public static void sop(Object obj){
System.out.println(obj);
}

public static void method(){
ArrayList al1 = new ArrayList();  //创建集合容器
al1.add("java01");  //添加元素
al1.add("java02");
al1.add("java03");
al1.add("java04");
sop("原集合是:"+al1);

al1.add(1,"java05"); //增:在指定位置添加元素
al1.remove(2);  //删:删除指定位置的元素
al1.set(2,"java007"); //改:修改元素
sop(al1);

sop("get(1):"+al1.get(1));//查:获取指定元素
for(int x=0; x<al1.size(); x++){  //获取全部元素
sop("al1("+x+"):"+al1.get(x));
}
for(Iterator it=al1.iterator(); it.hasNext(); ){  //迭代获取全部
sop(it.next());
}

//通过indexOf()获取对象的位置
sop("java007位置:"+al1.indexOf("java007"));
List sub = al1.subList(1,3); //包括首,不包括尾
sop("sub:"+sub);
}

public static void method_Iterator(){
ArrayList al2 = new ArrayList();  //创建集合容器
al2.add("java01");  //添加元素
al2.add("java02");
al2.add("java03");
sop("原集合是:"+al2);

Iterator it = al2.iterator();
while(it.hasNext()){
Object obj = it.next();
if(obj.equals("java02"))
//al2.add("java08");  并发异常,集合和迭代器不能同时操作
it.remove(); //将java02的引用从集合中删除了,但对象还在内存中
sop("obj="+obj);
}
sop(al2);
}

public static void method_ListIterator(){
ArrayList al3 = new ArrayList();  //创建集合容器
al3.add("java01");  //添加元素
al3.add("java02");
al3.add("java03");
sop("原集合是:"+al3);

ListIterator li = al3.listIterator(); //获取ListIterator迭代器。
while(li.hasNext()){
Object obj = li.next();
if(obj.equals("java02"))
li.add("java008"); //set,remove
}
sop(al3);
}
}

2.3  ArrayList集合

     ArrayList集合底层的数据结构使用的是数组结构。

     特点:查询速度快,但是增删很慢。

     ArrayList是线程不同步。

     ArrayList拥有Collection集合中的共性方法,以及List集合的特有方法。

 

     代码示例可以参考本文第一段代码Demo。

 

2.4  Vector集合

     Vector类是List接口的子类,当然也实现了集合Collection接口。

     Vector集合的底层数据结构是数组。功能与ArrayList相同,但是Vector线程同步。

     可以被ArrayList替代(多线程加锁后)。

 

     Vector中的枚举:

     枚举就是Vector特有的取出方式。

     枚举和迭代器很像,其实枚举和迭代器是一样的。

     因为枚举的名称以及方法的名称都过长,所以被迭代器取代了。

     (优先考虑Iterator接口,而不是Enumeration。)

 

     Vector代码示例:

import java.util.*;
class VectorDemo{
public static void main(String[] args){
Vector v = new Vector();
v.add("java01");
v.add("java02");
v.add("java03");
v.add("java04");

Enumeration en = v.elements();  //Vector的elements方法返回一个枚举
while(en.hasMoreElements()){  //hasMoreElements是否有更多元素
System.out.println(en.nextElement()); //nextElement返回下一个元素
}
}
}

2.5  LinkedList集合

     LinkedList集合底层使用的是链表数据结构。

     特点:查询速度很慢,增删速度快。

     LinkedList集合特有方法:

          addFirst():在头部添加一个元素。

          addLast():在尾部添加一个元素。

 

          getFirst():get获取元素但不删除元素,获取列表第一个元素。

          getLast():获取列表末尾的元素。

          removeFirst():获取并且删除第一个元素。

          removeLast():获取并且删除最后一个元素。

          如果get、remove时,列表为空没有元素,抛出NoSuchElementException异常。

 

     在JDK1.6中出现了替代方法(替代列表为空时抛出异常):

          offerFirst():offer替代了add,在此列表的开头插入指定的元素。

          offerLast():在此列表末尾插入指定的元素。

          peekFirst():peek替代了get,获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。

          peekLast():获取但不移除此列表的最后一个元素;如果此列表为空,则返回 nul。

          pollFirst():poll替代了remove,获取并移除此列表的第一个元素;如果此列表为空,则返回 null。

          pollLast():获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。

          如果peek、poll时,列表为空没有元素,不再抛出异常,而是返回null。

 

LinkedList集合的代码示例:

import java.util.*;
class LinkedListDemo{
public static void main(String[] args){
LinkedList link = new LinkedList();
link.addLast("java01");
link.addLast("java02");
link.addFirst("java03");
link.addFirst("java04");
sop(link);

sop(link.getFirst());  //获取第一个元素
sop(link.getLast());
sop("size="+link.size());
sop(link.removeFirst());  //获取并删除第一个元素
sop("size="+link.size());

while(!link.isEmpty()){  //使用LinkedList特有方法,相当于迭代器Iterator
sop(link.removeFirst());
}
}

public static void sop(Object obj){
System.out.println(obj);
}
}

3  集合的小练习

3.1  LinkedList集合的练习

     LinkedList集合的一个小练习,要求掌握。

     需求:使用LinkedList模拟一个堆栈或者队列数据结构。

     堆栈:先进后出。

     队列:先进先出。

 

     LinkedList练习的代码示例:

import java.util.*;
class LinkedListTest{
public static void main(String[] args){
DuiZhan d = new DuiZhan(); //堆栈
d.myAdd("java01");
d.myAdd("java02");
d.myAdd("java03");
d.myAdd("java04");
sop(d);

while(!d.isNull()){
sop(d.myGet());
}
}
public static void sop(Object obj){
System.out.println(obj);
}
}

class DuiLie{  //模拟队列,先进先出。
LinkedList link;
DuiLie(){
link = new LinkedList();
}
public void myAdd(Object obj){ //队列中在末尾添加元素。
link.addLast(obj);
}
public Object myGet(){  //队列中在头部删除元素。
return link.removeFirst();
}
public boolean isNull(){
return link.isEmpty();
}
}

class DuiZhan{  //模拟堆栈,先进后出。
LinkedList link;
DuiZhan(){
link = new LinkedList();
}
public void myAdd(Object obj){  //堆栈中在末尾添加元素。
link.addLast(obj);
}
public Object myGet(){    //堆栈中在末尾删除元素。
return link.removeLast(); //这里与队列不同
}
public boolean isNull(){
return link.isEmpty();
}
}

3.2  ArrayList集合的练习1

     需求:去除ArrayList集合中的重复元素。

     死路:定义一个新集合,遍历原集合的元素,如果新集合中没有此元素,则不重复,添加。如果新集合中已有此元素,则重复,不添加。

 

     代码示例:

import java.util.*;
class ArrayListTest{
public static void main(String[] args){
ArrayList al = new ArrayList();
al.add("java01");
al.add("java02");
al.add("java01");
al.add("java02");
al.add("java03");
sop(al);

al = singleElement(al); //去除重复元素
sop(al);

Iterator it = al.iterator();  //迭代循环中next调用一次,就要hasNext判断一次。
while(it.hasNext()){
sop(it.next());
//sop(it.next()+"..."+it.next()); //不能一次循环调用两次next();
}
}

public static void sop(Object obj){
System.out.println(obj);
}

public static ArrayList singleElement(ArrayList al){  //实现功能:去除重复元素
ArrayList newAl = new ArrayList();  //定义一个临时容器,存储结果集合

/* 如果新集合中没有此元素,则不重复,添加。
如果新集合中已有此元素,则重复,不添加。 */
Iterator it = al.iterator();
while(it.hasNext()){
Object obj = it.next();
if(!newAl.contains(obj))
newAl.add(obj);
}
return newAl;

}
}

3.3  ArrayList集合的练习2

     需求:将自定义对象作为元素存到ArrayList集合中,并去除重复元素。

     比如:存人对象。同姓名同年龄,视为同一个人,为重复元素。

     思路:

     1,对人进行描述,将数据封装进人对象。

     2,定义容器,将人存入。

     3,取出。

 

     注意:List集合判断元素是否相同,依据是元素的equals()方法,即Object父类的equals()方法,有时需要重写equals(),contains()、remove()都依赖equals()方法。

 

     代码示例(主要集合中的多态:add()中添加的是Object类型,如果要用自定义方法,需向下转型):

import java.util.*;
class ArrayListTest2{
public static void main(String[] args){
ArrayList al = new ArrayList();
al.add(new Person("lisi01",30)); //al.add(Object,obj); //Object obj = new Person("lisi01",30);
al.add(new Person("lisi02",32));
al.add(new Person("lisi02",32));
al.add(new Person("lisi03",36));
///sop(al);
al = singleElement(al); //去除重复元素

Iterator it = al.iterator();
while(it.hasNext()){
Object obj = it.next();
Person p = (Person)obj;  //next得到的是Object类型,向下转型为Person,才能调用Person自定义方法

sop(p.getName()+"..."+p.getAge());
}
}
public static void sop(Object obj){
System.out.println(obj);
}

public static ArrayList singleElement(ArrayList al){  //实现功能:去除重复元素
ArrayList newAl = new ArrayList();  //定义一个临时容器,存储结果集合

Iterator it = al.iterator();
while(it.hasNext()){
Object obj = it.next();

if(!newAl.contains(obj)) //Collection接口中contains()的原理就是equals();
newAl.add(obj);
}
return newAl;

}
}

class Person{
private String name;
private int age;
Person(String name,int age){
this.name = name;
this.age = age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public boolean equals(Object obj){  //重写equals(),自定义两个对象相同的规则,用来去重。
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
System.out.println(this.name+"..."+p.name);

return this.name.equals(p.name) && this.age == p.age;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息