美文网首页数据结构
动态数组(使用泛型)实现存储复杂类型数据【有错误尽管提,大家一起

动态数组(使用泛型)实现存储复杂类型数据【有错误尽管提,大家一起

作者: 小小飞的救赎 | 来源:发表于2018-09-06 16:41 被阅读0次
/**
 * 使用泛型实现存储各种复杂数据类型
 * @author hcc
 *
 */
public class HGenericityArrayList<E> {
        //默认数组的容量
        private static final int DEFAULT_CAPACITY = 10;
        //用来存储数据的数组
        private E[] data;
        //数据的个数(大小)
        private int size;
        
        /**
         * 有参构造函数
         * @param capacity 数组的容量
         */
        @SuppressWarnings("unchecked")
        public HGenericityArrayList(int capacity) {
            if(capacity > 0) {
                this.data = (E[]) new Object[capacity];     
                size = 0;
            }
            else {
                throw new  IllegalArgumentException("初始容量:"+capacity);
            }
        }
            
        /**
         * 无参构造函数 默认容量为10
         */
        public HGenericityArrayList() {
            this(DEFAULT_CAPACITY);
        }
        /**
         * 判断是否为空
         * @return true表示为空 false表示不为空
         */
        public boolean isEmpty() {
//          if(size==0) {
//              return true;
//          }
//          return false;
            //简写方式
            return size == 0;
        }
        
        /**
         * 添加数据 差一点的就是没有实现动态扩容
         * @param index 数据添加的位置
         * @param num 将要添加的数据
         */
        @SuppressWarnings("unchecked")
        public void add(int index,E num) {
            //如果“位置“的值小于0 或者大于最大的容量 报错 
            //熟知:size的大小应该是小于等于data.length 大于等于0的
            if(index < 0 || index > this.data.length) {
                throw new IllegalArgumentException("索引错误信息: index>capacity 或者 index<0");
            }else if(index > this.size) {
                //该条件判断的是:不能在任意位置添加数据,必须满足在插入的位置之前有数据
                throw new IllegalArgumentException("索引错误信息: index>size");
            }else {
                //判断是否需要扩容 当数据的个数和容量相等时需要扩容
                if(this.size == this.data.length) {
                    resize(data.length*2);
                }
                //将index(包括)之后的数据向后挪动
                for(int i = size-1;i>index-1;i--) {
                    this.data[i+1] = this.data[i];
                }
                this.data[index] = num;
                this.size++;
            }
        }
        /**
         * 在末尾插入数据
         * @param num
         */
        public void add(E num) {
            add(this.size,num);
        }
        
        /**
         * 删除指定位置的数据
         * @param index 索引
         * @return true表示删除成功 false表示删除失败
         */
        public E remove(int index) {    
            if(index < 0 || index >= this.size) {
                throw new IllegalArgumentException("索引错误信息: index>size 或者 index<0");
            }
            E num = this.data[index];
            for (int i = index; i < (size - 1); i++) {
                this.data[i] = this.data[i + 1];
            }       
            size--;
            this.data[size] = null;
            if(size == (this.data.length/2)) {
                resize(this.data.length/2);
            }
            return num;
        }
        /**
         * 删除数组中值为num的第一个位置上的数据
         * @param num 要删除的数据
         * @return true表示删除成功 false表示删除失败
         */
        public boolean removeElement(E num) {
            int index = find(num);
            if(index == -1) {
                throw new IllegalArgumentException("数组中没有"+ num +"这个值!");
            }
            return remove(index) == num;
        }
        /**
         * 删除数组中值为num的所有数据
         * @param num 要删除的数据
         * @return true表示删除成功 false表示删除失败
         */
        public boolean removeAllElement(E num) {
            int[] indexs = findAll(num);
            boolean tf = false;
            for (int i = 0; i < indexs.length; i++) {
                tf = (remove(indexs[i]) == num);
            }
            return tf;
        }
        /**
         * 修改指定位置的值
         * @param index 索引
         * @param num 值
         */
        public void set(int index,E num) {
            if(index < 0 || index >= this.size) {
                throw new IllegalArgumentException("索引错误信息: index>size 或者 index<0");
            }
            this.data[index] = num;
        }
        /**
         * 得到某个元素在数组中的第一个位置
         * @param num 索引
         * @return -1表示该数据不存在 其他大于等于0小于等于size的表示位置
         */
        public int find(E num) {
            for(int i = 0;i < this.size; i++) {
                if(this.data[i] == num) {
                    return i;
                }
            }
            return -1;
        }
        /**
         *得到某个元素在数组中的所有位置(索引)
         * @param num 数据
         * @return 索引
         */
        public int[] findAll(E num) {
            int[] arr = new int[size];
            int position = 0;
            for(int i = 0;i<this.size;i++) {
                if(num == this.data[i]) {
                    arr[position] = i;
                    position++;
                }
            }
            //以下操作是把数据从长度为size的数据转移到了长度为"num在数组中的个数"中去
            int[] arr1 = new int[position];
            for(int i = 0;i < position;i++) {
                arr1[i] = arr[i];
            }
            return arr1;
        }

        /**
         * 通过索引获取数组中的值
         * @param index 索引
         * @return 返回数据
         */
        public E get(int index) {
            if(index < 0 || index >= this.size) {
                throw new IllegalArgumentException("索引错误信息: index>size 或者 index<0");
            }
            return this.data[index];
        }
        
        /**
         * 获取数组中数据的个数
         * @return 数据的数量
         */
        public int getSize() {
            return this.size;
        }
        /**
         * 获取数组的容量
         * @return 输入容量
         */
        public int getCapacity() {
            return this.data.length;
        }
        
        /**
         * 将数据转化为字符串并返回
         */
        public String toString() {
            StringBuilder str  = new StringBuilder();
            str.append(String.format("HArray: size = %d, capacity = %d\n", this.size,data.length));
            if(this.size != 0) {
                str.append("[");
                for(int i = 0;i<this.size;i++) {
                    if(i == (size-1)) {
                        str.append(this.data[i]);
                        str.append("]");
                        break;
                    }
                    str.append(this.data[i]+",");
                }
            }
            return str.toString();
        }
        
        /**
         * @param num 要判断的数据
         * @return true表示存在 false表示不存在
         */
        public boolean contains(E num) {
            for(int i = 0; i < this.size;i++) {
                if(num.equals(data[i])) {
                        return true;
                }
            }
            return false;
        }
        /**
         * 改变动态数组的容量
         * @param capacity
         */
        @SuppressWarnings("unchecked")
        private void resize(int capacity) {
            E[] arr = (E[]) new Object[capacity];
            for(int i = 0;i<this.size;i++) {
                arr[i] = data[i];
            }
            data = arr;
        }
}

相关文章

  • 动态数组(使用泛型)实现存储复杂类型数据【有错误尽管提,大家一起

  • C语言 泛型动态数组

    泛型实现思路:万能指针void *动态数组实现思路:动态进行数组内存的扩容 realloc 泛型动态数组 数组可以...

  • Swift学习笔记-泛型

    泛型能让我们使用的类型和函数使用未知的类型,许多内置类型,例如可空类型,数组和字典都是用泛型实现的。 泛型类型 下...

  • typescript之泛型

    泛型是什么,为什么要使用泛型使用泛型定义数组中的元素类型,promise返回的数据类型等 创建泛型函数 exten...

  • 第五部分 集合

    (1)长度可变 (2)只能存储引用类型 (3)不使用泛型时,存储对象可以不是同种数组类型 Collection接口...

  • 数据结构

    数组和集合 -1 数组:有固定长度 ,存放统一类型数据 -2 集合大小可动态扩展,可以存储各种类型的数据 开发常用...

  • 实现数组_2_泛型

    在创造自己的数组_1中,数组内存储数据只支持int类型,我们现在改成泛型。 测试类 测试Student类

  • java_泛型

    泛型:jdk1.5新特性 为什么要用泛型(解决元素存储安全,解决获取元素需要进行强制转换,代码复用动态指定数据类型...

  • 第七节: TypeScript 泛型

    1. 泛型理解 泛型是通过参数化类型来实现在同一份代码上操作多种数据类型。 1.1 未使用泛型 现在如果需要实现函...

  • Android中使用泛型

    泛型是什么 所谓“泛型”,就是“宽泛的数据类型”,任意的数据类型。我们为什么要使用泛型呢?数据类型为什么要使用"宽...

网友评论

    本文标题:动态数组(使用泛型)实现存储复杂类型数据【有错误尽管提,大家一起

    本文链接:https://www.haomeiwen.com/subject/qsixgftx.html