Java基础之集合框架系列(二)

1.List集合共性方法

1.常用方法

List特有方法:

void add(int index, E element)
在列表的指定位置插入指定元素
boolean addAll(int index, Collection c)
将指定 collection 中的所有元素都插入到列表中的指定位置。

E remove(int index)
移除列表中指定位置的元素。

E set(int index, E element)
用指定元素替换列表中指定位置的元素。
E get(int index)
返回列表中指定位置的元素。

int indexOf(Object o)
返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。
int lastIndexOf(Object o)
返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回 -1。

ListIterator listIterator()
返回此列表元素的列表迭代器(按适当顺序)。
ListIterator listIterator(int index)
返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始。

List subList(int fromIndex, int toIndex)
返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。 (即集合的截取操作)

继承自Collecction的方法:

boolean add(E e)
向列表的尾部添加指定的元素

boolean addAll(Collection c)
添加指定 collection 中的所有元素到此列表的结尾,顺序是指定 collection 的迭代器返回这些元素的顺序

void clear()
从列表中移除所有元素(可选操作)。

boolean contains(Object o)
如果列表包含指定的元素,则返回 true。

boolean containsAll(Collection c)
如果列表包含指定 collection 的所有元素,则返回 true。

boolean equals(Object o)
比较指定的对象与列表是否相等。

int hashCode()
返回列表的哈希码值。

boolean isEmpty()
如果列表不包含元素,则返回 true。

Iterator iterator()
返回按适当顺序在列表的元素上进行迭代的迭代器。

boolean remove(Object o)
从此列表中移除第一次出现的指定元素(如果存在)(可选操作)。

boolean removeAll(Collection c)
从列表中移除指定 collection 中包含的其所有元素(可选操作)。

boolean retainAll(Collection c)
仅在列表中保留指定 collection 中所包含的元素(可选操作)。

int size()
返回列表中的元素数。

Object[] toArray()
返回按适当顺序包含列表中的所有元素的数组(从第一个元素到最后一个元素)。

T[] toArray(T[] a)
返回按适当顺序(从第一个元素到最后一个元素)包含列表中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。

2.示例程序

常见操作:

        //部分代码

        //创建List集合子类ArrayList对象
        ArrayList al=new ArrayList();

        //向集合中初始化添加对象
        al.add("demo1");
        al.add("demo2");
        al.add("demo3");

        System.out.println("初始集合:\n"+al);

        //演示获取指定位置元素
        String target=al.get(1);
        System.out.println("获取到的元素为:"+target);

        //演示向指定位置添加元素
        al.add(2,"demo_add");
        System.out.println("添加后的集合为:\n"+al);

        //演示移除指定位置的元素
        al.remove(3);
        System.out.println("进行移除操作后的集合为:\n"+al);

        //演示修改指定位置元素
        al.set(1, "demo_set");
        System.out.println("进行修改操作后的集合为:\n"+al);

        //演示获取指定元素索引
        int index=al.indexOf("demo_add");
        System.out.println("目标元素的索引为:"+index);

        //利用循环遍历的方式对集合元素进行取出
        for(int i=0;i"元素"+i+"为:"+al.get(i));
        }

程序运行结果:

初始集合:
[demo1, demo2, demo3]
获取到的元素为:demo2
添加后的集合为:
[demo1, demo2, demo_add, demo3]
进行移除操作后的集合为:
[demo1, demo2, demo_add]
进行修改操作后的集合为:
[demo1, demo_set, demo_add]
目标元素的索引为:2
元素0为:demo1
元素1为:demo_set
元素2为:demo_add

说明:以上程序使用ArrayList对集合List共性方法进行演示,其他List对象的使用方式与之类似

说明:由于list中元素有序,可以通过索引的方式获取List集合中的元素。因此list可以通过循环遍历的方式对元素进行取出,也可以通过迭代器的方式将元素进行取出,即list集合元素有两种取出方式。

2.ListIterator

使用场景

在用迭代器进行迭代操作时,不能通过集合对象的方法操作集合中的元素,否则会发生并发异常ConcurrentModificationException。因此,在迭代过程中只能使用迭代器的方法操作元素。考虑到iterator中的方法有限,List集合对象可以返回特有的迭代器ListIterator。该接口只能通过List集合的listIterator()方法获取。

ListIterator可以进行什么操作呢?

可以利用ListIterator迭代过程中对元素进行添加或删除操作

常用方法

void add(E e)
将指定的元素插入列表。

boolean hasNext()
以正向遍历列表时,如果列表迭代器有多个元素,则返回 true(换句话说,如果 next 返回一个元素而不是抛出异常,则返回 true)。

boolean hasPrevious()
如果以逆向遍历列表,列表迭代器有多个元素,则返回 true。 (用于逆向遍历)

E next()
返回列表中的下一个元素。
int nextIndex()
返回对 next 的后续调用所返回元素的索引。

E previous()
返回列表中的前一个元素。
int previousIndex()
返回对 previous 的后续调用所返回元素的索引。

void remove()
从列表中移除由 next 或 previous 返回的最后一个元素

void set(E e)
用指定元素替换 next 或 previous 返回的最后一个元素

说明:迭代器在迭代过程中对元素进行的操作(比如添加和删除),迭代后也会影响到被操作集合中的元素。因为迭代器获得的是对集合的引用。

3.List集合具体对象特性

1.ArrayList

ArrayList底层数据结构使用的是数组结构,并且是线程不同步的。查询修改速度很快,但是增删较慢。初始容量为10,在添加的过程中会动态增加容量。

构造方法:

ArrayList()
构造一个初始容量为 10 的空列表。
ArrayList(Collection c)
构造一个包含指定 collection 的元素的列表,且这些元素是按照collection 的迭代器返回它们的顺序进行排列的。
ArrayList(int initialCapacity)
构造一个具有指定初始容量的空列表。

特有方法:

protected void removeRange(int fromIndex, int toIndex)
移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素。

void trimToSize()
将此 ArrayList 实例的容量调整为列表的当前大小。

2.LinkedList

LinkedList底层数据结构使用的是链表结构,增删速度很快,查询稍慢。

构造方法:

LinkedList()
构造一个空列表。
LinkedList(Collection c)
构造一个包含指定 collection 中的元素的列表,这些元素按其 collection 的迭代器返 回的顺序进行排列。

特有方法:

void addLast(E e)
将指定元素添加到此列表的结尾。

Iterator descendingIterator()
返回以逆向顺序在此双端队列的元素上进行迭代的迭代器。

E element()
获取但不移除此列表的头(第一个元素)。

E getFirst()
返回此列表的第一个元素。如果集合中没有元素,会出现NoSuchElementException
E getLast()
返回此列表的最后一个元素。如果集合中没有元素,会出现NoSuchElementException

E removeFirst()
移除并返回此列表的第一个元素。如果集合中没有元素,会出现NoSuchElementException
E removeLast()
移除并返回此列表的最后一个元素。如果集合中没有元素,会出现NoSuchElementException

boolean removeFirstOccurrence(Object o)
从此列表中移除第一次出现的指定元素(从头部到尾部遍历列表时)。

boolean removeLastOccurrence(Object o)
从此列表中移除最后一次出现的指定元素(从头部到尾部遍历列表时)。

JDK1.6后出现的新方法:

boolean offer(E e)
将指定元素添加到此列表的末尾(最后一个元素)。
boolean offerFirst(E e)
在此列表的开头插入指定的元素。
boolean offerLast(E e)
在此列表末尾插入指定的元素。

E peek()
获取但不移除此列表的头(第一个元素)。
E peekFirst()
获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。
E peekLast()
获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。

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

E pop()
从此列表所表示的堆栈处弹出一个元素。

void push(E e)
将元素推入此列表所表示的堆栈。

3.Vector

Vector底层是数组数据结构,且是线程同步的

1.相关方法

构造方法:

Vector()
构造一个空向量,使其内部数据数组的大小为 10,其标准容量增量为零。
Vector(Collection c)
构造一个包含指定 collection 中的元素的向量,这些元素按其 collection 的迭代器返 回元素的顺序排列。
Vector(int initialCapacity)
使用指定的初始容量和等于零的容量增量构造一个空向量。
Vector(int initialCapacity, int capacityIncrement)
使用指定的初始容量和容量增量构造一个空的向量。

特有方法:

void addElement(E obj)
将指定的组件添加到此向量的末尾,将其大小增加 1。

int capacity()
返回此向量的当前容量。

void copyInto(Object[] anArray)
将此向量的组件复制到指定的数组中。

E elementAt(int index)
返回指定索引处的组件。

Enumeration elements()
返回此向量的组件的枚举。

void ensureCapacity(int minCapacity)
增加此向量的容量(如有必要),以确保其至少能够保存最小容量参数指定的组件数。

E firstElement()
返回此向量的第一个组件(位于索引 0) 处的项)。

int indexOf(Object o, int index)
返回此向量中第一次出现的指定元素的索引,从 index 处正向搜索,如果未找到该元素,则返回 -1。

void insertElementAt(E obj, int index)
将指定对象作为此向量中的组件插入到指定的 index 处。

E lastElement()
返回此向量的最后一个组件。

int lastIndexOf(Object o, int index)
返回此向量中最后一次出现的指定元素的索引,从 index 处逆向搜索,如果未找到该元素,则返回 -1。

void removeAllElements()
从此向量中移除全部组件,并将其大小设置为零。

boolean removeElement(Object obj)
从此向量中移除变量的第一个(索引最小的)匹配项。

void removeElementAt(int index)
删除指定索引处的组件。

protected void removeRange(int fromIndex, int toIndex)
从此 List 中移除其索引位于 fromIndex(包括)与 toIndex(不包括)之间的所有元素。

void setElementAt(E obj, int index)
将此向量指定 index 处的组件设置为指定的对象。

void setSize(int newSize)
设置此向量的大小。
void trimToSize()
对此向量的容量进行微调,使其等于向量的当前大小。

2.Vector中的枚举Enumeration

Vector其特有的元素取出方式

相关方法:

boolean hasMoreElements()
测试此枚举是否包含更多的元素。

E nextElement()
如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素。

示例代码:

        //部分代码
        Vector v=new Vector();
        //使用两种方法添加元素
        v.addElement("示例元素1");
        v.add("示例元素2");

        //使用枚举方式取出Vector中的元素
        Enumeration enu=v.elements();
        while(enu.hasMoreElements()){
            System.out.println("使用枚举方式取出元素:"+enu.nextElement());
        }

程序运行结果:

使用枚举方式取出元素:示例元素1
使用枚举方式取出元素:示例元素2

说明:枚举的使用方式与迭代器类似,是较早的元素取用方式。随着JDK版本更,由于枚举接口的名称以及方法的名称都较长,现在已被迭代器取代。

4.List集合具体对象应用实例

1.LinkedList应用

场景概述

场景:使用LinkedList模拟一个堆栈和队列数据结构

堆栈:其中的元素具有先进后出的特点。即在进行添加操作时先进入队列的元素,在进行取出操作时后被取出来。

队列:其中的元素具有先进先出的特点。即在进行添加操作时先进入队列的元素,在进行取出操作时也先被取出来。

思路:将LinkedList进行个性化封装

用LinkedList实现栈

示例代码:

import java.util.LinkedList;

//自定义类,利用LinkedList实现堆栈
class MyStack{   
    private LinkedList linkedList;

    //栈的构造方法
    public MyStack(){
        linkedList=new LinkedList();
    }

    //判断是否为空
    public boolean isEmpty(){
        return linkedList.isEmpty();
    }

    //添加元素
    public void ownAdd(T t){
        linkedList.add(t);
    }

    //获取元素
    public T ownGet(){
        return linkedList.removeLast();
    }
}

//测试类
public class StackDemo {

    public static void main(String[] args) {
        //新建自定义栈
        MyStack ms=new MyStack();
        //添加元素
        ms.ownAdd("示例元素1");
        ms.ownAdd("示例元素2");
        ms.ownAdd("示例元素3");
        //按照先进后出的顺序取出元素
        while(!ms.isEmpty()){
            System.out.println(ms.ownGet());
        }
    }

}

程序运行结果:

示例元素3
示例元素2
示例元素1

用LinkedList实现队列

示例代码:

import java.util.LinkedList;

//自定义类,借助LinkedList实现队列
class MyQueue{
    private LinkedList linkedList;

    //队列构造方法
    public MyQueue(){
        linkedList=new LinkedList();
    }

    //判断队列是否为空
    public boolean isEmpty(){
        return linkedList.isEmpty();
    }

    //添加元素
    public void ownAdd(T t){
        linkedList.add(t);
    }

    //获取元素
    public T ownGet(){
        return linkedList.removeFirst();
    }
}

//测试类
public class QueueDemo {

    public static void main(String[] args) {
        //新建自定义队列
        MyQueue mq=new MyQueue();
        //添加元素
        mq.ownAdd("示例元素1");
        mq.ownAdd("示例元素2");
        mq.ownAdd("示例元素3");
        //按照先进先出的顺序取出元素
        while(!mq.isEmpty()){
            System.out.println(mq.ownGet());
        }
    }

}

程序运行结果:

示例元素1
示例元素2
示例元素3

为什么要封装?
我们希望将这些基本的容器封装为与我们的具体项目有关的特有容器,这样的封装就使得这些基本容器具有了特殊的含义,符合实际项目开发中的要求。

2.ArrayList示例

去除ArrayList中的重复元素

思路:从原容器中取出元素放入另一个新容器中,且每次加入时都与新容器中的元素进行一次判断,不重复的元素才进行加入

程序代码:

//本程序去除String元素为例
import java.util.ArrayList;
import java.util.ListIterator;

public class ArrayDeleteSame {

    //传入ArrayList对象,去除重复元素后返回
    public ArrayList deleteSame(ArrayList src){
        //建立装入唯一元素的集合
        ArrayList target=new ArrayList();

        for(int i=0;i//进行重复元素判断
            if(!target.contains(srcElement))
                target.add(srcElement);
        }
        return target;
    }

    public static void main(String[] args) {
        ArrayDeleteSame ads=new ArrayDeleteSame();
        //新建用于去除重复元素的ArrayList
        ArrayList src=new ArrayList();
        src.add("示例元素1");
        src.add("示例元素1");
        src.add("示例元素2");
        src.add("示例元素3");
        src.add("示例元素3");
        src=ads.deleteSame(src);

        //利用ListIterator迭代器对新集合的元素进行取出  
        for(ListIteratorlt=src.listIterator();
        lt.hasNext();){
            System.out.println(lt.next());
        }   
    }

}

程序运行结果:

示例元素1
示例元素2
示例元素3

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

示例场景:向集合中存入Student对象。若Student对象同姓名同年龄,则视为同一个人,即为重复元素。

思路:
1.对Student描述,将数据封装后装入Student对象
2.定义容器,将Student对象加入容器
3.对元素进行取出

代码技巧:
1.在迭代器循环中用Student强制转化获得的集合元素
2.在Student对象中重写equals方法,此处可以规定为比较姓名和年龄。在该方法中用instanceof方法先对传入的对象进行判断,若传入对象不为Student对象则直接返回false。
3.结合去除重复String元素的方法,去除Student重复对象

示例代码:

import java.util.ArrayList;
import java.util.ListIterator;

//自定义Student类
class Student{
    String name;
    int age;

    public Student(String name,int age){
        this.name=name;
        this.age=age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    //定义一个输出学生信息的方法
    public void output(){
        System.out.println("姓名:"+name+"------"+"年龄:"+age);
    }

    //重写Student对象进行比较的方法
    public boolean equals(Object obj){
        //如传入的元素不为Student对象,则直接返回false
        if(!(obj instanceof Student))
            return false;

        //将传入对象强转为Student对象
        Student s=(Student)obj;

        if(s.getAge()==this.age&&s.getName().equals(this.name))
            return true;
        else            
            return false;       
    }
}

public class StudentDeleteSame {

    //传入装有Student对象的ArrayList集合,去除重复元素后返回
    public ArrayList deleteSame(ArrayList src){

        //新建装入非重复元素的ArrayList对象
        ArrayList al=new ArrayList();

        ListIterator lt=src.listIterator();
        while(lt.hasNext()){
            //将取得的元素强转为Student对象
            Student s=(Student)lt.next();
            //进行非重复判断后加入新集合
            if(!al.contains(s))
                al.add(s);              
        }

        return al;
    }

    public static void main(String[] args) {
        StudentDeleteSame sds=new StudentDeleteSame();

        //新建装载Student对象的ArrayList集合对象
        ArrayList al=new ArrayList();
        al.add(new Student("bill",30));
        al.add(new Student("bill",30));
        al.add(new Student("KD",25));
        al.add(new Student("KD",25));
        al.add(new Student("KD",25));
        al.add(new Student("Pardon",12));

        //删除重复元素
        al=sds.deleteSame(al);

        System.out.println("去除重复元素后元素个数为:"+al.size());
        //对删除重复元素的集合进行元素取出
        ListIterator lt=al.listIterator();
        while(lt.hasNext()){
            Student s=(Student)lt.next();
            s.output();
        }
    }

}

程序运行结果:

去除重复元素后元素个数为:3
姓名:bill——年龄:30
姓名:KD——年龄:25
姓名:Pardon——年龄:12

结论:List集合判断元素是否相同[contains()方法],依据的是元素的equals()方法;包括remove(Object o)方法的元素比较部分调用的也是元素的equals()方法(先判断集合中有没有该元素,再进行删除操作)

注意:复写对象的equals方法时,注意该方法的参数为Object


相关阅读
菜鸟猿大战Java之集合框架系列(一)
菜鸟猿大战Java之集合框架系列(三)
菜鸟猿大战Java之集合框架系列(四)
菜鸟猿大战Java之集合框架系列(五)

你可能感兴趣的:(Java基础)