@Java300 学习总结

一、自定义节点

LinkList底层为双向链表。特点为查询效率低,但增删效率高,线程不安全。

链表数据储存在节点,且每个节点有指向上个和下个节点的指针。

创建ggLinkedList类,可以先创建一个节点对象Entry。

public class Entry {
Entry previous;
Entry next;
Object element; public Entry(Entry previous, Entry next, Object element) {
super();
this.previous = previous;
this.next = next;
this.element = element;
} public Entry(Object element) {
super();
this.element = element;
}
}

二、增加add方法

LinkedList通过add方法往里面增加元素。

先建一个类。

public class ggLinkedList {
private Entry first; //链表头指针,指向第一个节点
private Entry last; //链表尾指针,指向最后一个节点
private int size; //长度,增加节点和删除节点时++或-- //往链表尾处添加元素
public void add(Object obj) {
Entry entry = new Entry(obj); if(first == null) {
first = entry;
last = entry;
}else { entry.previous = last; //新节点头指针指向上一个节点
entry.next = null; //新节点尾指针指向空 last.next = entry; //上一个节点的尾指针指向新添加节点
last = entry;//尾指针指向新节点
}
size++;//链表长度增加一
}
public static void main(String[] args) {
ggLinkedList list = new ggLinkedList();
list.add('a');
}
}

三、增加toString方法

在ggLinkedList类中,添加toString方法,以数组的形式输出链表每个节点的数据。

在main函数调用System.out.println(list),会默认调用toString方法。

public String toString() {
StringBuilder sb = new StringBuilder("[");
Entry temp = first;
while(temp!=null) {
sb.append(temp.element+",");
temp = temp.next;
}
sb.setCharAt(sb.length()-1,']');
return sb.toString();
}

四、增加get查找方法

get()方法,可以通过传递数字,查找LinkedList对应索引节点上的数据。

public Object get(int index) {
if(index< 0||index > size -1) {
throw new RuntimeException("索引数字不合法" + index);
}
if(index <= (size>>1)) { //索引index小于链表长度的一半,从链表头部开始查找
Entry temp = first;
for(int i = 0;i<index;i++) {
temp = temp.next;
}
return temp.element;
}else
{
Entry temp = last; //索引index大于链表长度的一半,从链表尾部开始查找
for(int i = size-1;i > index;i--) {
temp = temp.previous;
}
return temp.element;
}
}

五、增加remove()删除功能

remove()删除节点,需先定位到目标节点,与get()方法一致,所以可构造getEntry()方法,以简化代码。

public Entry getEntry(int index) {
Entry temp = null;
if(index <= (size>>1)) {
temp = first;
for(int i = 0;i<index;i++) {
temp = temp.next;
}
return temp;
}else
{
temp = last;
for(int i = size-1;i > index;i--) {
temp = temp.previous;
}
return temp;
}
}

重构get()方法

public Object get(int index) {
if(index< 0||index > size -1) {
throw new RuntimeException("索引数字不合法" + index);
}
Entry temp = getEntry(index);
return temp!= null?temp.element:null;
}

remove()方法

public void remove(int index) {
Entry temp = getEntry(index); //索引到指定的节点
Entry up = temp.previous; //上一个节点为up
Entry down = temp.next; // 下一个节点为down
if(temp!= null) {
if(down!= null) { //下一个节点不为空,down的头指针指向上一个节点
down.previous = up;
}
if(up!= null) { //上一个节点不为空,up的的尾指针为下一个节点
up.next = down;
}
if(index == 0) { //移除节点为头节点,链表头指针指向第二个
first = down;
}
if(index == (size-1)) { //移除节点为最后一个,链表尾指针指向倒数第二个
last = up;
}
}
size--;
}

六、增加插入方法

重载add()方法,实现在指定索引位置插入元素。

public void add(int index,Object obj) {
Entry newEntry = new Entry(obj); //新建节点,将它插入在索引节点的前面
Entry down = getEntry(index); //原节点为新插入节点的下一个节点,变量名为down if(down!=null) { //原节点不为空
Entry up = down.previous; //原节点的上一个节点为上一个节点,变量名为up if(index == 0) {
down.previous = newEntry; //原节点的前一个为新节点
newEntry.next = down;//新节点的下一个为原节点
first = newEntry;//链表头指针指向新节点
}
else if(index == (size-1)) {
down.next = newEntry; //原节点的下一个为新节点
newEntry.previous = up;//新节点的上一个为up
last = newEntry;//尾指针指向新节点 }else {
down.previous = newEntry;
up.next = newEntry;
newEntry.next = down;
newEntry.previous = up;
}
}
size++;

至此,LinkedList部分方法已实现,后续也可增加其他方法,或泛型。旨在理解底层原理,提升代码能力

Java手写简单Linkedlist一(包括增加,插入,查找,toString,remove功能)的更多相关文章

  1. Java手写简单HashMap一(包括增加,查找,toString,泛型)

    @Java 300 学习总结 HashMap底层采用实现采用了哈希表,结合了"数组和链表". 原理如图 一.定义HashMap类. 首先需要定义一个节点来存储数据,构成链表结构. ...

  2. 利用Java手写简单的httpserver

    前言: 在看完尚学堂JAVA300中讲解如何实现一个最简单的httpserver部分的视频之后, 一.前置知识 1.HTTP协议 当前互联网网页访问主要采用了B/S的模式,既一个浏览器,一个服务器,浏 ...

  3. 教你如何使用Java手写一个基于链表的队列

    在上一篇博客[教你如何使用Java手写一个基于数组的队列]中已经介绍了队列,以及Java语言中对队列的实现,对队列不是很了解的可以我上一篇文章.那么,现在就直接进入主题吧. 这篇博客主要讲解的是如何使 ...

  4. java 手写 jvm高性能缓存

    java 手写 jvm高性能缓存,键值对存储,队列存储,存储超时设置 缓存接口 package com.ws.commons.cache; import java.util.function.Func ...

  5. java手写多级缓存

    多级缓存实现类,时间有限,该类未抽取接口,目前只支持两级缓存:JVM缓存(实现 请查看上一篇:java 手写JVM高性能缓存).redis缓存(在spring 的 redisTemplate 基础实现 ...

  6. 不使用Tomcat,手写简单的web服务

    背景: 公司使用的YDB提供了http的查询数据库服务,直接通过url传入sql语句查询数据-_-||.ydb的使用参照:https://www.cnblogs.com/hd-zg/p/7115112 ...

  7. 手写简单call,apply,bind

    分析一下call的使用方法:call是显示绑定this指向,然后第一个参数是你所指向的this对象,后面跟着多个参数,以逗号隔开 function sum(num1,num2){ return num ...

  8. 手写Spring MVC框架(二) 实现访问拦截功能

    前言 在上一篇文章中,我们手写了一个简单的mvc框架,今天我们要实现的功能点是:在Spring MVC框架基础上实现访问拦截功能. 先梳理一下需要实现的功能点: 搭建好Spring MVC基本框架: ...

  9. 手写简单的jq雪花飘落

    闲来无事,准备写个雪花飘落的效果,没有写太牛逼的特效,极大的简化了代码量,这样容易读取代码,用起来也很简单,对于那些小白简直是福利啊,简单易读易学.先直接上代码吧,然后再一一讲解,直接复制粘贴就可以拿 ...

随机推荐

  1. 下载 nasm for win64

    下载nasm https://www.nasm.us/pub/nasm/releasebuilds/?C=M;O=D 以管理员身份运行安装.

  2. RabbitMQ 和 Kafka 的消息可靠性对比

    RabbitMQ和Kafka都提供持久的消息保证.两者都提供至少一次和至多一次的保证,另外,Kafka在某些限定情况下可以提供精确的一次(exactly-once)保证. 让我们首先理解一下上述术语的 ...

  3. Spring Cloud Gateway(二):Spring Cloud Gateway整合Eureka应用

    Spring Cloud Gateway 应用概述 下面的示例启动两个服务:gataway-server 和 user-service 都注册到注册中心 Eureka上,客户端请求后端服务[user- ...

  4. Apache Flink - 配置依赖,连接器,库

    每个Flink程序都依赖于一组Flink库. 1.Flink核心和应用程序依赖项 Flink本身由一组类和运行需要的依赖组成.所有类和依赖的组合形成了Flink运行时的核心,并且当一个Flink程序运 ...

  5. vue 中引入第三方js库

    以 jQuery 为例 一.绝对路径直接引入,全局可用 主入口页面 index.html 中用 script 标签引入: <script src="./static/jquery-1. ...

  6. Vue 目录

    什么是 vue-cli 通过 vue-cli 建立出来的 vue

  7. windows 连接 Linux 云服务器

    1.在我们购买了 阿里云 或者 腾讯云后,如果选择使用的是 Linux 系统,在 windows 上要远程连接,需要用到的是 putty 这一个软件 putty 官网:https://www.putt ...

  8. dubbo 初识(1)

    参考dubbo 中文官方文档:http://dubbo.apache.org/zh-cn/docs/user/preface/architecture.html 分布式架构的发展过程 1.初始小型的项 ...

  9. <JavaScript> 普通函数与构造函数的区别

    JavaScript中存在构造函数与函数两个概念. 这可能会给初学者造成一定的困扰,难不成存在两种函数. 然而事实这两种函数的构成完全一样,无论从长相还是气质都是一模一样的. 区别点在于,所扮演觉得不 ...

  10. ubuntu18 bluebooth

    QDBusPendingReply: type ManagedObjectList is not registered with QtDBus 19:36:14: The program has un ...