Java小白翻身-手写LinkedList1

简介: Java小白翻身-手写LinkedList

我们的第一个小目标,是做一个链表结构。其实就是之前写的TuziLinkedList,只不过我们不仅仅要存储Customer,还要存储任意的其他对象。

首先,我们复习一下之前写的链表结构:

52.png


源代码如下:

package tool;
import entity.Customer;
import tool.CustNode;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class TuziLinkedList implements Iterator{
  public CustNode firstNode; //第一个节点 
  public CustNode currentNode;//当前的节点
        public CustNode nodeForEach; //用于遍历的节点,默认等于第一个节点
  //新增的方法
  public void add(Customer cst){
    //将数据用节点类包装好,这样才能实现下一个数据的指向
    CustNode data = new CustNode(cst);
    //先判断是否是第一个节点
    if(this.firstNode == null){
      this.firstNode = data;
      this.currentNode = data;
    }else{
      //不是第一个节点,就指向当前节点的下一个节点,即currentNode.next
      this.currentNode.next = data;
      //因为已经指向下一个了,所以当前节点也要移动过来
      this.currentNode = data;
    }
  }
  //展示所有节点
  public void display(){
    //第一步,肯定是展示第一个节点(this其实可以省略的)
    if(firstNode != null){
      System.out.println(firstNode.data.getName());
      //然后循环,一直寻找next是否为空
      CustNode node = firstNode.next;
      while(node != null ){
        String name = node.data.getName();
        System.out.println(name);
        //循环的最后,再指向下一个节点,继续下一轮
        node = node.next;
      }
    }
  }
  @Override
  public boolean hasNext() {
    if(nodeForEach == null && firstNode != null) return true;
    if(nodeForEach == null) return false;
    return nodeForEach.next != null;
  }
  @Override
  public Object next() {
    if(nodeForEach == null && firstNode != null){
      nodeForEach = firstNode;
      return nodeForEach.data;
    }
    nodeForEach = nodeForEach.next;
    return nodeForEach.data;
  }
}


TuziLinkedList类的核心就是一个单链表,里面维护了CustNode节点,代码如下:

package tool;
import entity.Customer;
public class CustNode{
  public Customer data; 
  public CustNode next;
  public CustNode(Customer data){
    this.data = data;
  }
}


我们的TuziLinkedList还实现了Iterator接口,这个接口可以帮助我们遍历TuziLinkedList中的内容。


53.png


以上是单链表的一般结构,我们会发现,链表中的每一个元素是一个Object,什么是Object呢?Object是Java里面的一个类,它是所有类的父类。在Java中,所有的类都默认继承自Object。


继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。


这些都是概念上的解释,最多也就面试的时候问问。不过随着现在Java的行情越来越**“卷”**,面试也很少问这么基础的东西了。


随着我们代码的深入,相信你会对继承非常熟练的。


因此,与其我现在一股脑儿给你背书,读概念,还不如在之后的章节中,你自己看看继承都用在了哪些地方,是怎么用的?


回到正题,为什么链表的元素要放Object呢?那是因为,所有的类都会直接,或间接继承自Object。Java里面有一个叫做多态的特性,就是父类引用可以指向子类对象。


比如,我有一个人类,和教师类。


class Person{
}
class Teacher extends  Person {
}


Teacher类用extends关键字,继承了Person类,那么说明Teacher类是Person类的子类对吧?

那么,你可以直接new一个Teacher类的对象:

Teacher t = new Teacher();

还可以这样:

Person p = new Teacher();


这也是允许的,但是需要注意的是,父类引用(p)指向了子类对象new Teacher(),那么p就只能调用Person类中的属性和方法,不能调用子类的。除非你用强制转换,像这样:

Person p = new Teacher();
Teacher t = (Teacher) p;


因为p本来就是Teacher的实例,所以你强制转换是允许的,只要你觉得有必要,就强转吧。


说了这么多,现在相信你明白为什么要用Object了吧,因为Object是所有类的父类,所以你用Object可以接收任意类型的对象啊,就这么简单!


方法重写,重载

刚开始,我们不要考虑太多,就做单链表即可。这一节,我们会遇到方法重写和重载的问题。


1、数据模型改为Object

2、AbstractSequentialList

3、add方法报错了

4、什么是方法重写?

5、重写add方法

6、欣赏原生的add方法

为了让我们的链表可以海纳百川,就把Node换成Object型的。


创建一个新的工具包:

54.png

CustNode改为Node,就是通用节点的意思。

package com.tuzi.util;
public class Node{
  public Object data;
  public Node next;
  public Node(Object data){
    this.data = data;
  }
}


然后是TuziLinkedList,改为LinkedList

55.png


JDK中的LinkedList继承了AbstractSequentialList类,这是一个抽象类。


啥叫抽象类,就是有abstract关键字的类,这种类有点像接口,就是里面会有一些方法只有声明而没有实现。我们看下AbstractSequentialList,里面就有一些这样的方法,比如:


public abstract ListIterator<E> listIterator(int index);


这种方法就是抽象方法,在之前接口的章节中,我们已经见过它了。


为了学习的深度,我们虽然不需要做到跟Java中的LinkedList一模一样,但是从表面上,也可以去和它一个标准。就是说,Java中的LinkedList继承了AbstractSequentialList,我们的LinkedList也要去继承AbstractSequentialList。

public class LinkedList extends AbstractSequentialList implements Iterator{
}

因为继承了AbstractSequentialList,我们就不得不去实现它里面所有的抽象方法(和接口真的有点像)

所以,我们不得不实现listIterator方法(就是上面介绍的那个)

@Override
public ListIterator listIterator(int index) {
  return null;
}

虽然这是标准,但是我们现在,甚至连这个玩意到底干啥的都不知道,那就先放着。

继承了AbstractSequentialList之后,add方法就报错了。这是怎么回事呢?

56.png



从提示来看,是void用错了。

原来,AbstractSequentialList还继承了AbstractList。

public abstract class AbstractSequentialList<E> extends AbstractList<E> {
}

AbstractList里面有一个方法也叫做add。

public boolean add(E e) {
   add(size(), e);
   return true;
}


参数是E,是泛型,目测编译器是把这种的也看成方法重写了。我们看下报错:

57.png

意思就是冲突啦,这个被认为是方法重写。

继续之前的例子,我们快速学习一下这个知识点。

class Person{
    public void eat(){
        System.out.println("人在吃饭。。。");
    }
}
class Teacher extends  Person {
    public void eat(){
        System.out.println("老师在吃饭。。。");
    }
}


父类和子类都有一个eat方法,且都没有参数(即参数列表相同),返回值也相同,这就叫做参数重写。

测试代码:

Person p = new Teacher();
Teacher t = (Teacher) p;
t.eat();


运行结果:

老师在吃饭。。。

注意,方法重写的前提是:

1.方法名

2.参数列表

3.返回值

以上三者全部相同,唯有方法体不一样。这种的才叫方法重写。

除了方法重写,还有一种叫做方法重载,就是同一个方法名,参数列表不同的情况,比如:


class Teacher extends  Person {
    public void eat(){
        System.out.println("老师在吃饭。。。");
    }
    public void eat(String food){
        System.out.println("老师在吃" + food );
    }
}


两个方法都叫做eat,但是第二个eat方法多了一个参数,就是方法重载。注意,方法重载和返回值没有半毛钱关系,这个概念经常会在笔试题里面考。比如,下面这样的写法就是错误的:

58.png



相关文章
|
8月前
|
Java 程序员 Windows
【Java知识点详解 10】为何要配置环境变量,35岁老年程序员的绝地翻身之路
【Java知识点详解 10】为何要配置环境变量,35岁老年程序员的绝地翻身之路
|
Java API
Java小白翻身 - webservice教程2
来一个HelloWorld,SpringBoot发布WebService可简单啦。
187 0
|
Java 数据安全/隐私保护
java小白翻身-异常处理03: 自定义异常
java小白翻身-异常处理03: 自定义异常
|
存储 Java
java小白翻身-异常处理02: 常见异常
归纳一些Java开发中常见的一些异常。
100 0
|
算法 Java 测试技术
java小白翻身-手写HashMap
这一节课,我们来手写一个简单的HashMap,所谓HashMap,就是一个映射表。
|
XML JSON Java
Java小白翻身-手写LinkedList2
Java小白翻身-手写LinkedList
|
安全 Java BI
Java小白翻身-Excel教程
Java小白翻身-Excel教程
113 0
|
IDE Java 开发工具
Java小白翻身教程-链表结构与编译大法(4)
tools.jar是刚打出来的工具包,现在把它导入项目。
Java小白翻身教程-链表结构与编译大法(3)
D盘下面的tool文件夹已经有三个工具类了(其实是两个,CustNode是为了TuziLinkedList服务的),我们这一节来进行打包,这样的好处就是不用每次编译都把tool里面的类也带上了。