2022-7-27 第二组 程梓杭 Java(10)内部类与饿汉式与懒汉式与双链表


今日学习内容:内部类与饿汉式与懒汉式与双链表

一、块

二、static,外部类,内部类,匿名内部类

三、单例设计模式之饿汉式与懒汉式

四、双链表

知识点一:

块:

又称代码块,是直接写在类下的由{}包裹的代码。块适用于static修饰。
当其他类调用该类时,写在该类下的块也会执行,执行顺序:静态最优先,父类次优先,结构体最次优先。

知识点二:

1、static:

static是Java提供的静态修饰词。static可以修饰变量与方法成为类变量和类方法(静态变量和静态方法)。
静态变量有两种引用方式:类名引用和对象名引用。当静态变量发生变化时,该类实例化的所有对象的该静态成员变量也会发生相同的变化。
静态方法可以通过类名引用(在static修饰下变成了属于类而非具体对象的方法)(非静态方法需要通过对象引用)

2、外部类:

一般来说,外部类是定义在已设置主类的.java文件下的类。当在主类内部定义了一个内部类,主类成为了相对意义上的外部类。

3、内部类:

内部类是定义在.java文件主类内部的类,分为静态内部类和非静态内部类。
静态内部类和非静态内部类之间的区别主要如下:

点击展开
内部原理的区别:
静态内部类是属于外部类的类成员,是一种静态的成员,是属于类的,就有点类似于private static Singleton instance = null;
非静态内部类,是属于外部类的实例对象的一个实例成员,也就是说,每个非静态内部类,不是属于外部类的,是属于外部类的每一个实例的,创建非静态内部类的实例以后,非静态内部类实例,是必须跟一个外部类的实例进行关联和有寄存关系的。
创建方式的区别: 创建静态内部类的实例的时候,只要直接使用“外部类.内部类()”的方式,就可以,比如new School.Teacher();创建非静态内部类的实例的时候,必须要先创建一个外部类的实例,然后通过外部类的实例,再来创建内部类的实例,new School().Teader()
通常来说,我们一般都会为了方便,会选择使用静态内部类

知识点三:

1、设计模式:

所谓设计模式,是程序员们总结的行之有效的设计方式,包含诸多规则,有诸多设计模式。单例设计模式就是其中之一。
单例设计模式要求一个类只能有一个对象,不容许创建新对象。

2、饿汉式:

饿汉式取迫不及待的意思,在类创建之初就创建了一个private权限的对象,并且将构造方法也设置为private避免调用构造方法构造新对象。因为需要在主类中调用本类对象,所以还需要设置一个调用方法。

点击查看
public class Text{
    private static final Text text = new Text();

    private Text(){}

    public static Text getInstance(){
        return text;
    }
}
//定义了一个Text文本类,然后定义了一个私有的text文本对象,私有化了构造方法,公开了text的调用方法。
//于是我们得到了一个只能查看,不能再创建的文本。
3、懒汉式:

懒汉式取懒惰(不着急)的意思,在类创建时并未构造对象而是在主类访问本类时进行构造。关于懒汉式的写法,并不单一,不同写法有不同的优缺点。这里提供了其中两种写法。

点击查看第一种写法
public class Emperor {
    private static Emperor emperor;
    private static String name;

    private Emperor() {
    }

    public static Emperor getInstance(String name) {
        if ( emperor == null ) {
            emperor = new Emperor();
            emperor.name = name;
        }
        id++;
        return Emperor.emperor;
    }
//创建了一个皇帝类,私有化了对象(未创建)和对象名,私有化了构造方法。
//当使用公有化调用方法时,根据传入姓名在无对象时创建对象,否则直接返回对象。
点击查看第二种写法
public class SingletonPatternLazyInnerClass {

    private SingletonPatternLazyInnerClass(){}

    private static class SingletonHolder{
        private static final SingletonPatternLazyInnerClass INSTANCE = new SingletonPatternLazyInnerClass();
    }

    public static SingletonPatternLazyInnerClass getInstance(){
        return SingletonHolder.INSTANCE;
    }
}
//创建了一个“单例模式懒汉内部类”类,私有化了对象构造方法。公开了一个对象调用方法,但是返回了内部类对象。
//创建了内部类,内部类创建了私有化最终对象(不可更改),经由外部内对象调用方法传出。

知识点四:

双链表:

双链表结点模型、链表概念模型(2)如下图:
image
image
image

双链表代码示例:

点击查看
public class DoubleLinkList{
    private Node head;      // 头结点
    private Node tail;      // 尾指针
    private Integer length; // 链表有效长度

    private class Node{
        private Integer data;     // 数据域
        private Node prior; // 指针域 前
        private Node next;  // 指针域 后

        public Node(){}
        public Node(Integer data){
            this.data = data;
        }
    }

    public DoubleLinkList(){
        this.head = new Node();
        this.length = 0;
    }

    public Integer getLength(){
        return this.length;
    }

    public Boolean isEmpty(){
        return this.length == 0;
    }

    /**
     * 尾插
     * @param data 插入的数据
     */
    public void addNode(Integer data){
        Node tmp = this.head;
        while(tmp.next != null)
            tmp = tmp.next;
        Node newNode = new Node(data);
        tmp.next = newNode;
        newNode.prior = tmp;
        this.length++;
    }

    /**
     * 根据下标删除节点
     * @param index
     */
    public void deleteNode(Integer index){
        if(index < 0 || index >= this.length)
            return;
        Node tmp = this.head;
        while(tmp.next != null && index-- != 0)
            tmp = tmp.next;
        Node delNode = tmp.next;
        delNode.next.prior = tmp;
        tmp.next = delNode.next;
        this.length--;
    }

    /**
     * 通过下标查询节点并返回数据
     * @param index
     * @return
     */
    public Integer selectNode(Integer index){
        if(index < 0 || index >= this.length)
            return null;
        Node tmp = this.head;
        while(tmp.next != null && index-- != 0)
            tmp = tmp.next;
        return tmp.next.data;
    }

    /**
     * 通过下标进行修改节点
     * @param index
     * @param newData
     */
    public void updateNode(Integer index, Integer newData){
//        if(index < 0 || index >= this.length)
//            return;
        Node tmp = this.head;
        while (tmp.next != null && index-- != 0)
            tmp = tmp.next;
        if(index == 0) {
            tmp.next.data = newData;
        }
    }

    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        Node tmp = this.head;
        while (tmp.next != null){
            tmp = tmp.next;
            stringBuilder.append(tmp.data).append(" ");
        }
        return stringBuilder.append("/n").toString();
    }

    public static void main(String[] args) {
        DoubleLinkList doubleLinkList = new DoubleLinkList();
        System.out.println(doubleLinkList);
        doubleLinkList.addNode(1);
        doubleLinkList.addNode(2);
        doubleLinkList.addNode(3);
        doubleLinkList.addNode(4);
        System.out.println(doubleLinkList);

        doubleLinkList.deleteNode(4);
        doubleLinkList.deleteNode(0);
        doubleLinkList.deleteNode(4);
        System.out.println(doubleLinkList);

        System.out.println(doubleLinkList.selectNode(3));
        System.out.println(doubleLinkList.selectNode(2));
        System.out.println(doubleLinkList);

        doubleLinkList.updateNode(0, 10);
        doubleLinkList.updateNode(100, 10);
        System.out.println(doubleLinkList);
    }
}

一些思考:

当学习到的知识杂乱时,简单的思维导图或许收益甚小,可以考虑画一颗模糊的知识树,将新学的知识作为树枝找到它应在的位置。例如上述涉及的数据结构和设计模式完全不在同一枝干上,需要在学习前中后对背后相关的概念加以理解。

原创文章,作者:254126420,如若转载,请注明出处:https://blog.ytso.com/277425.html

(0)
上一篇 2022年7月28日
下一篇 2022年7月28日

相关推荐

发表回复

登录后才能评论