java 集合 List
List
List是一个有序的集合,可以包含重复的元素
List的两种遍历方式
-
迭代器对象遍历
//获取当前list对象的迭代器对象 Iterator iterator=list.iterator(); //遍历集合 //iterator.hasNext()相当于是一个指针,判断集合中下一个单元是否存在元素 //如果存在,返回true,指针向下走一个单元 while(iterator.hasNext()) { //返回当前指针指向的元素 Object next=iterator.next(); System.out.println(next); }
值得注意的是:用迭代器循环遍历时,用集合本身的remove方法删除元素 list.remove() 会报错 ConcurrentModificationException 因为迭代器创建后相当于一个快照,如果你用集合的remove方法去删除,而不是迭代器的方法去删除,那么当前集合中的元素就会和创建的快照不一样,就会报错
iterator1.remove();//迭代器,删除当前指针指向的元素
-
foreach循环遍历
for(Object object:list) { System.out.println(object); }
List的boolean contains(Object o)方法
contains()方法是用来判断集合中是否包含某一元素
-
我们先通过不同的方式定义几个String类型的变量并且加str1加到List集合中
String str1=new String("abc"); String str2="abc"; String str3=new String("abc"); List list = new ArrayList(); list.add(str1);
-
看是否包含str2和str3
System.out.println(list.contains(str2)); System.out.println(list.contains(str3));
-
查看输出结果
true true
-
结果分析
我们首先查看contains方法的ArrayList中的源码
return indexOf(o) >= 0;
再查看indexOf()方法的部分源码
if (o.equals(elementData[i])) return i;
可以看到contains()方法内部其实是调用了equals()方法的,那么在Object类中的本身的equals方法比较的是地址值,但是我们添加进集合的元素为String类型,String类中是对equals方法进行了重写了,将比较地址重写为了比较值,也就是说当在执行list.contains(str3)语句时,比较是值,因为都是"abc",所以当然应该返回true。
-
如果我们在list中添加一个新的没有重写equals()方法的类的对象
User user=new User(20); User user1=new User(20); list.add(user); System.out.println(list.contains(user1));
-
执行结果:
false
-
结果分析:
因为User类中是没有重写equals方法的,因此在调用contains方法时,contains方法调用的equals方法是调用的Object类的方法,即比较的地址值。user和user1的地址值很明显是不同的,返回false。
-
remove(Object o)方法
remove()方法是去除集合中的某一元素,remove()方法查看源码
-
if (o.equals(elementData[index])) { fastRemove(index); return true; }
remove()方法也是调用了equals方法,但是在remove之后直接return true了 所以只能删除一个元素。
泛型
jdk1.5版本之后引入的新特性,强制让集合只能存放某一种数据类型
<引用数据类型>钻石表达式
数据类型可以是一个父类,然后可以加子类的数据类型。数据类型还可以是一个接口,然后可以添加其实现类的数据类型,要获取某一个子类的私有方法的时候,则需要先判断是否属于某类,然后强制转型。
自定义泛型:
public class 类名<自定义泛型名>
{
}
LinkedList
ArrayList与LinkedList的区别:
ArrayList的底层是数组结构;LinkedList底层是链表结构
ArrayList随机查询效率高,增删效率低;LinkedList随机增删效率高,查询效率低