Java基础-Collection子接口之List接口
Java基础-Collection子接口之List接口
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
我们掌握了Collection接口的使用后,再来看看Collection接口中的子类,他们都具备那些特性呢?接下来我们一起Collection中的常用子类之一的:List集合。
一.List接口介绍
有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。与 set 不同,列表通常允许重复的元素。更确切地讲,列表通常允许满足 e1.equals(e2) 的元素对 e1 和 e2,并且如果列表本身允许 null 元素的话,通常它们允许多个 null 元素。难免有人希望通过在用户尝试插入重复元素时抛出运行时异常的方法来禁止重复的列表,但我们希望这种用法越少越好。
看完API我们可以做出如下总结:
1>.它是一个元素存取有序的集合。例如,存元素的顺序是11,22,33。那么集合中,元素的存储都是按照11,22,33的顺序完成的;
2>.它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个道理)。
3>.集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素。
List接口是继承了Collection接口,下面有很多实现类,常用的实现类有:ArrayList集合,LinkedList集合和Vector集合。
二.List接口的特有方法
List接口中的抽象方法,有一部分方法和他的父接口Collection是一样,List接口也有自己特有的方法,带有索引的功能。
1>.add(int index,E)方法【将元素插入到列表的指定索引上】
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.note; 8 9 import java.util.ArrayList; 10 import java.util.List; 11 12 public class ListDemo { 13 public static void main(String[] args) { 14 function(); 15 } 16 17 public static void function() { 18 List<String> list = new ArrayList<String>(); 19 list.add("yinzhengjie1"); 20 list.add("yinzhengjie2"); 21 list.add("yinzhengjie3"); 22 list.add("yinzhengjie4"); 23 System.out.println(list); 24 list.add(4,"yinzhengjie"); //这里是在当前集合中最后一个索引进行添加操作! 25 list.add(1,"尹正杰"); 26 System.out.println(list); 27 } 28 } 29 30 /* 31 以上代码执行结果如下: 32 [yinzhengjie1, yinzhengjie2, yinzhengjie3, yinzhengjie4] 33 [yinzhengjie1, 尹正杰, yinzhengjie2, yinzhengjie3, yinzhengjie4, yinzhengjie] 34 */
2>.get(int index)方法【返回列表中指定位置的元素】
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.note; 8 9 import java.util.ArrayList; 10 import java.util.List; 11 12 public class ListDemo { 13 public static void main(String[] args) { 14 function(); 15 } 16 17 public static void function() { 18 List<String> list = new ArrayList<String>(); 19 list.add("yinzhengjie1"); 20 list.add("yinzhengjie2"); 21 list.add("yinzhengjie3"); 22 list.add("yinzhengjie4"); 23 System.out.println(list.get(2)); //获取指定索引的值 24 } 25 } 26 27 /* 28 以上代码执行结果如下: 29 yinzhengjie3 30 */
3>.remove(Object o)方法【从此列表中移除第一次出现的指定元素(可选操作,如果存在就删除第一此匹配到的元素,如果没有匹配到就不做任何操作)】
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.note; 8 9 import java.util.ArrayList; 10 import java.util.List; 11 12 public class ListDemo { 13 public static void main(String[] args) { 14 function(); 15 } 16 17 public static void function() { 18 List<String> list = new ArrayList<String>(); 19 list.add("yinzhengjie1"); 20 list.add("yinzhengjie2"); 21 list.add("yinzhengjie3"); 22 list.add("yinzhengjie4"); 23 System.out.println(list); 24 System.out.println(list.remove("yinzhengjie4")); //删除指定的元素,删除后返回布尔值表示是否删除成功。 25 System.out.println(list); 26 } 27 } 28 29 /* 30 以上代码执行结果如下: 31 [yinzhengjie1, yinzhengjie2, yinzhengjie3, yinzhengjie4] 32 true 33 [yinzhengjie1, yinzhengjie2, yinzhengjie3] 34 */
4>.remove(int index)方法【移除列表中指定位置(索引)的元素】
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.note; 8 9 import java.util.ArrayList; 10 import java.util.List; 11 12 public class ListDemo { 13 public static void main(String[] args) { 14 function(); 15 } 16 17 public static void function() { 18 List<String> list = new ArrayList<String>(); 19 list.add("yinzhengjie1"); 20 list.add("yinzhengjie2"); 21 list.add("yinzhengjie3"); 22 list.add("yinzhengjie4"); 23 System.out.println(list); 24 System.out.println(list.remove(0)); //返回被删除的元素 25 System.out.println(list); 26 } 27 } 28 29 /* 30 以上代码执行结果如下: 31 [yinzhengjie1, yinzhengjie2, yinzhengjie3, yinzhengjie4] 32 yinzhengjie1 33 [yinzhengjie2, yinzhengjie3, yinzhengjie4] 34 */
5>.set(int index, E)方法【修改指定索引上的元素,返回被修改之前的元素】
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.note; 8 9 import java.util.ArrayList; 10 import java.util.List; 11 12 public class ListDemo { 13 public static void main(String[] args) { 14 function(); 15 } 16 17 public static void function() { 18 List<String> list = new ArrayList<String>(); 19 list.add("yinzhengjie1"); 20 list.add("yinzhengjie2"); 21 list.add("yinzhengjie3"); 22 list.add("yinzhengjie4"); 23 System.out.println(list); 24 System.out.println(list.set(3, "尹正杰")); //返回被修改的修改之前的元素。 25 System.out.println(list); 26 } 27 } 28 29 /* 30 以上代码执行结果如下: 31 [yinzhengjie1, yinzhengjie2, yinzhengjie3, yinzhengjie4] 32 yinzhengjie4 33 [yinzhengjie1, yinzhengjie2, yinzhengjie3, 尹正杰] 34 */
6>.List常见的三种遍历方式
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.note; 8 9 import java.util.ArrayList; 10 import java.util.Iterator; 11 import java.util.List; 12 13 public class ListDemo { 14 public static void main(String[] args) { 15 function(); 16 } 17 18 public static void function() { 19 List<String> list = new ArrayList<String>(); 20 list.add("yinzhengjie1"); 21 list.add("yinzhengjie2"); 22 list.add("yinzhengjie3"); 23 list.add("yinzhengjie4"); 24 //遍历方式一: 25 System.out.println("第一种遍历方式:"); 26 Iterator<String> it = list.iterator(); 27 while(it.hasNext()) { 28 System.out.println("\t"+it.next()); 29 } 30 //第二种遍历方式: 31 System.out.println("第二种遍历方式:"); 32 for (int index = 0; index < list.size(); index++) { 33 System.out.println("\t"+list.get(index)); 34 } 35 //第三种遍历方式:(可以理解是第一种遍历方式的简写模式,推荐使用) 36 System.out.println("第三种遍历方式:"); 37 for (String string : list) { 38 System.out.println("\t"+string); 39 } 40 //第四种遍历方式: 41 System.out.println("第四种遍历方式:"); 42 for(Iterator<String> it2 = list.iterator();it2.hasNext();) { 43 System.out.println("\t"+it2.next()); 44 } 45 } 46 } 47 48 /* 49 以上代码执行结果如下: 50 第一种遍历方式: 51 yinzhengjie1 52 yinzhengjie2 53 yinzhengjie3 54 yinzhengjie4 55 第二种遍历方式: 56 yinzhengjie1 57 yinzhengjie2 58 yinzhengjie3 59 yinzhengjie4 60 第三种遍历方式: 61 yinzhengjie1 62 yinzhengjie2 63 yinzhengjie3 64 yinzhengjie4 65 第四种遍历方式: 66 yinzhengjie1 67 yinzhengjie2 68 yinzhengjie3 69 yinzhengjie4 70 */
三.迭代器的并发修改异常
迭代器并发异常:java.util.ConcurrentModificationException
就是在遍历的过程中,使用了集合方法修改了集合的长度是不允许的!如果你用set命令修改元素的value的话是可以的,但是只要你修改长度就会抛异常!
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.note; 8 9 import java.util.ArrayList; 10 import java.util.Iterator; 11 import java.util.List; 12 13 public class ListDemo { 14 public static void main(String[] args) { 15 function(); 16 } 17 18 public static void function() { 19 List<String> list = new ArrayList<String>(); 20 list.add("yinzhengjie1"); 21 list.add("yinzhengjie2"); 22 list.add("yinzhengjie3"); 23 list.add("yinzhengjie4"); 24 Iterator<String> it = list.iterator(); 25 while(it.hasNext()) { 26 String s = it.next(); 27 if(s.equals("yinzhengjie1")) { 28 list.add("尹正杰"); //在遍历的过程中,使用集合方法修改集合的长度是不允许的(存在异常:java.util.ConcurrentModificationException)。但是你可以用set命令进行修改哟! 29 } 30 } 31 } 32 } 33 34 /* 35 以上代码执行结果如下: 36 Exception in thread "main" java.util.ConcurrentModificationException 37 at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:939) 38 at java.base/java.util.ArrayList$Itr.next(ArrayList.java:893) 39 at cn.org.yinzhengjie.note.ListDemo.function(ListDemo.java:26) 40 at cn.org.yinzhengjie.note.ListDemo.main(ListDemo.java:15) 41 */
四.数据的存储结构
List接口下有很多集合,他们存储元素所采用的结构方式是不同的,这样就导致了这些集合有它们各自的特点,供给我们在不同的环境下进行使用。数据存储的常用结构有:堆栈,队列,数组和链表。我们分别来了解一下:
1>.堆栈,采用该结构的集合,对元素的存取有如下的特点:
a>.先进后出(即,存进去的元素,要在它后面的元素异常取出后,才能取出该元素),例如:子弹压进弹夹,先压进去的子弹在下面,后压进去的子弹在上面,当开枪时,先弹出上面的子弹,然后才能弹出下面的子弹;
b>.栈的入口,出口的都是栈的顶端位置;
c>.压栈:就是存元素。即把元素存储到栈的顶端位置,栈中已有元素依次向栈低方向移动一个位置;
d>.弹栈:就是取元素。即,把栈的顶端位置元素取出,栈中已有元素依次向栈顶方向移动一个位置
2>.队列,采用该结构的结合,对元素的存取有如下的特点:
a>.先进先出(即存进去的元素要在它前面的元素异常取出后,才能取出该元素),例如:安检,排成一列,每个人依次检查,只有前面的人全部检查完毕后,才能排到当前的人进行检查。
b>.队列的入口,出口各占一侧。例如:下图中的左侧为入口。右侧则为出口。
3>.数组,采用该结构的结合,对元素的存取有如下的特点:
a>.查找元素块,通过索引,可以快速访问指定位置元素;
b>.增删元素慢原因之一:指定索引位置增加元素
需要创建一个新数组,将指定新元素存储在指定索引位置,再把原数组元素根据索引,复制到薪数组对应索引的位置。
c>.增删元素慢原因之二:指定索引位置删除元素
新数组对应索引的位置,原数组中指定索引位置元素不赋值到新数组中
4>.链表,采用该结构的集合,对元素的存取有如下的特点:
a>.多个节点之间,通过地址进行连接。例如,多个人手拉手,每个人使用自己的右手拉住下个人的左手,依次类推,这样多个人就连在一起了;
b>. 查找元素慢:想查找某个元素,需要通过连接的节点,依次向后查找指定元素;
c>.增删元素快原因之增加元素:操作如左图,只需要修改连接下个元素的地址即可;
d>.增删元素快原因之删除元素:操作如右图,只需要修改连接下个元素的地址即可;
五.ArrayList集合的自身特点
ArrayList集合数据存储的结构是数组结构。元素增删慢,查找快,由于日常开发中使用最多的功能为查询数据、遍历数据,所以ArrayList是最常用的集合。许多程序员开发时非常随意地使用ArrayList完成任何需求,并不严谨,这种用法是不提倡的。
六.LinkList特有方法
LinkedList集合数据存储的结构是链表结构。方便元素添加、删除的集合。实际开发中对一个集合元素的添加与删除经常涉及到首尾操作,而LinkedList提供了大量首尾操作的方法。
LinkedList是List的子类,List中的方法LinkedList都是可以使用,这里就不做详细介绍,我们只需要了解LinkedList的特有方法即可。在开发时,LinkedList集合也可以作为堆栈,队列的结构使用。
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.note; 8 9 import java.util.LinkedList; 10 11 public class ListDemo { 12 public static void main(String[] args) { 13 function(); 14 } 15 16 public static void function() { 17 LinkedList<String> link = new LinkedList<String>(); 18 //添加元素 19 link.addFirst("yinzhengjie1"); 20 link.addFirst("yinzhengjie2"); 21 link.addFirst("yinzhengjie3"); 22 link.addFirst("yinzhengjie4"); 23 //获取元素 24 System.out.println("当前元素的成员:"+link); 25 System.out.println("获取元素:"); 26 System.out.println("\t"+link.getFirst()); 27 System.out.println("\t"+link.getLast()); 28 //删除元素 29 System.out.println("当前元素的成员:"+link); 30 System.out.println("删除元素:"); 31 System.out.println("\t"+link.removeFirst()); //移除并返回链表的开头 32 System.out.println("\t"+link.removeLast()); //异常并返回链表的结尾 33 System.out.println("当前元素的成员:"+link); 34 System.out.println("遍历元素:"); 35 while(!link.isEmpty()){ //判断集合是否为空 36 System.out.println("\t"+link.pop()); //弹出集合中的栈顶元素,依次删除索引较小的元素 37 System.out.println("当前元素的成员:"+link); 38 } 39 System.out.println("当前元素的成员:"+link); 40 } 41 } 42 43 /* 44 以上代码执行结果如下: 45 当前元素的成员:[yinzhengjie4, yinzhengjie3, yinzhengjie2, yinzhengjie1] 46 获取元素: 47 yinzhengjie4 48 yinzhengjie1 49 当前元素的成员:[yinzhengjie4, yinzhengjie3, yinzhengjie2, yinzhengjie1] 50 删除元素: 51 yinzhengjie4 52 yinzhengjie1 53 当前元素的成员:[yinzhengjie3, yinzhengjie2] 54 遍历元素: 55 yinzhengjie3 56 当前元素的成员:[yinzhengjie2] 57 yinzhengjie2 58 当前元素的成员:[] 59 当前元素的成员:[] 60 */
七.Vector类的特点
Vector集合数据存储的结构是数组结构,为JDK中最早提供的集合。Vector中提供了一个独特的取出方式,就是枚举Enumeration,它其实就是早期的迭代器。此接口Enumeration的功能与 Iterator 接口的功能是类似的。Vector集合已被ArrayList替代。枚举Enumeration已被迭代器Iterator替代。
Vector集合的特点就是线程安全运行速度慢!
1>.Vector常见的方法
2>.Enumeration枚举常见的方法
3>.Vector集合对ArrayList集合使用的对比