Collection接口讲完,接下来就是它的另外一个常用子接口List接口。
List接口,可以看看JavaAPI文档的定义
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();
}
}
测试结果:
可以看出该法的遍历和数据的遍历非常类似。至此可以知道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();
}
测试结果:
这里只是测试了一个添加功能,其他功能原理类似,可自行测试。若是将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文档如何定义该类
ArrayList特点:
1、内部是数组结构
2、可变的数组
3、不同步的
LinkedList实现类:
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);
}
}
结果:
若是上面的例子存入具体实体对象,会有相反的现象。做个测试,定义一个Student实体对象
然后测试代码:
测试结果:
会发现有两个张三,没有达到我们想要的功能,这时就需要知道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;
}
然后我们在做测试,结果如下:
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集合了。