@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. 2015 ACM Arabella Collegiate Programming Contest

    题目链接:https://vjudge.net/contest/154238#overview. ABCDE都是水题. F题,一开始分类讨论,结果似乎写挫了,WA了一发.果断换并查集上,A了. G题, ...

  2. Notepad++编辑.sh文件

    使用记事本创建创建test.txt文件,修改后缀名为sh后,再文件里写以下内容: #!/bin/bash echo "hello world" 这样的文件再linux里是无法执行的 ...

  3. JAVA基础知识|抽象类与接口类

    一.抽象类 抽象类:拥有抽象方法的类就是抽象类,抽象类要使用abstract声明 抽象方法:没有方法体的方法,必须要使用abstract修饰 为什么要使用抽象类,抽象方法? 举例来说,如果你定义了一个 ...

  4. kafka学习汇总系列(一)kafka概述

    一.kafka概述 在流式计算中,kafka是用来缓存数据的,storm通过消费kafka的数据进行计算.kafka的初心是,为处理实时数据提供一个统一.高通量.低等待的平台: 1.kafka是一个分 ...

  5. 重读APUE(4)-fcntl和ioctl的区别

    fcntl(File Control)-文件控制 ioctl(In/Out Control)-I/O控制 1. fcntl作用于文件,提供对文件的基础控制:ioctl作用于文件和设备对象,一般用来向设 ...

  6. [GIT]比较不同分支的差异

        比如我们有 2 个分支:master, dev,现在想查看这两个 branch 的区别,有以下几种方式: undefined 1.查看 dev 有,而 master 中没有的: 1.查看 de ...

  7. kotlin 代码格式

    与java 不同,代码顺序影响编译过程. { var a:Int = 1; init(){ a++; } //var a:Int = 1;  写在 init 之后不可用. }

  8. CDH构建大数据平台-Kerberos高可用部署【完结篇】

    CDH构建大数据平台-Kerberos高可用部署[完结篇] 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.  一.安装Kerberos相关的软件包并同步配置文件 1>.实验环境 ...

  9. JVM的线程

    我们使用java命令来运行一个程序,那么就需要启动JVM , 而jvm的启动就相当于启动了一个进程 , 而这个进程在启动的时候会自动启动一个线程,由这个线程去调用main方法,而这个线程就是主线程 ; ...

  10. js 删除 按钮所在的行

    <body> <table id="delte"> <caption>简易购物车</caption> <tr> < ...