顺序表

顺序表(ArrayList)

1.顺序表的原理

2.Java中提供得顺序表(ArrayList)的主要用法(增删查改)

3.ArrayList的继承链条

可以被迭代的(Iterable)

interface Iterble<T>{
     Iterator<T> iterator();
}
     //通过iterator()方法,返回迭代器
     //通过迭代器,可进一步的进行迭代(Iterator)

迭代器(Iterator)

interface Iterator<E>{
      boolean hasnext();
      E next();
}
// hasnext()——ture :还有下一个/没有迭代完 false: 没有下一个了/迭代完了
//next() :1.返回下一个元素 2.同时跳过该元素(这个元素被迭代过了) 这两条都是基于hasnext() 返回ture的前提;
// Iterator的用法类似于以前的Scanner
package demo;

import java.util.ArrayList;
import java.util.Iterator;

public class IterableDemo {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("我");
        list.add("你");
        list.add("他");
        list.add("谁");

      for (String e : list) {
           System.out.println(e);
       }

        Iterable<String> r1 = list;


        // 假如不知道 r1 中一共有多少元素
        Iterator<String> it = r1.iterator();
        while (it.hasNext()) {
            // 能进到循环中来,代表 it.hasNext() => true 了,所以,迭代器中还有元素
            // 所以,正确地掉用 next() 方法
            String s = it.next();
            System.out.println(s);
      }

        // r1 指向的对象,具备迭代能力
        // 迭代其中的每一个元素
        
      // 1. 通过 r1 得到迭代器对象(Iterator)
        Iterator<String> it = r1.iterator();

      // 2. 利用迭代器对象,进行遍历
        System.out.println(it.hasNext()); // true
        String s1 = it.next();            // 返回 "我",iterator 内部走到了 "你"
        System.out.println(s1);                 // 我

        System.out.println(it.hasNext()); // true
        String s2 = it.next();            // 返回 "你",iterator 内部走到了 "他"
        System.out.println(s2);                 // 你

        System.out.println(it.hasNext()); // true
        String s3 = it.next();            // 返回 "他",iterator 内部全部走完了
        System.out.println(s3);                 // 他

        System.out.println(it.hasNext()); // false
    }
}

package demo;

import java.util.ArrayList;
import java.util.Collection;

public class CollectionDemo {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("我");
        list.add("你");
        list.add("他");
        list.add("谁");

        Collection<String> collection = list;
        System.out.println(collection);

        for (String e : collection) {
            System.out.println(e);
        }

        collection.add("不是我");
        System.out.println(collection);
        collection.remove("你");
        System.out.println(collection);
        System.out.println(collection.isEmpty());
        System.out.println(collection.size());
        collection.clear();
        System.out.println(collection);
        System.out.println(collection.isEmpty());
        System.out.println(collection.size());
    }
}
interface Collection<E>{
         boolean add(E e);
}
//把元素e放入集合中
//在Collection的语境下,可以说是尾插吗?
//不行!Collection代表的不一定是线性表,所以就没有次序的概念,没有头和尾的概念
//add 的时候,可能会出现放不进去的时候,所以通过返回值,来判断是否放入成功。
//在Collection的语境下,add可以返回false
//在list的语境下,add一定返回ture

复习多态的知识:

1.通过引用可以执行哪些方法?

由引用类型决定

2.通过引用执行方法后,真正执行的是哪个类的方法

由引用指向的对象类型决定

class Person{....}
class Teacher extends Person{...}
Teacher t = new Teacher();
Person p = t;
//让p指向t目前指向的对象
//由于p的类型是Person
//t 目前指向的对象的类型是Teacher
//所以允许指向

顺序表

1.学会顺序表的原理(逻辑上的理解)

2.重点学习Java中的顺序表(ArrayList)的使用

—————— 常见方法的含义+用法

—————— 继承链条+能力来自谁

3.实现自己的ArrayList

简化次要目标

1.不再追求泛型作为元素类型,使用Integer类型作为元素类型(不用基本类型,主要为了体现equals这些特点)
2.不会出现null元素
角色转换:顺序表的使用者 —>顺序表的实现者
我们需要关心容量的问题了(capacity)

capacity —— size
3.实现的方法(常见方法)+迭代器
实现过程中关注
1.原理
2.代码
3.性能——复杂度

package my_arraylist;

/**
 * Program: Created with IntelliJ IDEA
 * <p>
 * Description:
 * <p>
 * Author: Wan9N1n9
 * <p>
 * Time:2021-03-17 21:05
 **/
public interface MyList {

    boolean add(Integer e);
    void add(int index, Integer e);

    Integer remove(int index);
    boolean remove(Integer e);

    Integer get(int index);
    Integer set(int index, Integer e);

    boolean contains(Integer e);
    int indexOf(Integer e);
    int lastIndexOf(Integer e);

    void clear();
    int size();
    boolean isEmpty();
}

package my_arraylist;

import java.util.Arrays;

/**
 * Program: Created with IntelliJ IDEA
 * <p>
 * Description:
 * <p>
 * Author: Wan9N1n9
 * <p>
 * Time:2021-03-17 21:16
 **/
public class MyArrayList implements MyList {

    private Integer[] array;
    private int size;

    public MyArrayList(){
        array = new Integer[16];
        size = 0;
    }

    // O(n)
    // 供内部进行容量控制
    // 这个方法一旦执行结束后,可以保证,顺序表内部的数组中,至少还可以放一个元素
    private void ensureCapacity() {
        if (size < array.length) {
            // 当前元素个数 < 容量:至少还能放一个元素
            return;
        }
        // 否则进行扩容 —— 搬家的过程
        // 1. 找到一个新的房子,一般来说,房子大小往 2 倍进行扩容(经验值)
        // 如果新房子太大,意味着很多空间在闲置,浪费了
        // 如果新房子太小,意味着需要经常扩容
        // 所以,经过经验看,扩大 2 倍相对比较合适
        // 原来的房子大小是 array.length,新的房子的大小就是 array.length * 2
        Integer[] newArray = new Integer[array.length * 2];

        // 2. 把原来房子中的东西全部搬到新房子中来
        for (int i = 0; i < array.length; i++) {
            newArray[i] = array[i];
        }

        // 3. 通过发朋友圈,公布新房子的位置,老房子就可以推掉了
        this.array = newArray;  // 修改了对象中的属性,以后再操作顺序表,就操作 newArray 指向的对象了
    }


    // 数据规模 n是什么?元素个数 (size)
    //O(1)
    // 虽然最坏情况下,确实是 O(n)
    // 但由于扩容的机会非常少,所以,一般还是认为尾插是 O(1)
    @Override
    public boolean add(Integer e) {
        //TODO:暂时不考虑容量不足的情况
        ensureCapacity();

        array[size] = e;// 尾插,放入元素 O(1)
        size++; // o(1)

        return true;
    }


    //O(n)
    @Override
    public void add(int index, Integer e) {
        //TODO:暂时不考虑容量不足的情况
        ensureCapacity();   // O(n)

        //1.判断index下标是否合法
        if (index < 0 || index > size){
            throw new ArrayIndexOutOfBoundsException("index:"+ index + "size:" + size);
        }

        //2.进行插入.[index,size)
        for (int from = size - 1;from >= index; from--){
            int to = from + 1;
            array[to] = array[from];
        }
//        for (int to = index +1; to <= size; to++){
//            int from = to -1;
//            array[to] =array[from];
//
//        }
        //把元素放入index 位置
        array[index] = e;
        //size 增加
        size++;

    }

    //O(n)
    @Override
    public Integer remove(int index) {

        // 判断下标是否合法
        if (index < 0 || index >= size){
            throw new ArrayIndexOutOfBoundsException("index:"+ index + "size:" + size);
        }

        //1.把[index + 1,size - 1]的元素往前移一格
         Integer e = array[index];
        for (int from = index + 1;from < size; from++){
            int to = from - 1;
            array[to] = array[from];
        }
        //2.把size-1 置为null
        array[size-1] = null;
        //3.size 减一
        size--;
        return e;
    }

    //O(n)
    @Override
    public boolean remove(Integer e) {
        int i = indexOf(e);
        if (i < 0) {
            return false;
        }

        remove(i);
        return true;
    }

    //O(1)
    @Override
    public Integer get(int index) {
        //判断下标的合法性
        if (index < 0 || index >= size){
            throw new ArrayIndexOutOfBoundsException("index:"+ index + "size:" + size);
        }

        return array[index];
    }

    //O(1)
    @Override
    public Integer set(int index, Integer e) {
        if (index < 0 || index >= size){
            throw new ArrayIndexOutOfBoundsException("index:"+ index + "size:" + size);
        }
         int oldE = array[index];
        array[index] = e;
        return oldE;
    }

    @Override
    public boolean contains(Integer e) {
        return indexOf(e) >=0;
    }

    @Override
    public int indexOf(Integer e) {
        for (int i = 0;i < size;i++){
            if (e.equals(array[i])){
                return i;
            }

        }
        return -1;
    }

    @Override
    public int lastIndexOf(Integer e) {
        for (int i = size - 1; i >= 0; i--){
            if (e.equals(array[i])){
                return i;
            }
        }
        return -1;
    }

    @Override
    public void clear() {
        Arrays.fill(array,null);
        size = 0;
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public String toString() {
        Integer[] toShow = Arrays.copyOf(array, size);
        //toShow.length = size
        return Arrays.toString(toShow);
    }

    @Override
    public boolean isEmpty() {
        return size == 0;


    }
}

package my_arraylist;

/**
 * Program: Created with IntelliJ IDEA
 * <p>
 * Description:
 * <p>
 * Author: Wan9N1n9
 * <p>
 * Time:2021-03-18 15:00
 **/
public class MyArrayListTest {
    public static void main(String[] args) {
        MyList list = new MyArrayList();
        System.out.println(list);   // []
        list.add(1);
        list.add(2);
        list.add(3);
        System.out.println(list);   // [1, 2, 3]
        list.add(0, 100);
        list.add(0, 200);
        list.add(0, 300);
        System.out.println(list);   // [300, 200, 100, 1, 2, 3]

        Integer remove = list.remove(2);
        System.out.println(list);   // [300, 200, 1, 2, 3]
        System.out.println(remove); // 100

        boolean r = list.remove((Integer)1);    // 通过类型转换,确认调用的是 remove(Integer) 而不是 remove(int)
        System.out.println(r);      // true
        System.out.println(list);   // [300, 200, 2, 3]

        System.out.println(list.size());
        System.out.println(list.isEmpty());
        list.clear();
        System.out.println(list.size());
        System.out.println(list.isEmpty());
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值