zoukankan      html  css  js  c++  java
  • 实现简单的List功能

    简单的实现javaArrayList(可扩容)功能,实现新增,删除,取数据。

    package algorithm.data_structure;
    
    /**
     * 模拟ArrayList类的功能
     * @author fangsh
     *
     */
    public class SimpleList<T> {
        
        private Object[] elements ;
        
        private int size = 0 ;//记录元素数组的长度
        
        private int elementsNum = 0 ;//记录元素的个数
        
        private final static int ADD_NUMBER = 10 ;//扩容数量
        private final static int RELEASE_CACHE = 5 ;//释放内存的大小
        
        /**
         * 添加元素
         * @param e
         * @return
         */
        public void add(T e){
            if(elements == null) elements = new Object[10] ; // 初始化元素数组,初始化长度为10
            
            if(elements.length <= elementsNum){//判断是否有空间添加元素
                addNumberCache() ;
            }
            elements[elementsNum] = e ;
            
            elementsNum++ ;
        }
        
        /**
         * 删除元素的方法,删除元素时,列表的长度不应该有所改变
         * @param e
         * @return
         * 第一次写方法时犯的错误:对象比较的时候,使用了==,应该使用equals;
         * 需要优化的地方,在删除元素的时候,是否把元素占用的内存释放(涉及长度不够增加的情况)
         */
        public boolean remove(T e){
            if(elements != null){
                if(elements.length > 0){
                    int removeIndex = 0 ;
                    for(int i=0; i<elements.length; i++){
                        Object obj = elements[i] ;
                        if(obj.equals(e)){
                            removeIndex = i ;
                            break ;
                        }
                    }
                    Object[] newObject = new Object[elements.length - 1] ;
                    for(int begin=0; begin<removeIndex; begin++){
                        newObject[begin] = elements[begin] ;
                    }
                    for(int continueIndex= removeIndex+1; continueIndex<elements.length; continueIndex++){
                        newObject[continueIndex - 1] = elements[continueIndex] ;
                    }
                    
                    elements = newObject ;
                    elementsNum -- ;
                    
                    return true ;
                }
            }
            return false ;
        }
        
        /**
         * 改进的删除方法,返回删除的元素,并且删除时不修改列表的长度
         * @param t
         * @return
         */
        public T remove2(T t) throws Throwable{
            if(elements == null || isEmpty())
                throw new Throwable("列表为空,或者列表中没有数据") ;
            int removeIndex = -1 ;
            for(int i=0; i<elements.length; i++){
                Object obj = elements[i] ;
                if(obj.equals(t)){
                    removeIndex = i ;
                }
                if(removeIndex != -1){
                    Object nextElement = null ;
                    if(i != elements.length-1)
                     nextElement = elements[i+1] ;
                    elements[i] = nextElement ;
                }
            }
            elementsNum -- ;
            if(removeIndex < 0)
                throw new Throwable("删除的元素不在列表内!") ;
            return t ;
        }
        
        public boolean isEmpty(){
            if(elementsNum == 0){
                return true ;
            }
            return false ;
        }
        
        @SuppressWarnings("unchecked")
        public T get(int index) throws Throwable{
            if(elements == null) throw new NullPointerException("列表为空!") ;
            if(index < 0) throw new Throwable("请输入有效的列表下标!") ;
            if(index > elements.length) throw new Throwable("您输入的下标超过列表元素的个数!") ;
            return (T)elements[index-1] ;
        }
        
        /**
         * 扩容的方法,默认扩容的长度为10
         */
        private void addNumberCache(){
            if(elements == null) return ;
            if(elements.length == elementsNum){
                Object[] newElements = new Object[elementsNum + ADD_NUMBER] ;
                for(int i=0; i<elements.length; i++){
                    newElements[i] = elements[i] ;
                }
                elements = newElements ;
            }
        }
        
        /**
         * 当SimpleList中的空余内存达到一定数量时,释放SimpleList中的内存
         */
        private void releaseNumberCache(){
            if(elements == null) return ;
            if(elements.length > (elementsNum + 10)){//达到释放标准
                Object[] newElements = new Object[elements.length - RELEASE_CACHE] ;
                for(int i=0; i<(elements.length - RELEASE_CACHE); i++){
                    newElements[i] = elements[i] ;
                }
                elements = newElements ;
            }
        }
        
        /**
         * 查询列表元素的个数
         * @return
         */
        public int getElementNum(){
            return elementsNum;
        }
        
        /**
         * 查询元素列表的长度
         * 注意这个方法一定不能用来判断列表元素的个数,因为列表可能存在多余空间
         * @return
         */
        public int getSize() throws Throwable{
            if(elements == null)
                throw new Throwable("列表为空!") ;
            return elements.length ;
        }
    }

    总结一下,做这个时出现的一些问题,日后注意:

    1、在对比对象的时候,一开始脑残的使用了“==” ,导致删除方法不成功,对象比较注意一定使用equals方法。

    2、做删除元素的时候,将元素数组的长度减少了,没有更新size这个字段,这个字段可以不用,需要这个值的时候,直接调用数组的length方法,减少bug出现的可能性(要随时同步size这个值,增加了出bug的可能性)

    3、一开始的删除方法,会新建一个数组,并且还要重新遍历原素组,将元素重新加入到新数组中,这样造成资源的浪费,可以直接将被删除元素之后的元素依次往前移,最后一个数组位置补null。这样避免了新建数组造成的资源开销。

  • 相关阅读:
    SQL Server 动态行转列(参数化表名、分组列、行转列字段、字段值)
    Web Api 跨域解决方案
    Web Api Session开启会话支持
    Web Service 学习
    省市选择器
    如何创建圆形头像和圆角图片
    E
    二叉树
    素数筛法
    Color Me Less
  • 原文地址:https://www.cnblogs.com/fsh1542115262/p/5611432.html
Copyright © 2011-2022 走看看