1.List接口概述
有序的集合序列。此接口的用户可以对列表中的每个元素的插入位置进行精确的控制。用户可以根据元素的索引(在列表中的位置)访问元素,并搜索列表中的元素。
与Set接口不同,列表通常允许重复的元素。
2.List案例
存储字符串并遍历
package com; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * 存储字符串并遍历 * */ public class ListDemo { public static void main(String[] args) { //创建List集合对象 List<String> list = new ArrayList<String>(); //添加元素 list.add("hello"); list.add("world"); list.add("java"); //遍历方法一 将集合转换为Object数组 然后输出 Object[] obj = list.toArray(); for (int i = 0; i < obj.length; i++) { String str = (String)obj[i]; System.out.println(str); } //遍历方法二 使用迭代器进行迭代 for(Iterator<String> iterator = list.iterator();iterator.hasNext();){ String str = iterator.next(); System.out.println(str); } } }
存储自定义对象并遍历
package com; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * 存储自定义对象并输出 */ public class ListDemo2 { public static void main(String[] args) { //创建List集合对象 List<Student> list = new ArrayList<Student>(); //创建学生对象 Student stu1 = new Student("观音姐姐",23); Student stu2 = new Student("如来哥哥",46); Student stu3 = new Student("嫦娥妹妹",18); //将学生对象存放到集合中 list.add(stu1); list.add(stu2); list.add(stu3); //遍历方法一 将集合转换成数组 ,然后进行遍历 Object[] obj = list.toArray(); for (int i = 0; i < obj.length; i++) { Student stu = (Student) obj[i]; System.out.println(stu); } //遍历方法二 通过迭代器进行迭代 for(Iterator<Student> iterator = list.iterator();iterator.hasNext();){ Student stu = iterator.next(); System.out.println(stu); } } }
3.List的特有的功能
List接口继承自Collection接口,除了继承了Collection接口的方法,还扩展了自己特有的方法。
添加功能
public void add(int index,E e) //在指定的索引位置上添加元素
package com; import java.util.ArrayList; import java.util.List; public class ListDemo { public static void main(String[] args) { //创建List集合对象 List<String> list = new ArrayList<String>(); //添加元素 list.add("hello"); list.add("world"); list.add("java"); list.add(1,"android"); System.out.println("list:"+list);//list:[hello, android, world, java] } }
获取功能
public E get(int index) 获取指定索引位置上的元素
package com; import java.util.ArrayList; import java.util.List; public class ListDemo { public static void main(String[] args) { //创建List集合对象 List<String> list = new ArrayList<String>(); //添加元素 list.add("hello"); list.add("world"); list.add("java"); list.add(1,"android"); System.out.println(list.get(2));//world } }
删除功能
public E remove(int index) 根据索引删除元素,并返回被删除的元素
package com; import java.util.ArrayList; import java.util.List; public class ListDemo { public static void main(String[] args) { //创建List集合对象 List<String> list = new ArrayList<String>(); //添加元素 list.add("hello"); list.add("world"); list.add("java"); list.add(1,"android"); System.out.println(list.remove(0));//hello System.out.println(list);//[android, world, java] } }
修改功能
public E set(int index,E e)根据索引修改元素,返回被修改的元素
package com; import java.util.ArrayList; import java.util.List; public class ListDemo { public static void main(String[] args) { //创建List集合对象 List<String> list = new ArrayList<String>(); //添加元素 list.add("hello"); list.add("world"); list.add("java"); System.out.println(list.set(0, "helloworld"));//hello System.out.println(list);//[helloworld, world, java] } }
列表迭代器 List集合特有的迭代器
public ListIterator<E> listIterator() 返回列表迭代器
欲知后事如何?且听下面分解。
4.List的迭代方式
List集合存储字符串
package com; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ListDemo { public static void main(String[] args) { //创建List集合对象 List<String> list = new ArrayList<String>(); //添加元素 list.add("hello"); list.add("world"); list.add("java"); //方法一 将list转换为Object[] 并用for循环输出 Object[] obj = list.toArray(); for (int i = 0; i < obj.length; i++) { System.out.println(obj[i]); } System.out.println("-----------------------"); //方法二 用Iterator迭代器 for(Iterator<String> iterator = list.iterator();iterator.hasNext();){ String str = iterator.next(); System.out.println(str); } System.out.println("-------------------------"); //方法三 使用size()和get(int index) for(int i = 0;i<list.size();i++){ String str = list.get(i); System.out.println(str); } } }
hello
world
java
-----------------------
hello
world
java
-------------------------
hello
world
java
List集合存储自定义对象
package com; public class Student { private String name; private int age; public Student(){} public Student(String name,int age){ this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } } package com; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ListDemo2 { public static void main(String[] args) { //创建List集合对象 List<Student> list = new ArrayList<Student>(); //创建学生对象 Student s1 = new Student("观音姐姐",23); Student s2 = new Student("如来哥哥",34); Student s3 = new Student("玉帝叔叔",43); //添加元素 list.add(s1); list.add(s2); list.add(s3); //方法一:将集合转换为Object[] Object[] obj = list.toArray(); for (int i = 0; i < obj.length; i++) { Student stu = (Student) obj[i]; System.out.println(stu); } System.out.println("---------------------"); //方法二:通过Iterator迭代器 for(Iterator<Student> iterator = list.iterator();iterator.hasNext();){ Student stu = iterator.next(); System.out.println(stu); } System.out.println("-----------------------"); for(int x = 0;x<list.size();x++){ Student stu = list.get(x); System.out.println(stu); } } }
Student [name=观音姐姐, age=23]
Student [name=如来哥哥, age=34]
Student [name=玉帝叔叔, age=43]
---------------------
Student [name=观音姐姐, age=23]
Student [name=如来哥哥, age=34]
Student [name=玉帝叔叔, age=43]
-----------------------
Student [name=观音姐姐, age=23]
Student [name=如来哥哥, age=34]
Student [name=玉帝叔叔, age=43]
5.列表迭代器ListIterator
ListIterator迭代器是List接口特有的方法,Collection接口是没有的,只有Iterator迭代器。所以我们可以想象这一定很强大是吧。
package com; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; public class ListDemo3 { public static void main(String[] args) { //创建List集合 List<String> list = new ArrayList<String>(); //添加元素 list.add("hello"); list.add("world"); list.add("java"); //使用Collection接口的Iterator迭代器功能 for(Iterator<String> iterator = list.iterator();iterator.hasNext();){ String str = iterator.next(); System.out.println(str); } System.out.println("------------------------"); //ListIterator迭代器是一个接口,而且继承Iterator接口 //所以ListIterator迭代器也应该有顺向遍历 for(ListIterator<String> listIterator = list.listIterator();listIterator.hasNext();){ String str = listIterator.next(); System.out.println(str); } } }
hello
world
java
------------------------
hello
world
java
如果ListIterator迭代器仅仅只提供这个功能,那就没必要提供了,因为父类就已经有这样的功能了。
package com; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; public class ListDemo3 { public static void main(String[] args) { //创建List集合 List<String> list = new ArrayList<String>(); //添加元素 list.add("hello"); list.add("world"); list.add("java"); //使用Collection接口的Iterator迭代器功能 for(Iterator<String> iterator = list.iterator();iterator.hasNext();){ String str = iterator.next(); System.out.println(str); } System.out.println("------------------------"); //ListIterator迭代器是一个接口,而且继承Iterator接口 //所以ListIterator迭代器也应该有顺向遍历 ListIterator<String> listIterator = list.listIterator(); while(listIterator.hasNext()){ String str = listIterator.next(); System.out.println(str); } System.out.println("------------------------"); //ListIterator迭代器还可以逆向遍历哦 while(listIterator.hasPrevious()){ String str = listIterator.previous(); System.out.println(str); } } }
hello
world
java
------------------------
hello
world
java
------------------------
java
world
hello
如果你真这么想,那只能说你太天真了,哈哈,看下面的代码
package com; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; public class ListDemo3 { public static void main(String[] args) { //创建List集合 List<String> list = new ArrayList<String>(); //添加元素 list.add("hello"); list.add("world"); list.add("java"); //使用Collection接口的Iterator迭代器功能 for(Iterator<String> iterator = list.iterator();iterator.hasNext();){ String str = iterator.next(); System.out.println(str); } System.out.println("------------------------"); //ListIterator迭代器是一个接口,而且继承Iterator接口 //所以ListIterator迭代器也应该有顺向遍历 ListIterator<String> listIterator = list.listIterator(); //ListIterator迭代器还可以逆向遍历哦 while(listIterator.hasPrevious()){ String str = listIterator.previous(); System.out.println(str); } } }
hello
world
java
------------------------
是不是感到很奇怪啊,为什么没有逆序遍历集合元素。
这就是ListIterator迭代器最坑爹的地方,使用ListIterator需要顺向遍历,然后才能逆向遍历。哈哈,还是不懂,看下面的图吧。
看到这里,是不是感觉ListIterator迭代器很坑爹啊。
6.练习
package com; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * 需求: * 有一个List集合,有"hello","world","java"这三个元素。 * 那么,如果有"world"这个元素,就向集合中增加 "javaee"元素 */ public class ListTest { public static void main(String[] args) { //创建List集合对象 List<String> list = new ArrayList<String>(); //添加元素 list.add("hello"); list.add("world"); list.add("java"); Iterator<String> iterator = list.iterator(); while(iterator.hasNext()){ String str = iterator.next(); if(str.equals("world")){ list.add("javaee"); } System.out.println(str); } } }
hello
world
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at com.ListTest.main(ListTest.java:24)
报错了,怎么回事??
ConcurrentModificationException这是什么鬼??
通过查看API,我们知道当方法检测到对象的并发修改,但不允许这种修改时,就会抛出此异常。
产生异常的原因是:
迭代器是依赖于集合存在而存在的,先有集合后有迭代器啊。我们在判断成功后,集合中新添加了元素。此时的集合发生了改变,而迭代器却不知道,还访问的是先前的集合。这个错叫并发修改异常。
其实,换句话说迭代器遍历元素的时候,通过集合是不能修改元素的。
那么如何解决呢?
1.迭代器迭代元素,迭代器修改元素。
2.集合遍历元素,集合修改元素。
package com; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; /** * 需求: * 有一个List集合,有"hello","world","java"这三个元素。 * 那么,如果有"world"这个元素,就向集合中增加 "javaee"元素 */ public class ListTest { public static void main(String[] args) { //创建List集合对象 List<String> list = new ArrayList<String>(); //添加元素 list.add("hello"); list.add("world"); list.add("java"); //方法一:迭代器迭代元素 迭代器修改元素 //但是Iterator迭代器却没有添加功能,所以我们用子接口ListIterator //但是元素是跟在刚才迭代的后面 ListIterator<String> listIterator = list.listIterator(); while(listIterator.hasNext()){ String str = listIterator.next(); if("world".equals(str)){ listIterator.add("javaee"); } } System.out.println(list); } }
[hello, javaee, java, world]
package com; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; /** * 需求: * 有一个List集合,有"hello","world","java"这三个元素。 * 那么,如果有"world"这个元素,就向集合中增加 "javaee"元素 */ public class ListTest { public static void main(String[] args) { //创建List集合对象 List<String> list = new ArrayList<String>(); //添加元素 list.add("hello"); list.add("world"); list.add("java"); //方法二 for循环遍历 //元素是在最后 for(int x = 0;x<list.size();x++){ if(list.get(x).equals("world")){ list.add("javaee"); } } System.out.println(list); } }
[hello, world, java, javaee]
7.数据结构
数据结构:数据的组织方式。
栈:先进后出
队列:先进先出
数组:存储同一种类型的多个元素的容器。有索引,方便我们将数组的元素取出。
链表:由一个链子把错咯结点链接起来的数据结构。
结点:有数据和地址组成。(数据域和指针域组成)。
7.List的3个子类的特点
ArrayList:底层数据结构是数组,查询快,增删慢。线程不安全,效率高。
Vector:底层数据结构是数组,查询快,增删慢。线程安全,效率低。
LinkedList:底层数据结构是列表,查询慢,增删快。线程不安全,效率高。