Java SE入门及基础(50) Java实现LinkedList(单向链表、双向链表) Java实现栈

目录

List 接口

1. 特性描述

List 接口常用方法

2. ArrayList

示例及源码解读

3. LinkedList

示例及源码解读

单向链表

双向链表

4. 栈

练习

Java SE文章参考:Java SE入门及基础知识合集-CSDN博客

List 接口

1. 特性描述

A List is an ordered Collection (sometimes called a sequence). Lists may contain duplicate elements.
列表是有序的集合(有时称为序列)。 列表可能包含重复的元素。
The Java platform contains two general-purpose List implementations. ArrayList, which is usually the better-performing implementation, and LinkedList which offers better performance under certain circumstances.
Java 平台包含两个常用的 List 实现。 ArrayList 通常是性能较好的实现,而 LinkedList 在某些情况下可以提供更好的性能。

List 接口常用方法

E get ( int index ); // 获取给定位置的元素
E set ( int index , E element ); // 修改给定位置的元素
void add ( int index , E element ); // 在给定位置插入一个元素
E remove ( int index ); // 移除给定位置的元素
int indexOf ( Object o ); // 获取给定元素第一次出现的下标
int lastIndexOf ( Object o ); // 获取给定元素最后一次出现的下标
ListIterator < E > listIterator (); // 获取 List 集合专有的迭代器
ListIterator < E > listIterator ( int index ); // 获取 List 集合专有的迭代器,从给定的下标位置开始的迭代器
List < E > subList ( int fromIndex , int toIndex ); // 获取 List 集合的一个子集合

2. ArrayList

示例及源码解读

import java . util . ArrayList ;
import java . util . Iterator ;
import java . util . List ;
import java . util . ListIterator ;
public class ArrayListTest {
        public static void main ( String [] args ) {
        //集合有序是指存储顺序与遍历时取出来的顺序一致
        ArrayList < String > list = new ArrayList <> ();
        list . add ( "a" ); // 第一次调用 size =0;
        list . add ( "a" );
        list . add ( "b" );
        list . add ( "c" );
        list . add ( "d" );
        list . add ( 2 , "n" ); // a a b c d => a a b b c d => a a n b c d
        String old = list . set ( 1 , "g" );
        System . out . println ( old );
        System . out . println ( "====================" );
        for ( String str : list ){
                System . out . println ( str );
        }
        System . out . println ( "====================" );
        Iterator < String > iter = list . iterator ();
        while ( iter . hasNext ()){
                String s = iter . next ();
                System . out . println ( s );
        }
        System . out . println ( "====================" );
        ListIterator < String > listIterator = list . listIterator ();
        while ( listIterator . hasNext ()){
                String s = listIterator . next ();
                System . out . println ( s );
        }
        System . out . println ( "====================" );
        ListIterator < String > prevIterator = list . listIterator ( list . size ());
        while ( prevIterator . hasPrevious ()){
                String s = prevIterator . previous ();
                System . out . println ( s );
        }
        System . out . println ( "====================" );
        List < String > subList = list . subList ( 2 , 4 );
        for ( String str : subList ){
                System . out . println ( str );
        }
        System . out . println ( "====================" );
        int size = list . size ();
        for ( int i = 0 ; i < size ; i ++ ){
                String s = list . get ( i );
                System . out . println ( s );
        }
        System . out . println ( "===================" );
        ArrayList < Integer > numbers = new ArrayList <> ();
        numbers . add ( 1 );
        numbers . add ( 2 );
        numbers . add ( 3 );
        numbers . add ( 4 );
        //移除下标为 3 这个位置的元素
        numbers . remove ( 3 ); // 这是移除下标为 3 这个位置的元素还是移除 3 这个元素?
        //移除 3 这个元素
        numbers . remove (( Integer ) 3 );
        for ( Integer number : numbers ){
                System . out . println ( number );
        }
        numbers . add ( 2 );
        numbers . add ( 2 );
        int index1 = numbers . indexOf ( 2 );
        int index2 = numbers . lastIndexOf ( 2 );
        System . out . println ( index1 );
        System . out . println ( index2 );
        }
}
  • ArrayList 继承于 AbstractList AbstractList 继承于 AbstractColletion
  • ensureCapacityInternal(int minCapacity) 确保数组有足够的容量来存储新添加的数据
  • void grow(int minCapacity) 实现数组扩容,扩容至原来的1.5
  • ListItr 可以从前到后对集合进行遍历,也可以从后往前对集合进行遍历,还可以向集合中添加元素,修改元素。而 Itr 只能从前到后对集合进行遍历。
        ArrayList底层采用的是数组来存储元素,根据数组的特性, ArrayList 在随机访问时效率极高,在增加 和删除元素时效率偏低,因为在增加和删除元素时会涉及到数组中元素位置的移动。 ArrayList 在扩容 时每次扩容到原来的 1.5

3. LinkedList

示例及源码解读

单向链表
package com . wq . list ;
/**
* 自定义单向链表
* @param <T> 泛型变量
*/
public class MyNode < T > {
        private T data ; // 链中存储的数据
        private MyNode < T > next ; // 下一个链
        public MyNode ( T data , MyNode < T > next ) {
                this . data = data ;
                this . next = next ;
        }
        public T getData () {
                return data ;
        }
        public void setData ( T data ) {
                this . data = data ;
        }
        public MyNode < T > getNext () {
                return next ;
        }
        public void setNext ( MyNode < T > next ) {
                this . next = next ;
        }
}
package com . wq . list ;
public class MyNodeTest {
        public static void main ( String [] args ) {
                MyNode < String > first = new MyNode <> ( " 第一个链 " , null );
                MyNode < String > second = new MyNode <> ( " 第二个链 " , null );
                first . setNext ( second );
                MyNode < String > third = new MyNode <> ( " 第三个链 " , null );
                second . setNext ( third );
                MyNode < String > fourth = new MyNode <> ( " 第四个链 " , null );
                third . setNext ( fourth );
                MyNode < String > nextNode = first ;
                while ( nextNode != null ){
                        System . out . println ( nextNode . getData ());
                        nextNode = nextNode . getNext ();
                }
                System . out . println ( "===================" );
                MyNode < Integer > number4 = new MyNode <> ( 4 , null );
                MyNode < Integer > number3 = new MyNode <> ( 3 , number4 );
                MyNode < Integer > number2 = new MyNode <> ( 2 , number3 );
                MyNode < Integer > number1 = new MyNode <> ( 1 , number2 );
                MyNode < Integer > next = number1 ;
                while ( next != null ){
                        System . out . println ( next . getData ());
                        next = next . getNext ();
                }
        }
}
双向链表
package com . wq . list ;
/**
* 自定义双向链表
* @param <T>
*/
public class DeNode < T > {
        private T data ; // 链中存储的数据
        private DeNode < T > prev ; // 前一个链
        private DeNode < T > next ; // 后一个链
        public DeNode ( T data , DeNode < T > prev , DeNode < T > next ) {
                this . data = data ;
                this . prev = prev ;
                this . next = next ;
        }
        public T getData () {
                return data ;
        }
        public void setData ( T data ) {
                this . data = data ;
        }
        public DeNode < T > getPrev () {
                return prev ;
        }
        public void setPrev ( DeNode < T > prev ) {
                this . prev = prev ;
        }
        public DeNode < T > getNext () {
                return next ;
        }
        public void setNext ( DeNode < T > next ) {
                this . next = next ;
        }
}
package com . wq . list ;
public class DeNodeTest {
        public static void main ( String [] args ) {
                DeNode < Integer > number1 = new DeNode <> ( 1 , null , null );
                DeNode < Integer > number2 = new DeNode <> ( 2 , number1 , null );
                number1 . setNext ( number2 );
                DeNode < Integer > number3 = new DeNode <> ( 3 , number2 , null );
                number2 . setNext ( number3 );
                DeNode < Integer > number4 = new DeNode <> ( 4 , number3 , null );
                number3 . setNext ( number4 );
                DeNode < Integer > nextNode = number1 ;
                while ( nextNode != null ){
                        System . out . println ( nextNode . getData ());
                        nextNode = nextNode . getNext ();
                }
                System . out . println ( "==================" );
                DeNode < Integer > prevNode = number4 ;
                while ( prevNode != null ){
                        System . out . println ( prevNode . getData ());
                        prevNode = prevNode . getPrev ();
                }
        }
}
  • LinkedList 继承于 AbstractSequentialList AbstractSequentialList 继承于 AbstractList , AbstractList 继承于 AbstractColletion
  • void addFirst(E e) 将数据存储在链表的头部
  • void addLast(E e) 将数据存储在链表的尾部
  • E removeFirst() 移除链表头部数据
  • E removeLast() 移除链表尾部数据
package com . wq . list ;
import java . util . LinkedList ;
public class LinkedListTest {
        public static void main ( String [] args ) {
                LinkedList < String > list = new LinkedList <> ();
                list . add ( " 第一个字符串 " );
                list . add ( " 第二个字符串 " );
                list . addLast ( " 第三个字符串 " );
                list . addFirst ( " 第四个字符串 " );
                String first = list . removeFirst (); // 将第一个链移除
                String last = list . removeLast (); // 将最后一个链移除
                System . out . println ( first );
                System . out . println ( last );
                first = list . getFirst ();
                last = list . getLast ();
                System . out . println ( first );
                System . out . println ( last );
        }
}
        LinkedList底层采用的是双向链表来存储数据,根据链表的特性可知, LinkedList 在增加和删除元素时 效率极高,只需要链之间进行衔接即可。在随机访问时效率较低,因为需要从链的一端遍历至链的另一 端。

4.

package com . wq . list ;
import java . util . ArrayList ;
/**
* 自定义栈:后进先出
*/
public class MyStack < T > extends ArrayList < T > {
        public void push ( T t ){
                add ( t );
        }
        public T pop (){
                if ( size () == 0 ) throw new IllegalArgumentException ( " 栈里没有数据啦 " );
                        T t = get ( size () - 1 );
                        remove ( t );
                        return t ;
        }
}
package com .wq . list ;
public class MyStackTest {
        public static void main ( String [] args ) {
                MyStack < Integer > stack = new MyStack <> ();
                stack . push ( 1 );
                stack . push ( 2 );
                stack . push ( 3 );
                stack . push ( 4 );
                stack . push ( 5 );
                while ( ! stack . isEmpty ()){
                        System . out . println ( stack . pop ());
                }
        }
}

练习

        从控制台录入5 位学生信息:姓名,性别,年龄,成绩,并将这些学生信息以 "," 衔接起来,然后存储至文本中。然后再从文本中将这些信息读取至集合中。
package com . wq . list ;
import java . io . * ;
import java . util . ArrayList ;
import java . util . List ;
import java . util . Scanner ;
/**
* 从控制台录入 5 位学生信息:姓名,性别,年龄,成绩,并将这些学生信息以 "," 衔接起来,
* 然后存储至文本中。然后再从文本中将这些信息读取至集合中。
*/
public class Exercise {
        public static void main ( String [] args ) {
                List < Student > students = new ArrayList <> ();
                Scanner sc = new Scanner ( System . in );
                for ( int i = 0 ; i < 5 ; i ++ ){
                        System . out . println ( " 请输入姓名: " );
                        String name = sc . next ();
                        System . out . println ( " 请输入性别: " );
                        String sex = sc . next ();
                        System . out . println ( " 请输入年龄: " );
                        int age = sc . nextInt ();
                        System . out . println ( " 请输入成绩: " );
                        double score = sc . nextDouble ();
                        students . add ( new Student ( name , sex , age , score ));
                }
                saveStudents ( students , "F:\\stu\\stu.txt" );
                List < Student > read = readStudents ( "F:\\stu\\stu.txt" );
                for ( Student stu : read ){
                        System . out . println ( stu );
                }
        }
        public static List < Student > readStudents ( String path ){
                List < Student > students = new ArrayList <> ();
                try ( FileReader reader = new FileReader ( path );
                        BufferedReader br = new BufferedReader ( reader );){
                        String line ;
                        while (( line = br . readLine ()) != null ){
                                String [] arr = line . split ( "," );
                                //name + "," + sex +"," + age + "," + score;
                                String name = arr [ 0 ];
                                String sex = arr [ 1 ];
                                int age = Integer . parseInt ( arr [ 2 ]); // Float.parseFloat()
                                double score = Double . parseDouble ( arr [ 3 ]);
                                students . add ( new Student ( name , sex , age , score ));
                        }
                } catch ( FileNotFoundException e ) {
                        e . printStackTrace ();
                } catch ( IOException e ) {
                        e . printStackTrace ();
                }
                return students ;
        }
        public static void saveStudents ( List < Student > students , String path ){
                File file = new File ( path );
                File parent = file . getParentFile ();
                if ( ! parent . exists ()) parent . mkdirs ();
                        try ( FileWriter writer = new FileWriter ( file );
                                BufferedWriter bw = new BufferedWriter ( writer );){
                                for ( Student stu : students ){
                                        bw . write ( stu . toString ());
                                        bw . newLine ();
                                }
                                bw . flush ();
                        } catch ( IOException e ) {
                                e . printStackTrace ();
                        }
                }
}

Java SE文章参考:Java SE入门及基础知识合集-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/4775.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何实现瀑布流排列方式

瀑布流布局是一种流行的网页布局方式&#xff0c;它允许列的高度不一致&#xff0c;但宽度一致&#xff0c;从而给人一种流动的视觉效果。然而&#xff0c;使用纯CSS实现瀑布流布局并不简单&#xff0c;因为CSS本身并不支持动态计算元素的高度和位置。尽管如此&#xff0c;我们…

python--列表

列表的定义&#xff1a; 能装东西的东西&#xff08;包括字符串、数字、类型、以及列表本身等等&#xff09;。 #在python中用[ ]来表示一个列表&#xff0c;列表中的元素通过逗号&#xff08;,&#xff09;隔开。 例如&#xff1a; a ["陈冠希"&#xff0c;&qu…

OceanBase开发者大会实录-杨传辉:携手开发者打造一体化数据库

本文来自2024 OceanBase开发者大会&#xff0c;OceanBase CTO 杨传辉的演讲实录—《携手开发者打造一体化数据库》。完整视频回看&#xff0c;请点击这里&#xff1e;> 各位 OceanBase 的开发者&#xff0c;大家上午好&#xff01;今天非常高兴能够在上海与大家再次相聚&…

使用这 7 个绩效评估模板简化您的员工评估

绩效评估受到了不好的评价&#xff1b;员工发现它们压力很大&#xff0c;而管理者则发现它们很耗时。 但随着绩效管理成为 2024 年人力资源的首要任务&#xff0c;也许是时候重新思考了。绩效评估模板可以帮助减轻评估过程的麻烦。通过为管理者提供一种简单、标准化的方法来评…

学习记录695@EasyExcel 读取数据每一行都为null

原代码 import lombok.Data; import lombok.experimental.Accessors;Data public class ExcelData{/*** createtime*/ExcelProperty(value "姓名")private String name;/*** updatetime*/ExcelProperty(value "班级")private String class; }String fil…

Python中使用Gradient Boosting Decision Trees (GBDT)进行特征重要性分析

在机器学习中&#xff0c;了解哪些特征对模型的预测有重要影响是至关重要的。这不仅帮助我们理解模型的决策过程&#xff0c;还可以指导我们进行特征选择&#xff0c;从而提高模型的效率和准确性。Gradient Boosting Decision Trees&#xff08;GBDT&#xff09;是一种强大的集…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 4月29日,星期一

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年4月29日 星期一 农历三月廿一 1、 移民管理局&#xff1a;5月6日起换发补发出入境证件可“全程网办”。 2、 文旅部宣布恢复两岸旅游新措施&#xff1a;将率先恢复福建居民到马祖旅游。 3、 网信办&#xff1a;整治用夸…

微软最新季度业绩结果充分说明了云和AI的增长、谷歌和AWS的竞争

微软最新的季度业绩超出了华尔街的各种预期&#xff0c;但对其服务合作伙伴来说&#xff0c;最重要的是这家科技巨头的预期&#xff1a;人工智能不仅能够增长&#xff0c;而且其云产品尚未达到稳定状态——人工智能是云的潜在增长加速器。 周五的一份分析师报告称&#xff0c;…

scipy 笔记:spatial.KDTree

1 方法介绍 scipy.spatial.KDTree(data, leafsize10, compact_nodesTrue, copy_dataFalse, balanced_treeTrue, boxsizeNone) 用于快速最近邻查找的kd树 对于大维数&#xff08;20已经很大&#xff09;&#xff0c;不要期望这比暴力搜索快很多。高维最近邻查询是计算机科学中…

yo!这里是网络入门初识

目录 前言 基本概念 网络 协议 地址 网络传输流程 OSI七层模型 TCP/IP四层&#xff08;五层&#xff09;模型 流程图 数据封装&&分用 后记 前言 对于上一个专栏——Linux操作系统&#xff0c;我们学习了操作系统的基础知识以及基本的系统编程&#xff0c;其…

前端面试题大合集2----基础篇

目录 1、事件模型 2、什么是事件委托/事件代理 3、说一下Commonjs、AMD和CMD 4、Ajax原理 5、说一下XHR和Fetch的区别 6、实现一个once函数&#xff0c;传入函数只执行一次 7、js监听对象属性的改变 8、如何解决跨域问题 9、介绍js有哪些内置对象 10、介绍js有哪些方法…

setTimeout回调函数 this指向问题

本文主要介绍setTimeout的回调函数的this指向问题 例子1&#xff1a;回调函数是一个普通函数 setTimeout 的回调函数是一个普通函数&#xff0c;而不是箭头函数&#xff0c;因此它有自己的上下文&#xff0c;this 指向全局对象&#xff08;在浏览器中是 window 对象&#xff…

十大排序算法之——冒泡排序算法(Java实现)及思路讲解

冒泡排序是一种简单的排序算法&#xff0c;通过重复地遍历待排序的数列&#xff0c;一次比较两个元素&#xff0c;如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换&#xff0c;也就是说该数列已经排序完成。这个算法的名字由来是因为越小的…

挤压激励注意力 SE | Squeeze-and-Excitation Networks

论文名称&#xff1a;《Squeeze-and-Excitation Networks》 论文地址&#xff1a;https://arxiv.org/pdf/1709.01507.pdf 代码地址&#xff1a; https://github.com/hujie-frank/SENet 卷积神经网络 (CNN) 的核心构建块是卷积运算符&#xff0c;它使网络能够通过在每一层的局…

Linux进程基础概念子进程的创建

有着上一节我们对操作系统和冯诺依曼体系结构的理解&#xff0c;本篇我们便可以开始对 Linux 中的进程开始讲解。在本篇中对进程的基本概念进行了简单的介绍&#xff0c;然后通过对描述进程的 PCB&#xff0c;与 Linux 中的 task_struct 的详细讲解&#xff0c;使得对进程的概念…

Android Widget开发代码示例详细说明

因为AppWidgetProvider扩展自BroadcastReceiver, 所以你不能保证回调函数完成调用后&#xff0c;AppWidgetProvider还在继续运行。 a. AppWidgetProvider 的实现 /*** Copyright(C):教育电子有限公司 * Project Name: NineSync* Filename: SynWidgetProvider.java * Author(S…

界面组件DevExpress Blazor UI v23.2 - 网格、工具栏功能全新升级

DevExpress Blazor UI组件使用了C#为Blazor Server和Blazor WebAssembly创建高影响力的用户体验&#xff0c;这个UI自建库提供了一套全面的原生Blazor UI组件&#xff08;包括Pivot Grid、调度程序、图表、数据编辑器和报表等&#xff09;。 DevExpress Blazor控件目前已经升级…

数字文旅重塑旅游发展新生态:以数字化转型为契机,推动旅游产业的创新发展,提升旅游服务的智能化、网络化和个性化水平

目录 一、引言 二、数字化转型推动旅游产业创新发展 1、数字化转型提升旅游产业效率 2、数字化转型拓展旅游产业边界 3、数字化转型促进旅游产业可持续发展 三、提升旅游服务智能化、网络化和个性化水平 1、智能化提升旅游服务体验 2、网络化拓宽旅游服务渠道 3、个性…

爬虫的实战应用之短信炸弹playwright现代网页测试工具

不讲废话&#xff0c;先上原理&#xff1a; 短信炸弹&#xff0c;也就是说持续对一个手机进行发送短信&#xff0c;实现的方式就是&#xff0c;利用某些网站的登录 &#xff0c;注册的时候&#xff0c;发送短信验证码来实现。 如下图&#xff0c;其中有一个id为phone的输入框&a…

亲子公园实景剧本杀小程序系统开发

亲子公园实景剧本杀小程序系统开发涉及到多个方面的内容&#xff0c;具体步骤如下&#xff1a; 1. 系统需求分析&#xff1a;了解客户的需求和期望&#xff0c;明确开发目标和功能需求。 2. 系统架构设计&#xff1a;根据需求分析结果&#xff0c;设计系统的整体架构&#xf…