当前位置: 首页 > article >正文

《Java核心技术 卷I》链表

链表

ArrayList底层是数组,增删慢。

集合框架中的类

从数组中删除一个元素

链表(linked list)解决这个问题,在Java程序中所有链表实际上是双向链接(doubly linked),每个链接存放前面的引用。

删除元素很容易,将前后引用对象指向另一个就可以了。

小练习,增加5个元素,然后将第2个元素删除

package collection;

import java.util.Iterator;
import java.util.LinkedList;

public class LinkedListTest {

    public static void main(String[] args) {
        var staff = new LinkedList<String>();
        staff.add("Amy");
        staff.add("Bob");
        staff.add("Carl");
        staff.add("Dog");
        staff.add("Egg");
        Iterator<String> iter = staff.iterator();
        String f = iter.next();
        String s = iter.next();
        System.out.println(f);
        iter.remove();
        iter = staff.iterator();
        iter.forEachRemaining((e)->{
            System.out.println(e);
        });
    }
}

结果:Amy Amy Carl Dog Egg

Iterator接口中没有add方法,提供子接口ListIterator包含add方法,返回值为void,假定add操作总是能增加元素。

ListIterator接口有两个方法,E previous()和hasPrevious()用来反向遍历链表。

LinkedList返回了一个ListIterator接口的迭代器对象。

小案例

package collection;

import java.util.LinkedList;
import java.util.ListIterator;

public class LinkedListListIteratorTest {

    public static void main(String[] args) {
        var staff = new LinkedList<String>();
        staff.add("Amy");
        staff.add("Bob");
        staff.add("Carl");
        staff.add("Dog");
        staff.add("Egg");
        ListIterator<String> iter = staff.listIterator();
        iter.next();//略过第一个元素
        iter.add("Juliet");
        iter = staff.listIterator();
        iter.forEachRemaining((e)->{
            System.out.print(e+" ");
        });
    }

}
//结果:Amy Juliet Bob Carl Dog Egg 

不略过任何元素,则当前元素插入后为表头,若迭代器越过链表最后一个元素(hasNext返回false),插入的元素称为列表的新表尾。

链表有n个元素,会有n+1个位置可以添加新元素。

ABC三个元素就有4个位置,|ABC A|BC AB|C ABC|

set方法用新元素替换调用next和previous方法返回上一个元素。

某个迭代器修改集合,另一个迭代器访问,会出错,抛出ConcurrentModificationException异常。

package collection;

import java.util.LinkedList;
import java.util.ListIterator;

public class LinkedListListIteratorTest {

    public static void main(String[] args) {
        var staff = new LinkedList<String>();
        staff.add("Amy");
        staff.add("Bob");
        staff.add("Carl");
        staff.add("Dog");
        staff.add("Egg");
        ListIterator<String> iter1 = staff.listIterator();
        ListIterator<String> iter2 = staff.listIterator();
        iter1.next();
        iter1.remove();
        iter2.next();
    }

}
//Exception in thread "main" java.util.ConcurrentModificationException

LinkedList类提供了get方法反问特定元素,效率并不高。

注释:get方法做了一个微小的优化,如果索引大于size()/2,就从列表尾端搜索元素。

列表迭代器还有一个方法是告诉你当前位置的索引,有两个索引,nextIndex和previousIndex。

list.listIterator(n)将返回一个迭代器指向n的元素前面的位置,效率高。

java.util.List 1.2

  • ListIterator listIterator(),返回一个列表迭代器,用来访问列表中的元素。
  • ListIterator listIterator(int index),返回一个列表迭代器,访问列表中给定索引的元素。
  • void(int i,E element),在给定位置添加一个元素。
  • void addAll(int i,Collection elements),将集合中的所有元素添加到给定位置。
  • E remove(int i),删除并返回给定位置的元素。
  • E get(int i),获取给定位置的元素。
  • E set(int i,E element),用一个新元素替换给定位置的元素,并返回原来那个元素。
  • int indexOf(Object element),返回与指定元素相等的元素在列表中第一次出现的位置,如果没有这样的元素则返回-1。
  • int lastIndexOf(Object element),返回与指定元素相等的元素在列表中最后一次出现的位置,如果没有这样的元素将返回-1。

java.util.ListIterator 1.2

  • void add(E newElement),在当前位置前添加一个元素。
  • void set(E newElement),用新元素替换next或previous访问的上一个元素。
  • boolean hasPrevious(),当反向迭代列表时,如果还有可以访问的元素,返回true。
  • E previous(),返回前一个对象,如果已经到达了列表的头部,就抛出NoSuchElementException异常。
  • int nextIndex(),返回下一次调用next方法时将返回的元素的索引。
  • int previousIndex(),返回下一次调用previous方法时将返回的元素的索引。

java.util.LinkedList 1.2

  • LinkedList(),构造一个空链表
  • LinkedList(Collection elements),构造一个链表,并将集合中所有的元素添加到这个链表中。
  • void addFirst(E element)
  • void addLast(E element),将某元素添加到列表的头部或尾部。
  • E getFirst()
  • E getLast(),返回列表头部或尾部的元素。
  • E removeFirst()
  • E removeLast(),删除并返回列表头部或尾部的元素。

 


http://www.kler.cn/a/404855.html

相关文章:

  • kafka中是如何快速定位到一个offset的
  • UE5 5.1.1创建C++项目,显示error C4668和error C4067的解决方法
  • sed使用扩展正则表达式时, -i 要写在 -r 或 -E 的后面
  • iOS应用网络安全之HTTPS
  • IDEA2019搭建Springboot项目基于java1.8 解决Spring Initializr无法创建jdk1.8项目 注释乱码
  • 集合卡尔曼滤波(Ensemble Kalman Filter),用于二维滤波(模拟平面上的目标跟踪),MATLAB代码
  • 多目标优化算法:多目标吸血水蛭优化算法(MOBSLO)求解DTLZ1-DTLZ9,提供完整MATLAB代码
  • 集合卡尔曼滤波(Ensemble Kalman Filter),用于二维滤波(模拟平面上的目标跟踪),MATLAB代码
  • 机器学习——数据隐私与安全学习
  • 排序算法:直接插入排序,希尔排序,选择排序,快速排序,堆排序,归并排序
  • 【IEEE独立出版 |往届均已成功检索】第八届大数据与应用统计国际学术研讨会(ISBDAS 2025)
  • C#核心(10)拓展方法
  • 机器学习:智能技术的未来
  • Vue_Router权限控制:不同角色显示不同路由
  • MySQL基础大全(看这一篇足够!!!)
  • 解决.DS_Store 在项目一致无法排除,.gitignore里也不生效
  • C++ 网络编程:打造多线程 TCP 服务器,同时服务多个客户机!
  • Qt-常用的按钮控件 QPushButton QRadioButton QCheckBox
  • Kadane 算法 二维 详解
  • 如何创建一个网站?初学者的分步指南
  • 【Apache Paimon】-- 5 -- Flink 向 Paimon 表写入数据
  • 网络编程day2.2~day3——TCP并发服务器
  • TCP Listen 队列详解与优化指南
  • springboot基于大数据技术的电影推荐系统的设计与实现
  • 区块链预言机;预言机的部署、与智能合约的关系以及是否分布式;基于Fabric联盟链与链外世界的数据交互
  • Python 之网络爬虫