java集合--- list接口下的ArrayList、LinkedList、Stack

一、List接口
1、 List接口:是Collection接口的子接口,也是最常用的接口。此接口对Collection接口进行了大量的扩充,存储的内容是允许有重复,允许有null并且有序的。有序为插入的顺序。
2、List接口特点是Collection接口的子接口,也是最常用的接口。此接口对Collection接口进行了大量的扩充,里面的内容是1)允许重复 2)允许为NULL 3)并且有序(插入的顺序)。
3、List接口常用的实现类有3个:ArrayList、LinkedList、Vector。
二、ArrayList
ArrayList是一种变长的集合类,基于定长数组实现
1、特点: ArrayList具有List接口所具有的特点。
ArrayList特点:适合做随机访问操作,不适合做随机的插入或者删除操作。
缺点:随机的插入删除时,ArrayList会伴随大量的数据移动工作是非常耗时的。
2、List接口的继承
ArrayList:public class ArrayList extends AbstractList
implements List, RandomAccess, Cloneable, java.io.Serializable
3、Arraylist的基本使用
添加:
public void add(int index,Object o){
rangeCheck(index);
ensureCapacityInternal(size + 1);
System.arraycopy(arr,index,arr,index+1,size-index);
arr[index] = o;
size++;
}
删除:
public void remove1(int index){
rangeCheck(index);
System.arraycopy(arr,index+1,arr,index,size-index-1);
arr[–size] = null; //最后一位为空,不占用空间,可以GC
}
修改:
public void set(int index,T newValue){
rangeCheck(index);
arr[index] = newValue;
}
查找:
public T get(int index){
rangeCheck(index);
return (T)arr[index];
}
4、ArrayList–交集、并集、差集、子集
(1)交集:两个集合的共同部分
实现方法:list.retainAll(list2);
(2)并集:两个集合相并
实现方法:一个集合+(另一个集合的-交集)
arrList2.removeAll(arrList1); //集合2-交集
list3.addAll(arrList1);
list3.addAll(arrList2);
(3)差集:一个集合-交集
arrList1.removeAll(arrList2);
(4)子集:subList();
subList(int fromIndex, int toIndex)
List ll = list2.subList(1,3); //ll集合为list2中在下标区间[1,3)之间的元素,为list2的一子集合
5、遍历
用for循环进行遍历:
for (int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
用foreach遍历:
System.out.println(“");
for (Object a:list){
System.out.println(a);
}
iterator迭代器对象的遍历方式:
System.out.println("
”);
Iterator iterator=list.iterator();
while (iterator.hasNext()){//判断Arraylist中是否还有新的元素
Character next=iterator.next();
System.out.println(next);//获取Arraylist是否还有新的元素
}
ListItertor迭代器遍历:
//从前往后遍历
System.out.println(“");
ListIterator IsIterator=list.listIterator();
while(IsIterator.hasNext()){
System.out.println(IsIterator.next());
}
从后往前遍历
System.out.println("
”);
ListIterator IsIterator1= list.listIterator(26);
while(IsIterator.hasPrevious()){
System.out.println(IsIterator1.previous());
}

三、LinkList

  1. LinkedList接口特性
    (1)底层结构:双向链表
    LinkedList:即是List接口的集合,又是queue接口下的集合
    (2)实现的接口:
    implements List, Deque, Cloneable, java.io.Serializable
    List:存放单值,内容允许为null允许重复,插入有序(插入的顺序)插入的第一个元素为双向链表的头结点
    Deque:queue的子接口,双端队列接口,即双端队列,是一种具有队列和栈的性质的数据结构
    Cloneable:集合可以使用clone方法
    Serializable:可序列化,表示LinkedList可以进行可序列化操作
    (3)内部类:
    private class ListItr implements ListIterator
    是Iterator接口的子接口,可以进行双向输出
    private class DescendingIterator implements Iterator
    可以使用迭代器遍历的,从前向后进行遍历。
  2. LinkedList基本使用
    LinkedList linkedList = new LinkedList<>();
    添加元素
    linkedList.add(i);
    修改元素:
    public void set(int index,E newValue){
    rangeCheck(index);
    Node x = nodeIndex(index);
    E oldValue = x.item;
    x.item = newValue;
    }

添加元素:
//尾插
public void add(E item){
Node last = tail;
Node newNode = new Node(item,last,null);
if (last == null){
head = newNode;
}else{
last.next = newNode;
}
tail = newNode;
size++;
}

//随机插入 LinkedList不适合随机访问
public void add(int index,E item) {
rangeCheck(index);
//判断index == size 等于 尾插
if (index == size){
add(item);
return;
}
Node s = nodeIndex(index);
Node p = s.prev;
Node newNode = new Node(item,p,s);
p.next = newNode;
s.prev = newNode;
if (p == null){
head = newNode;
}else{
p.next = newNode;
}
size++;
}
删除元素:
public void remove1(int index){
rangeCheck(index);
Node s = nodeIndex(index);
Node p = s.prev;
Node n = s.next;
s.item = null;
if (p == null) {
head = n;
} else {
p.next = n;
s.prev = null;
}
if (n == null) {
tail = p;
} else {
n.prev = p;
s.next = null;
}
size–;
}
四、Vector
1.Vector接口特性
(1)Vector:实现类似动态数组的功能,线程安全。
特点:与ArrayList特点几乎一样
(2)实现类:
implements List, RandomAccess, Cloneable, java.io.Serializable
List:存放单值,内容允许为null允许重复,插入有序(插入的顺序)插入的第一个元素为双向链表的头结点
RandomAccess:表示ArrayList可被随机访问
Cloneable:集合可以使用clone方法
Serializable:可序列化,表示LinkedList可以进行可序列化操作
(3)内部类:
private class Itr implements Iterator
可以使用迭代器遍历的,从前向后进行遍历。
final class ListItr extends Itr implements ListIterator
是Iterator接口的子接口,可以进行双向输出
2.Vector基本操作
添加:
add(E item);
add(int index, E item);
删除:
remove(object o);
remove(int index);
获取:
get(int index);
修改:
set(int index, E item);
五、Stack
1.Stack接口特性
栈:利用vector实现了一个栈,线程安全。
class Stack extends Vector
2.Stack基本使用
添加:push();
取出栈顶元素并删除:pop();
取出栈顶元素不删除:peek();
六、总结
1、LinkedList和ArrayList的一大区别
从方法进行对比
get(int index) 方法:通过下标返回对应的元素
(1)ArrayList为底层是数组,可以直接通过下标去拿对应的元素
(2)LinkedList为双向链表,只能一边遍历一边计数,直到计数到index位置上,然后将数据返回,因此LinkedList不适合做随机访问操作。
add(int index); remove(int index);
(1)ArrayList在实现的时候,有大量的数据移动和拷贝,比如在指定下标进行添加,该下标及后面的元素需要向后移动,删除元素后需要向前移动,扩容涉及到数据拷贝,效率低,时间复杂度为O(n),不适合做随机的插入和删除。
(2)LinkedList插入和删除时不需要移动数据,只需要改节点的前驱和后继地址,所以LInkedList适合做数据的插入和删除
总结:
ArrayList适合随机访问,不适合插入和删除操作
LinkedList适合插入删除操作,不适合随机访问
2、ArrayList 和Vector的异同
1)从继承的接口来看:
实现的接口相同,特点相同
2)底层实现上来看
都是数组实现,调用方法没有区别
3)从源码上来看
a:
ArrayList 的初始数组大小为空
Vector的初始数组大小为10
b:
扩容方法:Vector更合理
ArrayList 以1.5倍扩容,如果目前元素时1000,再增加1个,则要1.5倍扩容,会造成499个空间的浪费。
Vector默认2倍扩容,如果增长因子大于零,则扩容增长因子个大小。
c:
线程安全问题:
Vector:方法都用了Synchronized 来修饰,是线程安全
ArrayList :没有加锁是线程不安全的
4)使用场景
如果需要考虑线程安全问题,则选择Vector
如果不考虑线程安全问题,则选择ArrayList
(为什么不考虑线程安全问题时不使用Vector?
答:加锁操作是非常耗时的)
3、什么时候该用vector,什么时候用ArrayList
使用场景:线程安全问题
多线程条件下需要考虑线程安全问题选择Vector,如果不考虑则使用ArrayList
不用考虑线程安全问题时为什么不使用Vector:加锁操作非常耗时
4、什么时候该用LinkedList,什么时候用ArrayList
LinkedList更适合添加删除方法比较频繁的操作,因为不会有数据的移动
ArrayList随机的添加删除时,会造成数据的移动,导致效率过低。ArrayList适合于随机访问操作比较频繁的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值