Java学习日记——List接口

什么是List

List接口是在Java中继承自Collection接口,是一个有序的集合,用来存储一组数据,可以暂且的将他理解成一个数组来看待,但是他比起数组有着更丰富快捷的使用方法。

 List的特点

有序、允许值的重复

实现类

ArrayList类

数据结构

ArrayList基于Object[ ]数组实现Object[ ]ElementData

扩容方式

初始化

1.public ArrayList( )——无参构造方法,将内部数组初始化为一个长度位0的数组。

eg.

public static void main(String[] args) {
        ArrayList<String> str=new ArrayList<>();
    }

2.public ArrayList(int initialCapacity)——将内部数组初始化为一个长度为()中数字长度的数组

有利于后续输入数组时,扩容对资源的占用。

eg.

 public static void main(String[] args) {
        ArrayList<String> str=new ArrayList<>(10);
    }
扩容

1.如果使用了无参构造方法来创建ArrayList则默认长度为0,担当添加任何一个元素后,数组的长度就会扩容至10.

2.当数组元素被添加满担当前容量,则数组的长度会自动扩容至原来容量的1.5倍。

3.数组的最大容量在Integer.MAX_VALUE-8至Integer.MAX_VALUE之间,如果超出,则抛出OutOfMemoryError错误

Ps

这里就可以体现出为何要使用ArrayList的有参构造方法来初始化内部数组的长度,因为每当数组内元素数量多出该数组的长度后,JVM会自动将此数组扩容至其原来的1.5倍,如果数组的元素过多,扩容多次的话,每次的扩容就会对资源进行占用造成资源浪费,这时就不如程序员在开发过程中就对数组内元素数量进行一个预估,给内部数组初始化一个大致的长度,来减少数组扩容对资源的占用。

适用场景

ArrayList 适合数据连续性遍历,读多写少的场景

常用方法

添加新元素

1.boolean add(E e)——添加新元素至集合尾部

2.void add(int index, E element)——添加新元素至集合指定下标位置

3.boolean addAll(Collection c)——添加集合内所有元素至当前集合

eg.

public static void main(String[] args) {
        ArrayList<String> list=new ArrayList<>();
        list.add("貂蝉");
        list.add("貂蝉");
        list.add(1,"小乔");
        list.addAll(Arrays.asList("南拳妈妈","腾格尔","奥斯特洛夫斯基","张杰","易烊千玺","信","梦龙乐队","伍佰"));
        System.out.println(list);
    }
//输出内容
//[貂蝉, 小乔, 貂蝉, 南拳妈妈, 腾格尔, 奥斯特洛夫斯基, 张杰, 易烊千玺, 信, 梦龙乐队, 伍佰]
获取元素

1.E get(int index)——获取指定位置下标的元素

2.List<E> subList(int fromIndex, int toIndex)——按照指定下标区间截取子集合

eg.

public static void main(String[] args) {
        ArrayList<String> list=new ArrayList<>();
        list.add("貂蝉");
        list.add("貂蝉");
        list.add(1,"小乔");
        list.addAll(Arrays.asList("南拳妈妈","腾格尔","奥斯特洛夫斯基","张杰","易烊千玺","信","梦龙乐队","伍佰"));
        String s= list.get(3);
        List<String> str1=new ArrayList<>(list.subList(4,8));
        System.out.println(s);
        System.out.println(str1);
    }
//输出内容
//南拳妈妈
//[腾格尔, 奥斯特洛夫斯基, 张杰, 易烊千玺]
判断元素

1.boolean contains(Object o)——判断集合中是否存在元素

2.boolean equals(Object o)——判断两个集合中的元素是否相同

3.int indexOf(Object o)——查找指定元素的下标位置,如果不存在,则返回-1

eg.

public static void main(String[] args) {
        ArrayList<String> list=new ArrayList<>();
        list.add("貂蝉");
        list.add("貂蝉");
        list.add(1,"小乔");
        list.addAll(Arrays.asList("南拳妈妈","腾格尔","奥斯特洛夫斯基","张杰","易烊千玺","信","梦龙乐队","伍佰"));
        ArrayList<String> list2=new ArrayList<>();
        list2.addAll(Arrays.asList("貂蝉","小乔","貂蝉","南拳妈妈","腾格尔","奥斯特洛夫斯基","张杰","易烊千玺","信","梦龙乐队","伍佰"));
        ArrayList<String> list3=new ArrayList<>();
        //判断数组中是否含有元素:
        System.out.println(list.contains("伍佰"));
        System.out.println(list.contains("五百"));
        System.out.println("=====================");
        //判断两个集合的元素是否相等
        System.out.println(list);
        System.out.println(list2);
        System.out.println(list3);
        System.out.println(list.equals(list2));
        System.out.println(list.equals(list3));
        System.out.println("======================");
        //查找指定元素下标,有则返回下标,无则返回-1
        System.out.println(list.indexOf("伍佰"));
        System.out.println(list.indexOf("五百"));
    }
/*输出内容
true
false
=====================
[貂蝉, 小乔, 貂蝉, 南拳妈妈, 腾格尔, 奥斯特洛夫斯基, 张杰, 易烊千玺, 信, 梦龙乐队, 伍佰]
[貂蝉, 小乔, 貂蝉, 南拳妈妈, 腾格尔, 奥斯特洛夫斯基, 张杰, 易烊千玺, 信, 梦龙乐队, 伍佰]
[]
true
false
======================
10
-1
*/
删除元素

1.void clear()——清空集合

public static void main(String[] args) {
            ArrayList<String> list = new ArrayList<>();
            list.addAll(Arrays.asList("貂蝉", "小乔", "貂蝉", "南拳妈妈", "腾格尔", "奥斯特洛夫斯基", "张杰", "易烊千玺", "信", "梦龙乐队", "伍佰"));
            list.clear();
            System.out.println(list);
        }
//输出
//[]

2.boolean remove(Object o)——删除指定内容的元素

public static void main(String[] args) {
        ArrayList<String> list=new ArrayList<>();
        list.addAll(Arrays.asList("貂蝉","小乔","貂蝉","南拳妈妈","腾格尔","奥斯特洛夫斯基","张杰","易烊千玺","信","梦龙乐队","伍佰"));
        System.out.println("原数组"+list);
        list.remove("易烊千玺");
        System.out.println("删除指定元素\"易烊千玺\"后的数组"+list);
    }
/*输出内容
原数组[貂蝉, 小乔, 貂蝉, 南拳妈妈, 腾格尔, 奥斯特洛夫斯基, 张杰, 易烊千玺, 信, 梦龙乐队, 伍佰]
删除指定元素下标"7"后的数组[貂蝉, 小乔, 貂蝉, 南拳妈妈, 腾格尔, 奥斯特洛夫斯基, 张杰, 信, 梦龙乐队, 伍佰]
*/

3.E remove(int index)——删除指定位置的元素

 public static void main(String[] args) {
        ArrayList<String> list=new ArrayList<>();
        list.addAll(Arrays.asList("貂蝉","小乔","貂蝉","南拳妈妈","腾格尔","奥斯特洛夫斯基","张杰","易烊千玺","信","梦龙乐队","伍佰"));
        System.out.println("原数组"+list);
        list.remove(7);
        System.out.println("删除指定元素下标\"7\"后的数组"+list);
    }
/*输出内容
原数组[貂蝉, 小乔, 貂蝉, 南拳妈妈, 腾格尔, 奥斯特洛夫斯基, 张杰, 易烊千玺, 信, 梦龙乐队, 伍佰]
删除指定元素下标"7"后的数组[貂蝉, 小乔, 貂蝉, 南拳妈妈, 腾格尔, 奥斯特洛夫斯基, 张杰, 信, 梦龙乐队, 伍佰]
*/

4.boolean removeAll(Collection c)——删除当前集合与指定集合的相同元素

 public static void main(String[] args) {
        ArrayList<String> list=new ArrayList<>();
        list.addAll(Arrays.asList("貂蝉","小乔","貂蝉","南拳妈妈","腾格尔","奥斯特洛夫斯基","张杰","易烊千玺","信","梦龙乐队","伍佰"));
        ArrayList<String> list2=new ArrayList<>();
        list2.addAll(Arrays.asList("GGBond","SpiderMan","IronMan","Thor","奥斯特洛夫斯基","张杰","易烊千玺","信","梦龙乐队","伍佰"));
        System.out.println("原数组list"+list);
        System.out.println("原数组list2"+list2);
        list.removeAll(list2);
        System.out.println("删除当前集合与指定集合的相同元素\"list2\"后的数组"+list);
    }
/*输出内容
原数组list[貂蝉, 小乔, 貂蝉, 南拳妈妈, 腾格尔, 奥斯特洛夫斯基, 张杰, 易烊千玺, 信, 梦龙乐队, 伍佰]
原数组list2[GGBond, SpiderMan, IronMan, Thor, 奥斯特洛夫斯基, 张杰, 易烊千玺, 信, 梦龙乐队, 伍佰]
删除当前集合与指定集合的相同元素"list2"后的数组[貂蝉, 小乔, 貂蝉, 南拳妈妈, 腾格尔]
*/

5.boolean retainAll(Collection c)——保留当前集合与指定集合的相同元素,删除其余元素

public static void main(String[] args) {
        ArrayList<String> list=new ArrayList<>();
        list.addAll(Arrays.asList("貂蝉","小乔","貂蝉","南拳妈妈","腾格尔","奥斯特洛夫斯基","张杰","易烊千玺","信","梦龙乐队","伍佰"));
        ArrayList<String> list2=new ArrayList<>();
        list2.addAll(Arrays.asList("GGBond","SpiderMan","IronMan","Thor","奥斯特洛夫斯基","张杰","易烊千玺","信","梦龙乐队","伍佰"));
        System.out.println("原数组list"+list);
        System.out.println("原数组list2"+list2);
        list.retainAll(list2);
        System.out.println("保留当前集合与\"list2\"集合的相同元素,删除其余元素后的数组"+list);
    }
/*
输出内容
原数组list[貂蝉, 小乔, 貂蝉, 南拳妈妈, 腾格尔, 奥斯特洛夫斯基, 张杰, 易烊千玺, 信, 梦龙乐队, 伍佰]
原数组list2[GGBond, SpiderMan, IronMan, Thor, 奥斯特洛夫斯基, 张杰, 易烊千玺, 信, 梦龙乐队, 伍佰]
保留当前集合与"list2"集合的相同元素,删除其余元素后的数组[奥斯特洛夫斯基, 张杰, 易烊千玺, 信, 梦龙乐队, 伍佰]
*/
修改元素

E set(int index, E element)——将指定下标位置的元素,修改为指定新元素

public static void main(String[] args) {
            ArrayList<String> list = new ArrayList<>();
            list.addAll(Arrays.asList("貂蝉", "小乔", "貂蝉", "南拳妈妈", "腾格尔", "奥斯特洛夫斯基", "张杰", "易烊千玺", "信", "梦龙乐队", "伍佰"));
            System.out.println("原数组"+list);
            list.set(1,"大乔");
            System.out.println("修改后的数组"+list);
        }
/*
输出内容
原数组[貂蝉, 小乔, 貂蝉, 南拳妈妈, 腾格尔, 奥斯特洛夫斯基, 张杰, 易烊千玺, 信, 梦龙乐队, 伍佰]
修改后的数组[貂蝉, 大乔, 貂蝉, 南拳妈妈, 腾格尔, 奥斯特洛夫斯基, 张杰, 易烊千玺, 信, 梦龙乐队, 伍佰]
*/
排序

void sort(Comparator c)——按照Comparator接口实现类的比较规则,对集合内的元素进行排序

 public static void main(String[] args) {
            ArrayList<String> list = new ArrayList<>();
            list.addAll(Arrays.asList("貂蝉", "小乔", "貂蝉", "南拳妈妈", "腾格尔", "奥斯特洛夫斯基", "张杰", "易烊千玺", "信", "梦龙乐队", "伍佰"));
            list.sort(null);//使用默认排序方法
            System.out.println("修改后的数组"+list);
        }
/*
输出内容
修改后的数组[伍佰, 信, 南拳妈妈, 奥斯特洛夫斯基, 小乔, 张杰, 易烊千玺, 梦龙乐队, 腾格尔, 貂蝉, 貂蝉]
*/

若想按照自己自定义的方法排序则可重写Comparator方法

转换

T[ ] toArray(T[ ] a)——将当前集合转换为数组

public static void main(String[] args) {
            ArrayList<String> list = new ArrayList<>();
            list.addAll(Arrays.asList("貂蝉", "小乔", "貂蝉", "南拳妈妈", "腾格尔", "奥斯特洛夫斯基", "张杰", "易烊千玺", "信", "梦龙乐队", "伍佰"));
            list.toArray();
            System.out.println(list);
        }
/*
输出内容
修改后的数组[貂蝉, 小乔, 貂蝉, 南拳妈妈, 腾格尔, 奥斯特洛夫斯基, 张杰, 易烊千玺, 信, 梦龙乐队, 伍佰]
*/
迭代器

1.Iterator<E> iterator()——该迭代器仅提供向后遍历

2.ListIterator<E> listIterator(int index)——该迭代器提供向前或向后遍历,并提供添加元素的操作

public static void main(String[] args) {
        ArrayList<String> list=new LinkedList<>();
        list.add("晁盖");
        list.addFirst("宋江");
        list.add(0,"武松");
        list.addLast("悟空");
        System.out.println(list);
        System.out.println("==========================");

        String item= list.get(1);
        String first= list.getFirst();
        String last= list.getLast();
        System.out.println(item);
        System.out.println(first);
        System.out.println(last);
        System.out.println("==========================");

        System.out.println("for循环正序遍历");
        for (int i=0;i<list.size();i++){
            System.out.println(list.get(i));
        }
        System.out.println("正序遍历迭代器");
        Iterator<String> it= list.iterator();
        while (it.hasNext()){
            String name=it.next();
            System.out.println(name);
        }
        System.out.println("逆序遍历迭代器");
        ListIterator<String> it1= list.listIterator(list.size());
        while (it1.hasPrevious()){
            String name=it1.previous();
            System.out.println(name);
        }


    }
/*
[武松, 宋江, 晁盖, 悟空]
==========================
宋江
武松
悟空
==========================
for循环正序遍历
武松
宋江
晁盖
悟空
正序遍历迭代器
武松
宋江
晁盖
悟空
逆序遍历迭代器
悟空
晁盖
宋江
武松

进程已结束,退出代码0

*/

LinkedList类

数据结构

LinkedList是基于双向链表实现,链表中的每个节点都是一个Node类型的对象,Node对象由item、prev、next三部分组成

扩容方式

由于采用链表结构,每次添加元素,都会创建新的Node节点并分配空间,所以不存在扩容

适用场景

适合数据频繁添加删除操作,写多读少的场景

常用方法

添加元素

1.boolean add(E e)——添加新元素至链表尾部

2.void addFirst(E e)——添加新元素至链表头部

3.void addLast(E e)——添加新元素至链表尾部

public static void main(String[] args) {
        LinkedList linked=new LinkedList<>();
        linked.add("张飞");
        linked.add("张飞");
        linked.addFirst("李逵");
        linked.add("张飞");
        linked.add("张飞");
        linked.addLast("黄盖");
        System.out.println(linked);
    }
/*
输出内容
[李逵, 张飞, 张飞, 张飞, 张飞, 黄盖]
*/
获取元素

1.E get(int index)——遍历链表,查找指定位置的元素

2.E getFirst()——获取链表中的头元素

3.E getLast()——获取链表中的尾元素

 public static void main(String[] args) {
        LinkedList linked=new LinkedList<>();
        linked.add("张飞");
        linked.add("张飞");
        linked.addFirst("李逵");
        linked.add("张飞");
        linked.add("张飞");
        linked.addLast("黄盖");
        System.out.println(linked.get(5));
        System.out.println(linked.getFirst());
        System.out.println(linked.getLast());
    }
/*
输出内容
黄盖
李逵
黄盖
*/
判断元素

int indexOf(Object o)——查找链表中的指定元素的下标位置,如果不存在,则返回-1

public static void main(String[] args) {
        LinkedList linked=new LinkedList<>();
        linked.add("张飞");
        linked.add("张飞");
        linked.addFirst("李逵");
        linked.add("张飞");
        linked.add("张飞");
        linked.addLast("黄盖");
        System.out.println(linked.indexOf("李逵"));
        System.out.println("李白");
    }
/*
输出内容
0
李白
*/
删除元素

1.E remove()——删除链表中的头元素

2.boolean remove(Object o)——删除指定内容的元素

3.E remove(int index)——删除指定位置的元素

4.E removeFirst()——删除链表中的头元素

5.E removeLast()——删除链表中的尾元素

public static void main(String[] args) {
        LinkedList linked=new LinkedList<>();
        linked.add("0");
        linked.add("1");
        linked.add("2");
        linked.add("3");
        linked.add("4");
        linked.add("5");
        linked.add("6");
        linked.add("7");
        linked.add("8");
        linked.add("9");
        linked.remove();
        System.out.println("删除链表中的头元素"+linked);
        linked.remove("4");
        System.out.println("删除指定内容的元素\"4\""+linked);
        linked.remove(5);
        System.out.println("删除指定下标内容的元素\"5\""+linked);
        linked.removeFirst();
        System.out.println("删除链表中的头元素\"5\""+linked);
        linked.removeLast();
        System.out.println("删除链表中的尾元素\"5\""+linked);
        

    }
/*
输出内容
删除链表中的头元素[1, 2, 3, 4, 5, 6, 7, 8, 9]
删除指定内容的元素"4"[1, 2, 3, 5, 6, 7, 8, 9]
删除指定下标内容的元素"5"[1, 2, 3, 5, 6, 8, 9]
删除链表中的头元素"5"[2, 3, 5, 6, 8, 9]
删除链表中的尾元素"5"[2, 3, 5, 6, 8]
*/
default void sort(Comparator c)

按照Comparator比较器,将链表中的所有元素进行排序

public static void main(String[] args) {
        LinkedList linked=new LinkedList<>();
        linked.add("0");
        linked.add("1");
        linked.add("2");
        linked.add("3");
        linked.add("4");
        linked.add("5");
        linked.add("6");
        linked.add("7");
        linked.add("8");
        linked.add("9");
        linked.sort(null);//默认比较方法
        System.out.println(linked);
    }
/*
输出
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
*/
T[ ] toArray(T[ ] a)

将链表转换成数组

public static void main(String[] args) {
        LinkedList linked=new LinkedList<>();
        linked.add("0");
        linked.add("1");
        linked.add("2");
        linked.add("3");
        linked.add("4");
        linked.add("5");
        linked.add("6");
        linked.add("7");
        linked.add("8");
        linked.add("9");
        linked.toString();
        System.out.println(linked);
    }
/*
输出
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
*/

Vector类

Stack类

常见问题

ArrayList和LinkedList的区别

实现方式

ArrayList底层是通过数组实现的,而LinkedList底层是通过链表实现的,所以ArrayList在进行增删改查的时候,会使得其他元素移动来保持数组的连续性。而LinkedList底层由于是通过链表实现,它的存储方式是通过节点链接下一个节点来存储元素,所以LinkedList进行增删改查的时候只需要修改节点的引用即可。

访问效率

ArrayList可直接通过下标来访问元素,更加的快捷

LinkedList是通过遍历来访问元素,访问效率取决于元素存储的位置

插入和删除的效率

ArrayList由于底层使用数组实现,所以在增删改元素时需要同时对其他受影响的元素也进行改变,所以复杂度更高

LinkedList由于底层使用链表实现,所以在增删改元素时只需要改变节点的引用即可,无需对其他元素负责,复杂度更低

ArrayList和Vector的区别

线程安性

ArrayList 是非线程安全的,多个线程同时操作一个 ArrayList 实例可能会导致数据不一致的问题。

Vector 是线程安全的,它的方法都是通过 synchronized 关键字实现的,保证了多个线程对同一个 Vector 实例的安全访问。因为要进行同步,所以在性能上相对于 ArrayList 会有一些影响。

动态增长

ArrayList 和 Vector 都支持动态增长,即在不断添加元素时,集合的容量会根据需要自动扩展。它们都提供了相似的方法来控制集合的初始容量和扩容倍数。

不同之处在于,ArrayList 的扩容策略是当前容量不够时增加 50% 的容量,而 Vector 是增加当前容量的一倍。

ArrayList的扩容方式

请看此篇文章   实现类=>ArrayList类=>扩容方式   段

LinkedList的适用场景

更具以上内容,LinkedList的使用场景可以是在有频繁的插入和删除场景中

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值