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需要顺向遍历,然后才能逆向遍历。哈哈,还是不懂,看下面的图吧。

java集合框架--List接口_java

java集合框架--List接口_框架_02

看到这里,是不是感觉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.数据结构

数据结构:数据的组织方式。

栈:先进后出

java集合框架--List接口_框架_03

队列:先进先出

java集合框架--List接口_java_04

数组:存储同一种类型的多个元素的容器。有索引,方便我们将数组的元素取出。

java集合框架--List接口_集合_05

链表:由一个链子把错咯结点链接起来的数据结构。

结点:有数据和地址组成。(数据域和指针域组成)。

java集合框架--List接口_框架_06


7.List的3个子类的特点

ArrayList:底层数据结构是数组,查询快,增删慢。线程不安全,效率高。

Vector:底层数据结构是数组,查询快,增删慢。线程安全,效率低。

LinkedList:底层数据结构是列表,查询慢,增删快。线程不安全,效率高。