4、List集合
(1)List集合的特点和常用方法

List集合继承于Collection接口,List集合本质也是一个接口。
(1)List系列集合特点:
添加的元素是有序(有序指的是存和取的顺序是一样的)、可重复、有索引。
(2)List集合的特有方法
因为List继承于Collection所以List继承了Collection方法,又因为List集合有索引,所以多了很多索引操作的方法。
void add(int index,E element) 在此集合中的指定位置插入指定的元素。
E remove(int index) 删除指定索引处的元素,返回被删除的元素
E set(int index,E element) 修改指定索引处的元素,返回被修改的元素
E get(int index) 返回指定索引处的元素
List集合中删除操作的 注意事项 :
在调用方法的时候,如果方法出现了重载现象, 优先调用实参跟形参类型一致 的那个方法,//手动装箱,手动把基本数据类型的1,变成Integer类型。
具体请看下面的代码练习:
java
import java.util.ArrayList;
import java.util.List;
public class ListText1 {
public static void main(String[] args){
List<String> list = new ArrayList<>();
//直接在集合尾部添加元素
list.add("aaa");
list.add("ccc");
list.add("ddd");
System.out.println(list);
//指定索引的位置添加元素
list.add(1,"bbb");
System.out.println(list);
//直接删除指定元素
boolean flag = list.remove("ddd");
System.out.println(list);
//删除索引出的元素
String result1=list.remove(2);
System.out.println(result1 + list);
//修改指定索引处的元素
String result2=list.set(0,"kkk");
System.out.println(result2 + list);
//获取指定索引的元素
String result3=list.get(0);
System.out.println(result3);
}
}
List集合中的删除操作:
java
import java.util.ArrayList;
import java.util.List;
public class ListText2 {
public static void main(String[] args){
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
//问:此时删除的是1这个元素,还是1索引上的元素?
//答:删除的是索引1上的元素;
//因为在调用方法的时候,如果方法出现了重载现象,优先调用实参跟形参类型一致的那个方法。
list.remove(1);
System.out.println(list);
list.add(1,2);
System.out.println(list);
//手动装箱,手动把基本数据类型的1,变成Integer类型
Integer i = Integer.valueOf(1);
list.remove(i);
System.out.println(list);
}
}
(2)List集合的遍历方式

-
for循环遍历
-
迭代器遍历
-
列表迭代器遍历
-
增强for遍历
-
Lambda表达式遍历
------1、for循环遍历
------2、迭代器遍历
迭代器遍历
迭代器在java中的类是Iterator,迭代器是集合专用的遍历方式。 Iterator是一个接口,Iterator对象也被称为迭代器。迭代器遍历不依赖索引。
Collection集合获取迭代器
方法:Iterator<E> iterator() 返回迭代器对象,默认指向当前集合的0索引
Iterator中常用的方法
boolean hasNext() 判断当前位置是否有元素,有元素返回true,没有元素返回false
E next() 返回当前位置的元素,并将迭代器对象移向下一个位置
void remove() 删除集合里上一次next方法返回的元素。
遍历的语法:
Iterator<String> it = list.iterator() 获取集合对应的迭代器创建指针默认指向0索引
while(it.hasNext()){ 判断是否有元素
String str = it.next(); 获取元素
System.out.println(str);
}
细节:
-
如果迭代器已经指向末尾的下一个位置,此时如果再次调用next()方法获取元素,则会报NoSuchElementException
没有这个元素异常。因为迭代器不依赖索引 -
迭代器遍历完毕, 指针不会复位 ,若想重新遍历,则需重新获取一个迭代器对象。
-
循环中只能用一次next方法,因为next方法调用一次会移动指针,所以在最后会出现NoSuchElementException异常。
-
迭代器遍历时,不能用集合的方法进行增加或者删除( 迭代过程中增加或删除集合元素则运行时会报ConcurrentModificationException 并发异常)
------3、增强for遍历
------4、Lambda表达式遍历
Lambda表达式遍历
利用Lambda表达式里面的方法:
方法:default void forEach(Consumer<? super T> action); 结合Lambda遍历集合
// 方法底层原理: //底层会自己遍历集合,依次获取每个元素,把得到的每个元素,传递给下面的accept方法
下面代码的匿名内部类:new的是大括号中没有名字的类的对象,实现了Consumer<String>()这个接口。
java
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
public class ListText3 {
public static void main(String[] args) {
List<String> list = new ArrayList<> ();
list.add("aaa");
list.add("bbb");
list.add("ccc");
//迭代器遍历
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String str = it.next();
System.out.println(str);
}
//增强for遍历
for(String s: list) {
System.out.println(s);
}
//Lambda表达式遍历
// list.forEach(new Consumer<String>() {
// @Override
// public void accept(String s) {
// System.out.println(s);
// }
// });
list.forEach( s-> System.out.println(s));
//普通for循环遍历
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}
}
------5、列表迭代器遍历
ListIterator接口--列表迭代器继承于Iterator接口。
ListIterator创建对象:
ListIterator<E> listIt = 集合.listIterator();
ListInterator常用方法
boolean hasNext()正向: 判断后面有没有元素
E next()正向: 取出下一个元素
boolean hasPrevious()反向: 判断前面有没有元素
E previous()反向: 取出上一个元素
void remove() 删除迭代器遍历到的元素
void add(E e) 在当前位置插入新元素
java
import java.util.*;
import java.util.List;
//import java.util.function.Consumer;
public class ListText3 {
public static void main(String[] args) {
List<String> list = new ArrayList<> ();
list.add("aaa");
list.add("bbb");
list.add("ccc");
//列表迭代器
ListIterator<String> It = list.listIterator();
while (It.hasNext()) {
String str = It.next();
if("bbb".equals(str)){
list.add("qqq");//这里会运行时异常错误。因为在迭代器遍历中使用集合的方式进行添加
It.add("qqq");//可以添加,因为使用的是迭代器中的添加方法
}
}
System.out.println(list);
运行结果: [aaa, bbb, qqq, ccc]
}
}
5、List集合的实现类
(1)ArrayList集合类;
因为ArrayList是List的实现类,所以ArrayList也继承了List的方法,这里不再讲解。
List2.addAll(list1);将List1集合添加到list2
ArrayList集合底层原理
(1)利用空参创建的集合,在底层创建一个默认长度为0的数组。
(2)添加第一个元素时,底层 会创建一个新的长度为10的数组。
(3)存满时,会自动扩容1.5倍,即长度为15的数组。而当15的长度也存满时,还会继续扩容1.5倍,持续不断。
(4)如果一次添加多个元素,1.5倍还放不下,则新创建数组的长度以实际为准。
(2)LinkedList集合
LinkedList集合
-
底层数据结构是 双链表 ,查询慢,增删快,但是如果操作的是首尾元素,速度也是极快的。
-
LinkedList本身多了很多直接操作首尾元素的特有API。
LinkedList集合特有方法
Public void addFirst(E e) 在该列表开头插入指定的元素
Public void addLast(E e) 将指定元素追加到此列表的末尾
Public E getFirst() 返回此列表的第一个元素
Public E getLast() 返回此列表的最后一个元素
Public E removeFirst() 从此列表中删除并返回第一个元素
Public E removeLast() 从此列表中删除并返回最后一个元素