Java学习路线-13:链表定义与实现

简介: Java学习路线-13:链表定义与实现

第30 章 : 链表的定义与使用

134 链表实现简介

链表本质是一个动态的对象数组,它可以实现若干个对象的存储


链表利用引用的逻辑关系来实现类似于数组的数据处理操作


实现链表,需要一个公共结构-节点:

1、保存数据

2、连接下一个结构


Node<E>
-E data
-next

还需要一个管理Node节点的类


客户端:数据的增删改查
链表LinkImpl:处理Node细节 -> ILink<T>
Node:存储数据
private class Node<T>{
    private T data;   // 数据
    private Node<T> nextNode; // 下一节点
    public Node(T data){
        this.data = data ;
    }
    public void setNextNode(Node<T> nextNode){
        this.nextNode = nextNode ;
    }
    public Node<T> getNextNode(){
        return this.nextNode ;
    }
    public T getData(){
        return this.data;
    }
}

简单的单向链表实现

135 数据增加


public void add(E e);

136 获取数据集合个数


public int size();

137 空集合判断


public boolean isEmpty();

138 返回集合数据


public Object[] toArray();

139 根据索引取得数据


public E get(int index);

数组获取数据的时间复杂度为1

链表获取数据的时间复杂度为n


140 修改链表指定索引数据


public void set(int index, E data);

141 判断链表数据是否存在


public boolean contains(E data);

142 删除链表数据


public void remove(E data);

两种情况

删除根节点数据

删除非根节点数据


引用修改


143 清空链表


public void clean();

只用设置头节点为空即可


完整代码


// 定义链表的接口
interface ILink<E>{
    public void add(E e);  // 添加元素
    public int size();     // 获取元素个数
    public boolean isEmpty();  // 判断是否为空
    public Object[] toArray();  //转为对象数组
    public E get(int index);  // 根据索引取得数据
    public void set(int index, E data);  //修改数据
    public boolean contains(E data); // 判断数据是否存在
    public boolean remove(E data);  // 链表数据
    public void clean();  // 清空链表
}
// 实现链表
class LinkImpl<T> implements ILink<T>{
    private Node<T> rootNode;  // 记录头指针
    private int count ;    // 计数统计
    private Object[] dataList; // 数据列表
    private int foot; //角标
    // 链表节点,内部类,便于外部类直接访问其私有属性
    private class Node<T>{
        private T data;   // 数据
        private Node<T> nextNode; // 下一节点
        public Node(T data){
            this.data = data ;
        }
        public void addNode(Node<T> node){
            if(!this.hasNextNode()){
                this.nextNode = node;
            } else{
                this.nextNode.addNode(node);
            }
        }
        public boolean hasNextNode(){
            return this.nextNode != null;
        }
        public void toArrayNode(){
            LinkImpl.this.dataList[LinkImpl.this.foot++] = this.data;
            if(this.hasNextNode()){
                this.nextNode.toArrayNode();
            }
        }
        public Node<T> getNode(int index){
            if(LinkImpl.this.foot++ == index){
                return this ;
            }else{
                return this.nextNode.getNode(index);
            }
        }
        public boolean containsNode(T data){
            // 比较对象 不能是null
            if(this.data.equals(data)){
                return true;
            } else {
                // 有后续节点继续
                if(this.hasNextNode()){
                    return this.nextNode.containsNode(data);
                } else {
                    // 没有找到数据
                    return false;
                }
            }
        }
        public boolean removeNode(Node<T> preNode, T data){
            if(this.data.equals(data)){
                preNode.nextNode = this.nextNode;
                return true;
            } else {
                // 有后续节点,继续移除操作
                if(this.hasNextNode()){
                    return this.nextNode.removeNode(this, data);    
                } else{
                    return false;
                }
            }
        }
    }
    public void add(T data){
        // 不接受null 类型的值
        if(!isValidData(data)){
            return;
        }
        Node<T> newNode = new Node<T>(data);
        // 添加第一个元素的时候,头节点为null
        if (this.count == 0){
            this.rootNode = newNode;
        } else {
            this.rootNode.addNode(newNode);
        }
        this.count++;
    }
    public int size(){
        return this.count;
    }
    public boolean isEmpty(){
        return this.count == 0;
    }
    public Object[] toArray(){
        if(this.isEmpty()){
            return null;
        }
        // 角标清零,创建空数组
        this.foot = 0;
        this.dataList = new Object[this.count];
        // 递归获取节点数据
        this.rootNode.toArrayNode();
        return this.dataList;
    }
    // 检查索引是否在有效范围内
    private boolean isValidIndex(int index){
        if(index < 0 || index >= count){
            return false;
        } else{
            return true;
        }
    }
    // 检查是否为有效数据
    private boolean isValidData(T data){
        if(data == null){
            return false;
        } else{
            return true;
        }
    }
    public T get(int index){
        if(!this.isValidIndex(index) || this.isEmpty()){
            return null ;
        }
        // 重置下标
        this.foot = 0;
        return this.rootNode.getNode(index).data;
    }
    public void set(int index, T data){
        if(!this.isValidIndex(index) || this.isEmpty() ){
            return ;
        }
        // 重置下标
        this.foot = 0;
        this.rootNode.getNode(index).data = data;
    }
    public boolean contains(T data){
        if(!isValidData(data) || this.isEmpty()){
            return false;
        }
        return this.rootNode.containsNode(data);
    }
    public boolean remove(T data){
        if(!isValidData(data) || this.isEmpty()){
            return false;
        }
        boolean removeResult = false;
        // 移除头节点
        if(this.rootNode.data.equals(data)){
            this.rootNode = this.rootNode.nextNode; 
            removeResult = true;
        } else{
            removeResult = this.rootNode.nextNode.removeNode(this.rootNode, data);
        }
        if(removeResult == true){
            this.count --;
        }
        return removeResult;
    }
    public void clean(){
        this.rootNode = null;
        this.count = 0;
    }
    public void printLink(){
        Object[] list = this.toArray();
        if (list == null){
            System.out.println("null");
            return;
        }
        for(int i=0; i < this.count; i++){
            if(i == 0){
                System.out.print("[ ");
            } else {
                System.out.print("-> ");
            }
            System.out.print(list[i]); 
            if (i == count - 1){
                System.out.print(" ]");
            }           
        }
        System.out.println();
    }
}
class Demo{
    public static void main(String[] args) {
        LinkImpl<Integer> link = new LinkImpl<Integer>();
        System.out.println("添加前:" + link.size() + " " + link.isEmpty());
        // 添加前:0 true
        link.add(2);
        link.add(3);
        link.add(4);
        link.add(5);
        System.out.println("添加后:" + link.size() + " " + link.isEmpty());
        // 添加后:4 false
        link.printLink();
        // [ 2-> 3-> 4-> 5 ]
        System.out.println(link.get(2));
        // 4
        link.set(2, 6);
        System.out.println(link.get(2));
        // 6
        System.out.println(link.contains(10)); // false
        System.out.println(link.contains(5)); // true
        link.printLink();
        // [ 2-> 3-> 6-> 5 ]
        link.remove(2);
        System.out.println(link.contains(2));
        link.printLink();
        // [ 3-> 6-> 5 ]
        link.clean();
        link.printLink();
        // null
    }
}

144 综合实战:宠物商店

要求

宠物上架,下架,查询宠物信息


设计

宠物接口

-猫

-狗


宠物链表接口

-宠物链表


宠物商店

-宠物列表


根据接口标准定义信息


145 综合实战:超市购物车

类与标准有关,降低类与类之间耦合


146 Eclipse简介

Eclipse 中文意思:日蚀


开发工具 + 操作系统 + 中间件 + 数据库

Eclipse EE + Linux + Tomcat + MySQL


https://www.eclipse.org/downloads/


147 使用JDT开发Java程序

项目目录


src *.java 
bin *.class

UTF-8编码


快捷方式:

自动导包

代码格式化

代码纠正提示

代码提示

复制当前行

单行注释

代码自动生成


148 代码调试

断点break point


单步跳入 进入代码

单步跳过 直接到结果

单步返回 进入之后直接返回

恢复执行 取消断点,程序正常执行


149 junit测试工具

白盒测试

黑盒测试

用例测试 junit


testCase 一个测试

testSuite 一组测试

相关文章
|
3月前
|
IDE Java 关系型数据库
Java 初学者学习路线(含代码示例)
本教程为Java初学者设计,涵盖基础语法、面向对象、集合、异常处理、文件操作、多线程、JDBC、Servlet及MyBatis等内容,每阶段配核心代码示例,强调动手实践,助你循序渐进掌握Java编程。
481 3
|
3月前
|
SQL Java 数据库
2025 年 Java 从零基础小白到编程高手的详细学习路线攻略
2025年Java学习路线涵盖基础语法、面向对象、数据库、JavaWeb、Spring全家桶、分布式、云原生与高并发技术,结合实战项目与源码分析,助力零基础学员系统掌握Java开发技能,从入门到精通,全面提升竞争力,顺利进阶编程高手。
719 1
|
3月前
|
SQL 算法 Java
零基础到精通的史上最强 Java 学习路线图推荐
史上最全Java学习路线图,涵盖基础语法、面向对象、数据结构与算法、多线程、JVM、Spring框架、数据库及项目实战,助你从零基础到精通Java开发,附完整代码与工具推荐。
276 3
零基础到精通的史上最强 Java 学习路线图推荐
|
3月前
|
SQL 算法 Java
适合自学的史上最强 Java 学习路线图分享
本路线图系统讲解Java从入门到进阶的学习路径,涵盖基础语法、面向对象编程、数据结构与算法、多线程、JVM原理、主流框架如Spring、数据库操作及项目实战,助你全面掌握Java开发技能,适合零基础及进阶学习。
914 0
|
3月前
|
Java API 数据库
2025 年最新 Java 实操学习路线,从入门到高级应用详细指南
2025年Java最新实操学习路线,涵盖从环境搭建到微服务、容器化部署的全流程实战内容,助你掌握Java 21核心特性、Spring Boot 3.2开发、云原生与微服务架构,提升企业级项目开发能力,适合从入门到高级应用的学习需求。
785 0
|
3月前
|
NoSQL Java 关系型数据库
超全 Java 学习路线,帮你系统掌握编程的超详细 Java 学习路线
本文为超全Java学习路线,涵盖基础语法、面向对象编程、数据结构与算法、多线程、JVM原理、主流框架(如Spring Boot)、数据库(MySQL、Redis)及项目实战等内容,助力从零基础到企业级开发高手的进阶之路。
350 1
|
3月前
|
缓存 Java API
2025 年小白也能轻松上手的 Java 最新学习路线与实操指南深度剖析
2025年Java最新学习路线与实操指南,涵盖基础语法、JVM调优、Spring Boot 3.x框架、微服务架构及容器化部署,结合实操案例,助你快速掌握企业级Java开发技能。
442 0
|
3月前
|
前端开发 Java 数据库连接
帮助新手快速上手的 JAVA 学习路线最详细版涵盖从入门到进阶的 JAVA 学习路线
本Java学习路线涵盖从基础语法、面向对象、异常处理到高级框架、微服务、JVM调优等内容,适合新手入门到进阶,助力掌握企业级开发技能,快速成为合格Java开发者。
573 3
|
3月前
|
监控 Java API
2025 年全新出炉的 Java 学习路线:从入门起步到实操精通的详细指南
2025年Java学习路线与实操指南,涵盖Java 21核心特性、虚拟线程、Spring Boot 3、微服务、Spring Security、容器化部署等前沿技术,助你从入门到企业级开发进阶。
843 0
|
4月前
|
NoSQL Java 关系型数据库
Java 从入门到进阶完整学习路线图规划与实战开发最佳实践指南
本文为Java开发者提供从入门到进阶的完整学习路线图,涵盖基础语法、面向对象、数据结构与算法、并发编程、JVM调优、主流框架(如Spring Boot)、数据库操作(MySQL、Redis)、微服务架构及云原生开发等内容,并结合实战案例与最佳实践,助力高效掌握Java核心技术。
446 1