zoukankan      html  css  js  c++  java
  • 自定义ArrayList

    ArrayList

    1、ArrayList底层是使用数据实现的存储(动态数组)

    2、数组的特点:数组在内存中是一段连续的空间,每个元素都有一个下标,数组一旦创建,容量是不可以改变的。

    3、根据下标的特性:查询效率较高,而增加和删除元素就会导致数据发生移动(创建新数组,将旧数组中数据拷贝到新数组中),大量的数据在增加或者删除就会很消耗性能

    4、ArrayList是线程不安全的。

    通过ArrayList源码分析

    1、ArrayList的成员变量 elementData,是一个Object类型的数组

    2、size:集合的个数

    3、默认容量 DEFAULT_CAPACITY = 10 ;

    自定义 ArrayList01

    • 构造方法:在不传值的情况下,默认数组的容量是10

    • 构造方法:在给一个容量的前提下,将容器赋给数组

    • 增加方法:将元素添加到数组中

    • toString方法:将集合中的元素进行遍历,循环打印每一个元素

    package com.xw.arrayList;
    
    /**
     * 自定义实现ArrayList
     */
    public class MyArrayList01 {
    
        private Object[] elementData ;
    
        private int size ;
    
        private static final int DEFAULT_CAPACITY = 10 ;
    
        /**
         * 默认值10
         */
        public MyArrayList01(){
            elementData = new Object[10] ;
        }
    
        /**
         * 带容量的构造方法
         * @param capacity
         */
        public MyArrayList01(int capacity){
            elementData = new Object[capacity] ;
        }
    
        /**
         * 添加方法
         * @param object
         */
        public void add(Object object){
            elementData[size++] = object ;
        }
    
        public String toString(){
            StringBuilder sb = new StringBuilder() ;
            sb.append("[");
            for(int i=0;i<size;i++){
                sb.append(elementData[i]).append(",");
            }
            sb.append("]");
            int i = sb.lastIndexOf(",");
            if (i!=-1){
                sb.deleteCharAt(i);
            }
            return sb.toString();
        }
    
        public static void main(String[] args) {
            MyArrayList01 myArrayList01 = new MyArrayList01(20);
    
            myArrayList01.add("abc");
            myArrayList01.add("efg");
            myArrayList01.add("hig");
    
            System.out.println(myArrayList01);
        }
    
    }
    

    自定义 ArrayList02

    • 在第一个的基础上添加泛型
    package com.xw.arrayList;
    
    /**
     * 添加泛型
     * @param <E>
     */
    public class MyArrayList02<E> {
    
        private Object[] elementData ;
        private int size ;
    
        private static final int DEFAULT_CAPACITY = 10 ;
    
        public MyArrayList02(){
            elementData = new Object[10] ;
        }
    
        public MyArrayList02(int capacity){
            elementData = new Object[capacity] ;
        }
    
        /**
         * 添加方法
         * @param e
         */
        public void add(E e){
            elementData[size++] = e ;
        }
    
        public String toString(){
            StringBuilder sb = new StringBuilder() ;
            sb.append("[");
            for(int i=0;i<size;i++){
                sb.append(elementData[i]).append(",");
            }
            sb.append("]");
            int i = sb.lastIndexOf(",");
            if (i!=-1){
                sb.deleteCharAt(i);
            }
            return sb.toString();
        }
    
        public static void main(String[] args) {
            MyArrayList02<String> myArrayList01 = new MyArrayList02<String>(20);
    
            myArrayList01.add("abc");
            myArrayList01.add("efg");
            myArrayList01.add("hig");
    
            System.out.println(myArrayList01);
        }
    }
    

    自定义 ArrayList03

    思考问题:

    1、数组的容量问题,在指定容量之后(20),循环添加操作(21)次,就会出现错误。-> 扩容问题

    2、什么时候扩容?:在集合的 size==数组的长度

    3、怎么扩容,扩多大:可以将新数组的长度 * /(+)操作,对于计算机底层来说,位运算效率是很高的 我们使用 >>(右移1位相当于除2取余) 或者 << (左移1位相当于*2)

    4、其实扩容的本质就是创建新的数组,将旧数组中的数据拷贝到新数组中。

    新增的方法

    1、扩容

    2、设置添加元素,根据指定下标添加元素

    3、根据下标获取元素

    4、增加一些判断操作

    package com.xw.arrayList;
    
    /**
     * 增加get set方法
     * @param <E>
     */
    public class MyArrayList03<E> {
    
        private Object[] elementData ;
        // 长度
        private int size ;
    
        private static final int DEFAULT_CAPACITY = 10 ;
    
        public MyArrayList03(){
            elementData = new Object[10] ;
        }
    
        public MyArrayList03(int capacity){
            if (capacity<=0){
                throw new RuntimeException("容器容量不能为负数");
            }else if (capacity == 0){
                elementData = new Object[DEFAULT_CAPACITY];
            }else {
                elementData = new Object[capacity] ;
            }
        }
    
        /**
         * 添加方法
         * @param e
         */
        public void add(E e){
            // 什么时候扩容
            if (size==elementData.length){
                Object[] newArray = new Object[elementData.length+(elementData.length>>1)];
                System.arraycopy(elementData,0,newArray,0,elementData.length);
                elementData = newArray ;
            }
            elementData[size++] = e ;
        }
    
        /**
         * 获取元素
         * @param index
         */
        public <E> E get(int index){
            if (index<0||index>size-1){ // 10 index 0|0-9
                throw new RuntimeException("索引不合法");
            }
            return (E)elementData[index] ;
        }
    
        /**
         * 设置值
         * @param element
         * @param index
         */
        public void set(E element,int index){
            if (index<0||index>size-1){ // 10 index 0|0-9
                throw new RuntimeException("索引不合法");
            }
            elementData[index] = element ;
        }
    
        /**
         * toString
         * @return
         */
        public String toString(){
            StringBuilder sb = new StringBuilder() ;
            sb.append("[");
            for(int i=0;i<size;i++){
                sb.append(elementData[i]).append(",");
            }
            sb.append("]");
            int i = sb.lastIndexOf(",");
            if (i!=-1){
                sb.deleteCharAt(i);
            }
            return sb.toString();
        }
    
        public static void main(String[] args) {
            MyArrayList03<String> myArrayList01 = new MyArrayList03<String>(20);
    
            for (int i = 0; i < 40; i++) {
                myArrayList01.add("xing"+i);
            }
    
            System.out.println(myArrayList01);
            System.out.println(myArrayList01.get(1).toString());
    
            myArrayList01.set("张三女",10);
            System.out.println(myArrayList01);
    
            myArrayList01.get(40);
            System.out.println(myArrayList01);
        }
    
    }
    

    自定义 ArrayList04

    删除元素操作:

    1、怎么删:本质还是数组的拷贝

     删除元素 -> 数组的拷贝
     a b c d e f index
     a b (c) d e f  index+1
    

    2、如何拷贝:就是从删除掉的那个元素的下标+1的位置开始移动

    • elementData:原数组

    • index+1:从哪开始移动

    • elementData:新数组

    • index:新数组的下标开始移动的索引

    • elementMoved:移动多少

    int elementMoved = elementData.length-1-index; // 计算个数
    System.arraycopy(elementData,index+1,elementData,index,elementMoved);
    

    3、最后一点:数组中最后一个位置空了出来,需要移除,集合的个数需要 --

    4、增加的方法

    • 根据下标删除元素

    • 集合的个数

    • 判断是否为空

    package com.xw.arrayList;
    
    /**
     * 添加remove方法
     * size:获取集合的个数
     * isEmpty:判断集合是否为空
     * @param <E>
     */
    public class MyArrayList04<E> {
    
        private Object[] elementData ;
        // 个数
        private int size ;
    
        private static final int DEFAULT_CAPACITY = 10 ;
    
        public MyArrayList04(){
            elementData = new Object[10] ;
        }
    
        public MyArrayList04(int capacity){
            if (capacity<=0){
                throw new RuntimeException("容器容量不能为负数");
            }else if (capacity == 0){
                elementData = new Object[DEFAULT_CAPACITY];
            }else {
                elementData = new Object[capacity] ;
            }
        }
    
        /**
         * 添加方法
         * @param e
         */
        public void add(E e){
            // 什么时候扩容
            if (size==elementData.length){
                Object[] newArray = new Object[elementData.length+(elementData.length>>1)];
                System.arraycopy(elementData,0,newArray,0,elementData.length);
                elementData = newArray ;
            }
            elementData[size++] = e ;
        }
    
        /**
         * 获取元素
         * @param index
         */
        public <E> E get(int index){
            if (index<0||index>size-1){ // 10 index 0|0-9
                throw new RuntimeException("索引不合法");
            }
            return (E)elementData[index] ;
        }
    
        /**
         * 设置值
         * @param element
         * @param index
         */
        public void set(E element,int index){
            if (index<0||index>size-1){ // 10 index 0|0-9
                throw new RuntimeException("索引不合法");
            }
            elementData[index] = element ;
        }
    
        /**
         * toString
         * @return
         */
        public String toString(){
            StringBuilder sb = new StringBuilder() ;
            sb.append("[");
            for(int i=0;i<size;i++){
                sb.append(elementData[i]).append(",");
            }
            sb.append("]");
            int i = sb.lastIndexOf(",");
            if (i!=-1){
                sb.deleteCharAt(i);
            }
            return sb.toString();
        }
    
        public void removeElement(E element){
            // 循环比较每一个元素
            for (int i=0;i<size;i++){
                if (element.equals(get(i))){
                    remove(i);
                }
            }
        }
    
        public int size(){
            return size ;
        }
    
        public boolean isEmpty(){
            return size==0?true:false;
        }
    
        /**
         * 根据下标删除元素
         * @param index
         */
        public void remove(int index){
            // 删除元素 -> 数组的拷贝
            // a b c d e f index
            // a b d e f  index+1
            int elementMoved = elementData.length-1-index; // 5-2
            if (index>0){
                System.arraycopy(elementData,index+1,elementData,index,elementMoved);
            }
            // 移除最后一个元素
            elementData[size-1] = null ;
            size--;
        }
    
        public static void main(String[] args) {
            MyArrayList04<String> myArrayList01 = new MyArrayList04<String>(20);
    
            for (int i = 0; i < 40; i++) {
                myArrayList01.add("xing"+i);
            }
    
            System.out.println(myArrayList01);
            System.out.println(myArrayList01.get(1).toString());
    
            myArrayList01.set("张三女",10);
            System.out.println(myArrayList01);
    
            myArrayList01.remove(10);
            System.out.println(myArrayList01);
    
            System.out.println(myArrayList01.size());
            System.out.println(myArrayList01.isEmpty());
    
    //        System.out.println(myArrayList01.size-1);
    //        System.out.println(myArrayList01.elementData.length);
        }
    
    }
    

    OK !!!。

    下一篇:自定义LinkedList

    做的不好,多多指教
  • 相关阅读:
    Discuz 页面不能加载插件的原因和解决方法
    discuz 插件核心函数hookscript分析.
    比较容易犯的一些智障错误(不定时修改)
    浅谈树状数组入门
    图论的小总结
    usaco 2009 12 过路费
    0122(本来是想ak的但是因为智障只拿了200。)
    图论
    欧拉路
    bfs
  • 原文地址:https://www.cnblogs.com/xingStudy/p/14626825.html
Copyright © 2011-2022 走看看