在集合框架中,List就是一个接口,继承于Collection接口。
在数据结构的角度,List就是一个线性表,即n个具有相同类型元素的有限序列,在该序列上可以执行增删查改以及变量等操作。
什么是线性表? 线性表是由n个具有相同类型元素组成的有限序列。线性表是一种常见的数据结构。在逻辑上,线性表是一种线性结构,就是连续的一条直线,在物理结构上,不一定是连续的,在物理存储是,通常是以数组和链式的结构形式存储。常见的线性比表有顺序表、链表、栈、队列.......
增 | |
---|---|
boolean add(E e) | 插入元素e在末尾 |
void add(int index,E element) | 插入元素e在index位置 |
boolean addAll(Collection?extends?E>c) | 尾插c中的元素 |
删 | |
E remove(int index) | 删除index位置的元素 |
boolean remove(Object o) | 删除第一次出现的o元素 |
void clear() | 清空 |
查 | |
E get(int index) | 获取index下标位置元素 |
int indexOf(Object o) | 获取第一个o元素所在的下标 |
int lastindexOf(Object o) | 获取最后一个o元素所在的下标 |
boolean contains(Object o) | 查看是否包含o元素 |
改 | |
E set(int index,E Element) | 将index下标的元素改为e |
截取 | |
List<E>subList(int formIndex,int toIndex) | 截取部分list |
List是一个接口,所以不能直接实例化。如果想要使用list接口,必须实例化list的实现类。
在集合框架中,ArrayList和LinkedList都实现了这个接口。
ArrayList是一个普通的类,是顺序表的一种,实现了list接口,是一种可动态调整大小的数组,能够储存不同类型的对象。
什么是顺序表? 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
//接口的实例化:
List<Integer> list1=new ArrayList<>();
//ArrayList的实例化:
ArrayList<Integer> list=new ArrayList<>();
两者区别:
ArrayList常见方法:
增: | |
---|---|
void add(int data) | 在数组最后添加元素 |
void add(int pos,int data) | 在数组某下标插入元素 |
删: | |
void remove(int toRemove) | 删除第一次出现的元素 |
void clear(); | 清空所有元素 |
查: | |
boolean contains(int toFind) | 查看是否包含该元素 |
int get(int pos) | 获取该下标元素 |
int indexOf(int toFind ) | 获取该元素下标 |
改: | |
void set(int pos,int value) | 将下标元素进行更改 |
ArrayList方法的使用:
public static void main(String[] args) {
List<Integer> list1=new ArrayList<>();
//增:
//add:尾插
list1.add(1);
list1.add(2);
list1.add(3);
list1.add(4);
list1.add(5);
System.out.println(list1);//[1, 2, 3, 4, 5]
//add:任意位置插入
list1.add(3,100);
System.out.println(list1);//[1, 2, 3, 100, 4, 5]
//查:
//contains:是否包含该元素
System.out.println(list1.contains(11));//false
//get:获取下标元素
int ret=list1.get(3);
System.out.println(ret);//100
//indexOf:获取元素下标
int ret2=list1.indexOf(4);
System.out.println(ret2);//4
//改
//set:将某下标的元素进行更改
list1.set(1,13);
System.out.println(list1);//[1, 13, 3, 100, 4, 5]
//删:
// remove:删除第一次出现的元素
list1.remove(2);
list1.remove(3);
//list1.remove(6);//超出范围,报错
System.out.println(list1);//[1, 13, 100, 5]
//清空
list1.clear();
System.out.println(list1);//无
//大小的获取:
System.out.println(list1.size());
}
ArrayList的遍历可以使用三种方法:for循环、foreach、使用迭代器
示例:
public static void main(String[] args) {
List<Integer> list1=new ArrayList<>();
list1.add(1);
list1.add(2);
list1.add(3);
list1.add(4);
list1.add(5);
}
for循环:
//for循环语句:
//list1.size():list1长度
for (int i = 0; i < list1.size(); i++) {
//get(i):获取i下标的元素
System.out.print(list1.get(i)+" ");//1 2 3 4 5
}
foreach语句:
//foreach:
//每次循环时,取出list中的一个元素,将该元素赋值给变量num中
for (Integer num:list1) {
System.out.print(num+" ");//1 2 3 4 5
}
迭代器:Iterator和ListIterator
//迭代器:
//从前往后打印
// Iterator
System.out.println("=====Iterator=====");
Iterator<Integer> a=list1.iterator();
//a.hasNext():用于判断集合a中是否还有下一个元素,如果有返回true,没有返回false
while(a.hasNext()){
//a.next:返回迭代器当前所指向的元素,然后指向下一个元素未被遍历的元素并打印
System.out.print(a.next()+" ");
}
System.out.println();
//listIterator
System.out.println("=====listIterator=====");
ListIterator<Integer> b=list1.listIterator();
while(b.hasNext()){
System.out.print(b.next()+" ");//1 2 3 4 5
}
System.out.println();
System.out.println("=====listIterator=====");
//从后往前打印
ListIterator<Integer> c=list1.listIterator(list1.size());
//b.hasPrevious():用于判断集合a中是否有上一个元素,如果有返回true,没有返回false
while(b.hasPrevious()){
//b.previous:返回迭代器当前所指向的元素,然后指向上一个元素未被遍历的元素并打印
System.out.print(b.previous()+" ");//5 4 3 2 1
}
Iterator和Listiterator的区别:
由于ArrayList不适合进行频繁的插入和删除元素,所以在Java集合中引入了LinkedList,即链表结构。
LinkedList的底层是双向链表结构,是链表的一种。
什么是链表? 链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据域和指针域。链表逻辑顺序是连续的,在物理存储结构是非连续的。 链表的分类: 有头链表或者无头链表:
以下分类都有分为是否是有头链表还是无头链表:
LinkedList<Integer> list1=new LinkedList<>();
其常用方法与ArrayList相差不大
public static void main(String[] args) {
LinkedList<Integer> list1=new LinkedList<>();
//增:
//add:尾插
list1.add(1);
list1.add(2);
list1.add(3);
list1.add(4);
list1.add(5);
System.out.println(list1);//[1, 2, 3, 4, 5]
//add:任意位置插入
list1.add(3,100);
System.out.println(list1);//[1, 2, 3, 100, 4, 5]
//查:
//contains:是否包含该元素
System.out.println(list1.contains(11));//false
//get:获取下标元素
int ret=list1.get(3);
System.out.println(ret);//100
//indexOf:获取元素下标
int ret2=list1.indexOf(4);
System.out.println(ret2);//4
//改
//set:将某下标的元素进行更改
list1.set(1,13);
System.out.println(list1);//[1, 13, 3, 100, 4, 5]
//删:
// remove:删除第一次出现的元素
list1.remove(2);
list1.remove(3);
//list1.remove(6);//超出范围,报错
System.out.println(list1);//[1, 13, 100, 5]
//清空
list1.clear();
System.out.println(list1);//无
//大小的获取:
System.out.println(list1.size());//0
}
遍历的三种方式:for循环,foreach、迭代器
public static void main(String[] args) {
LinkedList<Integer> list1=new LinkedList<>();
list1.add(1);
list1.add(2);
list1.add(3);
list1.add(4);
list1.add(5);
//for循环语句:
for (int i = 0; i < list1.size(); i++) {
int ret=list1.get(i);
System.out.print(ret+" ");//1 2 3 4 5
}
System.out.println();
//foreach
for (Integer x:list1) {
System.out.print(x+" ");//1 2 3 4 5
}
System.out.println();
//迭代器:
Iterator<Integer> a=list1.iterator();
while (a.hasNext()){
System.out.print(a.next()+" ");//1 2 3 4 5
}
System.out.println();
ListIterator b=list1.listIterator();
while (b.hasNext()){
System.out.print(b.next()+" ");//1 2 3 4 5
}
System.out.println();
ListIterator c=list1.listIterator(list1.size());
while(c.hasPrevious()){
System.out.print(c.previous()+" ");//5 4 3 2 1
}
}
不同点 | ArrayList | LinkedList |
---|---|---|
数据结构 | 逻辑上和物理上都是连续的 | 在逻辑上连续,物理上不连续 |
随机访问 | 随机访问效率快, 时间复杂度为O(1) | 随机访问效率慢, 时间复杂度为O(n) |
插入或删除 | 效率慢, 时间复杂度为O(n) | 效率快, 时间复杂度为O(1) |
容量 | 空间不够需要扩容 | 没有容量限制 |
内存占用 | 内存利用相对高效 | 内存利用率低 |
应用场景 | 元素访问+高效存储 | 插入和删除频繁 |