Collection接口讲完,接下来就是它的另外一个常用子接口List接口。

List接口,可以看看JavaAPI文档的定义

lua 移除teble第一元素 list去掉第一个元素_System

List接口的特点:
            1、有序 (存入和取出的顺序一致)
            2、可重复
            3、元素都有索引
 可以引申出List的一个共性特点:都可以操作角标(索引)

既然可以可以操作角标,那我们就可以结合数组的一些特性来学习List。

List中提供了一个特有方法get(int index)获取List集合中元素,优点类似数值的角标获取值array[int index]。说个具体应用,我们再建一个com.java.list包,然后定义一个ListTest1类:具体代码如下:

package com.java.list;
import java.util.ArrayList;
import java.util.List;
public class ListTest1 {
    @SuppressWarnings("rawtypes")
    List list = new ArrayList();

    @SuppressWarnings("unchecked")
    public void addElement(){
        list.add("张三");
        list.add("李四");
        list.add("王五");
    }
    public void getElement(){
        for(int i = 0; i < list.size(); i++){
            System.out.print(list.get(i) + "\t");
        }
    }
    public static void main(String[] args) {
        ListTest1 lt = new ListTest1();
        lt.addElement();
        lt.getElement();
    }
}

测试结果:

lua 移除teble第一元素 list去掉第一个元素_lua 移除teble第一元素_02

可以看出该法的遍历和数据的遍历非常类似。至此可以知道List集合有两种方法来获取List中元素。在此在介绍一个List集合本身具备的特有的迭代器——ListIterator接口

单从名字就可推测出来它一定与Iterator接口有关系,ListIterator接口是Iterator接口的子接口,但是它比Iterator更加强大。它可以实现在迭代过程中的增删改查。可以ListTest1类中添加一个方法,具体代码如下:

@SuppressWarnings({ "rawtypes", "unchecked" })
    public void getElement1(){
        ListIterator li = list.listIterator();
        while(li.hasNext()){
            Object obj = li.next();
            if("张三".equals(obj)){
                li.add("小强");
            }
        }
    }

测试代码如下:

public static void main(String[] args) {
        ListTest1 lt = new ListTest1();
        lt.addElement();
        //正常遍历
        lt.getElement();
        //在遍历时添加"小强"对象
        lt.getElement1();
        //正常遍历
        lt.getElement();
    }

测试结果:

lua 移除teble第一元素 list去掉第一个元素_System_03

这里只是测试了一个添加功能,其他功能原理类似,可自行测试。若是将ListIterator对象换为Iterator对象是会报错的,这里就不做测试了,有兴趣的可以试试。

虽然这个ListIterator提供一些强大的方法,但在平时用Iterator对象就能够满足我们大部分需求,所以Iterator对象用的较多。同时也不推荐用迭代器进行元素的增删改查。

现在在介绍一些方法,因为较为简单就不多做测试了

void clear()移除所有元素;
int indexOf(Object obj) 
 返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1;
int lastIndextOf(Object obj)
返回此列表中最后出现的指定元素的索引;如果此列表不包含该元素,则返回 -1;
E set(int index, E element)
用指定元素替换列表中指定位置的元素,返回以前在指定位置的元素。

至此List接口学完,接下来开始学习它的子类ArrayList和LinkedList,这里将两者结合学习,分析他们的区别。

因为很多集合是一个体系框架,所以在学习时,我们需要先学习它们之间的共同方法,再去学习它们特有的方法。

ArrayList实现类,先看看JavaAPI文档如何定义该类

lua 移除teble第一元素 list去掉第一个元素_lua 移除teble第一元素_04

ArrayList特点:
             1、内部是数组结构
             2、可变的数组
             3、不同步的

LinkedList实现类:

lua 移除teble第一元素 list去掉第一个元素_System_05

LinkedList特点:1、内部是链表结构
                2、是不同步的

概念和特点介绍完,我们开始分析它们的应用场景。根据它们各自的特点可做出如下分工:

ArrayList用于查询。
 因为它内部结构是数组,在内存中开辟了一块连续的空间,存放元素地址,查询速度快。
 LinkedList用于增删改。
 因为他内部是链表结构,增或是删,无需整体变动,这是链表的特点,这里不多做解释。
 因为链表结构在内存中开辟的空间未必是连续的,所以查询速度相对较慢。
  若是数据量不大两者都适用,在平时ArrayList用的最多。

在此介绍一些需要注意的方法。

ArrayList:
            E remove(int index)根据所以删除指定位置的元素,返回被删除的元素

 LinkedList:
 E getFirst() 返回列表第一个元素
 E getLast() 返回列表最后一个元素
 E removeFirst() 移除并返回此列表的第一个元素
 E removeLast() 移除并返回此列表的最后一个元素

接下来ArrayList和LinkedList各做一个例子,加深理解。

package com.java.list;
import java.util.ArrayList;
import java.util.Iterator;
/**
 * 去除容器中相同元素
 * @author Administrator
 *
 */
public class ArrayListTest {
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static ArrayList getSingleElement(ArrayList al){

        ArrayList tempList = new ArrayList();
        for(Iterator it = al.iterator(); it.hasNext();){
            Object obj = it.next();
            if(!tempList.contains(obj)){
                tempList.add(obj);
            }
        }
        return tempList;
    }
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static void main(String[] args) {
        ArrayList al = new ArrayList();
        al.add("abc");
        al.add("abc");
        al.add("def");
        System.out.println(al);
        ArrayList list = getSingleElement(al);
        System.out.println(list);
    }
}

结果:

lua 移除teble第一元素 list去掉第一个元素_System_06

若是上面的例子存入具体实体对象,会有相反的现象。做个测试,定义一个Student实体对象

lua 移除teble第一元素 list去掉第一个元素_lua 移除teble第一元素_07

然后测试代码:

lua 移除teble第一元素 list去掉第一个元素_List_08

测试结果:

lua 移除teble第一元素 list去掉第一个元素_System_09

会发现有两个张三,没有达到我们想要的功能,这时就需要知道ArrayList是依据什么判断相同。

我们调用boolean contains()来判断相同元素,而它却将两个张三存入,可以推测出contains()方法,并未判断Student对象的具体内容,而是判断了Student对象的地址,因为都是通过new创建对象,所以两个张三的Student对象地址不同,是两个不同的对象,因此将两个张三存入新的ArrayList集合中。

在此在说说contains()方法的原理

contains()实际上是对equals()方法的包装。
   若是判断实体类是否相等,默认是对对象地址进行判断,
   所以为了去掉两个张三,我们需要在实体类中重写equals()方法,
   让equals()方法判断对象中的内容是否相同即可。

具体在Student实体类中加入下面的代码即可。

public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        Student student = (Student) obj;
        if (name == null) {
            if (student.name != null)
                return false;
        } else if (!name.equals(student.name))
            return false;
        if (sId != student.sId)
            return false;
        return true;
    }

然后我们在做测试,结果如下:

lua 移除teble第一元素 list去掉第一个元素_lua 移除teble第一元素_10

LinkedList例子:

package com.java.list;
import java.util.LinkedList;
/**
 * 用LinkedList模拟堆栈的数据结构
 */
public class LinkedListTest {

    @SuppressWarnings("rawtypes")
    LinkedList linkList = new LinkedList();

    @SuppressWarnings("unchecked")
    public void add(Object obj){
        linkList.addLast(obj);
    }

    public Object remove(){
        return linkList.removeLast();
    }

    public static void main(String[] args) {
        LinkedListTest llt = new LinkedListTest();
        //第一存入
        llt.add("张三");
        //第二个存入
        llt.add("李四");
        //第三个存入
        llt.add("王五");
        System.out.println(llt.linkList);
        System.out.println("删除第一个:" + llt.remove());
        System.out.println("删除第二个:" + llt.remove());
        System.out.println("删除第三个:" + llt.remove());
    }
}

至此List体系算是大体收工了。接下来开始介绍Set集合了。