2022-07-25 第二小组 张鑫 学习笔记

实训第十五天 多态与链表

1.学习重点

1.多态

2.匿名对象

3.超级数组完善

4.链表

2.学习心得

今天是新的一周的第一天,紧张的学习又开始了,今天主要学习了面向对象三大特征的最后一项——多态,还有简单单向链表的学习,总体感觉难度还是可以接受的!如果有时间我要主动学习一些知识了,争取早日成为可以给他人讲题的选手!

3.学习内容

多态

多态的形成有3个条件
1、有继承
2、有重写
3、有父类对象指向子类引用


第一种多态形式:(向上转型)
父类 父类对象 = new 子类();

第二种多态形式:(向下转型)
发生向下转型的前提,要先发生向上转型,才能通过强转再转成子类类型。


instanceof关键字:判断某一个对象是否是某一个类的实例,返回值是boolean类型

无敌方法

public Object show(Object ... obj){

        return true;
    }

匿名对象

语法:
new 类名();
功能:和正常的有名字的对象的功能是相同的。
依然具备了调用属性,方法的功能。
使用场景:多数是用在传参,实参,多数情况下配合构造器使用
好处:节约资源。


超级数组完善

public class SuperArray {

    // 维护一个数组,要考虑的是怎么存
    private Object [] array;

    // 超级数组的长度
    private int size;

    // 数组当前的容量
    private int capacity;

    public SuperArray(){
//        array = new Integer[10];
        this(10);
//        capacity = 10;
    }

    public SuperArray(int capacity){
        array = new Object[capacity];
        this.capacity = capacity;
    }

    // 添加数据,默认添加,在数组的尾部添加
    public void add(Object data) {
        // 添加时要确保容量足够,如果不够,就需要扩容
        ensureCapacity(size + 1);
        // 真正的添加数据
        array[size++] = data;

    }
    // 添加数据,传入两个参数
    // 在指定位置添加
    public void add(int index,Object data){
        if(rangeCheck(index)){
            ensureCapacity(size + 1);
            System.arraycopy(array,index,array,index + 1,size - index);
            // 真正的添加数据
            array[index] = data;
            size++;
        }

    }

    // 删除最后一个数据
    public Object remove(){
        if(size > 0){
            return array[--size];
        }
        return null;
    }

    // 删除指定下标位置的元素
    public Object remove(int index){
        if(rangeCheck(index)){
            Object res = array[index];
            System.arraycopy(array,index + 1,array,index,(--size - index));
            return res;
        }
        return null;
    }

    // 修改
    public boolean set(int index,Object data) {
        if(rangeCheck(index)){
            array[index] = data;
            return true;
        }
        return false;
    }

    // 获取超级数组的长度
    public int size(){

        return size;
    }

    // 获取指定下标的元素
    public Object get(int index) {
        // 判断一下index和合法性
        if(rangeCheck(index)){
            return array[index];
        }
        return null;
    }

    private boolean rangeCheck(int index) {
        // index >= 0
        // index <= size - 1
        return (index >=0 && index <= size - 1);
    }

    // 这个方法只在当前类使用,所以声明成private
    private void ensureCapacity(int needCapacity) {
//        System.out.println(needCapacity + "-----" + capacity);
        if(needCapacity > capacity){
            // 1.5倍
            capacity = capacity + (capacity >> 1);
            //  创建一个新的扩容好的数组
            Object [] newArray = new Object[capacity];
            // 把原数组的数据拷贝过来
            /*
                src:原数组
                srcPos:拷贝原始数组的起始位置
                dest:目标数组
                destPos:目标数组的起始位置
                length:拷贝数据的长度
             */
            System.arraycopy(array,0,newArray,0,array.length);
            array = newArray;
        }


    }

}

链表

一个数据结构
在内存中,数组和链表都是最基本的数据结构,表,或者线性表。
线性表,线性的结构,它是一个含有n>=0个结点的有限序列,
有且只有一个上一个结点,有且只有一个下一个结点。

单向链表:在维护一个结点的自身的值得同时,还要维护它的下一个值的指向
双向链表:在维护一个结点的自身的值得同时,还要维护它的上一个和下一个值得指向

public class SuperLinked {

    // 链表的长度
    private int size;
    // 链表的第一个结点
    private Node first;
    // 链表的最后一个结点
    private Node last;

    // 无参构造器
    public SuperLinked() {
    }

    // 把数组添加到链表的尾部
    public boolean add(Integer data){
        // 把传入的数据构建成一个结点
        Node node = new Node(data,null);
        // 如果现在链表是空的,那我就是第一个结点
        if(first == null) {
            first = node;
        }else {
            // 如果链表不是空,那我就是最后一个结点
            // 我应该是在原来的last结点后面
            // 我是原来last结点的下一个结点
            last.setNext(node);
        }
        last = node;
        size++;
        return true;
    }

    // 在指定位置添加元素
    public boolean add(int index,Integer data) {
        Node node = getNode(index);
        Node newNode = new Node(data,null);
        if(node != null){
//            Node next = node.getNext();
//            newNode.setNext(next);
            newNode.setNext(node.getNext());
            node.setNext(newNode);
        } else {
            // 如果要插入的位置是null,只有一种情况,就是整个链表都是空
            first = newNode;
            last = newNode;
        }
        size++;
        return true;

    }

    // 默认删除头部的数据
    public boolean removeFirst() {
        if(size < 0){
            return false;
        }
        if(first != null){
            first = first.getNext();
            size--;
        }
        return true;
    }

    // 删除尾部的数据
    public boolean removeLast(){
        if(size <= 0){
            return false;
        }
        if(size == 1){
            first = null;
            last = null;
            size--;
            return true;
        }
        if(last != null){
            last = getNode(size - 2);
            last.setNext(null);
            size --;
        }
        return true;
    }

    public boolean remove(int index) {
        if(size < 0){
            return false;
        }
        if(size == 1){
            first = null;
            last = null;
            size--;
            return true;
        }else {
            Node node = getNode(index - 1);
            node.setNext(node.getNext().getNext());
        }
        size--;
        return true;
    }

    // 修改指定下标位置的元素
    public boolean set(int index,Integer data){
        Node node = getNode(index);
        node.setData(data);
        return true;
    }

    // 根据下标获取指定的数据
    public Integer get(int index) {
        return getNode(index).getData();
    }

    // 获取链表的长度
    public int size() {
        return size;
    }

    // 根据下标获取指定的结点
    private Node getNode(int index){
        if(index < 0){
            index = 0;
        }
        if(index >= size - 1){
            index = size - 1;
        }
        // 找到第index个
        Node cursor = first;
        for (int i = 0; i < index; i++) {
            cursor = cursor.getNext();
        }
        return cursor;
    }
}
posted @ 2022-07-25 20:02  菜鸡成长记  阅读(21)  评论(0)    收藏  举报