首先,大致介绍下List集合的特征,List集合中的元素是有序的并且是可重复的,可以根据索引进行取值。一般的结合操作详见API。List集合有三个具体集合类:ArrayList,LinkedList,Vector;
ArrayList:底层实现是数组,相对来说,查询速度比较快,但是增删速度较慢。线程不同步。
LinkedList:底层实现是链表,相对来说,增删速度较快,查询速度较慢。
Vector:底层是数据,是出现在ArrayList之前,由于线程同步,增删,查询都比较慢,被ArrayList所代替。
在List集合中有一个特殊的方法:listIterator();整个集合框架都有一个返回Iterator对象的方法。在List集合中又出现了一个listIterator()方法,该方法返回一个ListIterator对象。查阅API可以了解到这个ListIterator是 Iterator的子接口。那么究竟有什么用途呢?
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {
int value = it.next();
if (value == 5) {
list.remove();
}
}
在上面的那段代码中, list.remove(); 是会抛出并发操作异常的。意思就是在进行迭代的时候使用了集合对象的方法来对集合进行增删改的操作,会引发并发操作异常。一种改进的方法就是不使用 Iterator进行迭代,换成循环;另一种方法就是将 list.remove() 代码换成it.remove();后一种改进方法是有缺陷的,如果需求是向集合增加一个元素而不是删除一个元素,这时,Iterator对象就显得无能无力了,因为它只有删除的操作,并没有添加。为了解决这个缺陷,出现了ListIterator,该接口拓冲了 Iterator接口,增加了一些实用的方法。这时List集合中所需要知道的第一个知识点。
对于LIst集合还需要了解的是其contains()方法,该方法底层其实就是equals两个对象。将要比较的对象与集合中的每一个对象都equals比较。如果是字符串集合List<String>,那么这种比较结果是我们所期待的,但是如果是我们自己写的类,比如Person,List<Person>。如果Person类没有实现其equals方法,那么结果和我们所期待的并不相同。因为Person类从Object所继承的equals方法是比较两个对象的引用是否相同。我们期待的是比较它们所包含的变量是否相同。怎么办呢?很简单,覆盖从Object继承的equals方法即可。
假设Person类有name,age包含两个变量。
@Override
public boolean equals(Object obj) {
if (obj instanceof People) {
People p = (People) obj;
return this.name.equals(p.getName()) && this.age == p.getAge();
} else {
return false;
}
}
通过覆盖这个方法,equals的行为就是我们所期待的了。