day_16 数组封装、集合

 1.数组封装
    1.需求
        数组操作,相对还是比较复杂的,也不能做添加和删除操作,当需要添加和删除的时候需要新建数组,
        复制数组,或者元素移位,比较麻烦所以我们对这些添加和删除操作进行封装

    2.编码实现
        public class Array {           
            // 封装的数组
            private Object[] elements;            
            // 数组中已有元素个数           
            private int size = 0;
            public Array() {
                // 数组默认长度为 10
                elements = new Object[10];
            }
            
            // 获取元素个数           
            public int size() {
                return size;
            }

            
            // 根据索引获取数据            
            public Object get(int index) {
                // 如果index >= size 说明 不存在
                if (index >= size) {
                    throw new ArrayIndexOutOfBoundsException(index);
                }
                return elements[index];
            }

          
            // 更改
            public void set(int index, Object element) {
                // 如果index >= size 说明 不存在
                if (index >= size) {
                    throw new ArrayIndexOutOfBoundsException(index);
                }
                elements[index] = element;
            }
        
            // 向数组中添加元素 
            public void add(Object element) {
                // 1 判断数组中是否满了
                if (size == elements.length) {
                    // 1.2 满了 就扩容,复制数组,再放进去
                    // 扩容为原来的二倍
                    Object[] newArr = new Object[size << 1];
                    // 数组复制
                    System.arraycopy(elements, 0, newArr, 0, size);
                    // 赋值
                    elements = newArr;
                }
                // 添加进去,size++
                elements[size] = element;
                size++;
            }

            // 删除指定元素
            public void remove(int index) {
                // 如果index >= size 说明 不存在
                if (index >= size) {
                    throw new ArrayIndexOutOfBoundsException(index);
                }
                // 移位
                for (int i = index; i < size - 1; i++) {
                    elements[index] = elements[index + 1];
                }
                // 最后一位赋值为null
                elements[size - 1] = null;
                // 个数-1
                size--;
            }
        
    3.测试
        //创建对象
        Array arr = new Array();
        //元素个数
        System.out.println(arr.size());
        //尾部添加
        arr.add(1);
        arr.add(12);
        arr.add(13);
        arr.add(14);
        arr.add(15);
        System.out.println(arr.size());
        //更改
        arr.set(0,"张三");
        for(int i=0;i<arr.size();i++){
            //获取
            System.out.println(arr.get(i));
        }
        arr.remove(3);
        for(int i = 0;i<arr.size();i++){
            System.out.println(arr.get(i));
        }

 Object数组可以放任何数据类型的数组 
 arraycopy(原数组,原数起始位置,现,现起始,现长度)

封装增删改查

2.集合
    1.概述
        数组长度是固定,当添加的元素超过了数组的长度时需要对数组重新定义, 这样太麻烦了! 
        所以, Java内部给我们提供了集合类,能存储任意对象,长度是可以改变的,随着元素的增加而增加,随着元素的减少而减少.

        Java集合是使程序能够存储和操纵元素不固定的一组数据。所有Java集合类都位于java.util包中
        
        问:之前我们需要把多个元素放到一起的时候,使用的是数组,那么为什么还要提供Java集合工具类呢?
           我们通过对比数组和Java集合工具类来解释Java集合工具类的必要性

    集合和数组的区别
        数组既可以存储基本数据类型,又可以存储引用数据类型, 
        基本数据类型存储的是值, 引用数据类型存储的是地址值;
        
        集合只能存储引用数据类型(对象), 集合中也可以存储基本数据类型,
        但是在存储的时候会自动装箱(JDK1.5新特性)变成对象.

    注:如果集合中存放基本类型,一定要将其“装箱”成对应的“基本类型包装类”
    
    2.继承体系
        图间:继承体系
        
        Collection是集合,两个直接子接口是List和set

        List特性:有序,可重复,保证数据的添加顺序和取出顺序一致
        set特性: 无序,不可重复,不能保证数据的添加和取出顺序一致

        List有三个子类:
            ArrayList:底层是数组,查询和更改效率极高
            LinkedList:底层是双向链表,添加和删除效率要高一些
            Vector: 底层也是数组,是线程安全,已废弃,被ArrayList代替
        set有两个子类:
            HashSet:底层是散列表
            TreeSet:底层是二叉树

    3.Collection 
        Collection作为集合类的父类,所以collection中的方法是所有集合类都有的方法

        1.常用方法
            boolean add(Object o):用于向集合里添加一个元素,添加成功返回true
            void clear():清除集合里所有元素,将集合长度变为0
            boolean containsAll(Collection c):返回集合里是否包含集合c里的所有元素
            int hashCode():返回此collection的哈希码值
            boolean isEmpty():返回集合是否为空,当集合长度为0时,返回true
            Iterator iterator():返回一个Iterator对象,用于遍历集合里的元素
            boolean remove(Object o):删除集合中所有指定元素o,该方法将返回true
            boolean removaAll(Collection c):删除集合中集合c里包含的所有元素,返回true
            boolean retainAll(Collection c):从集合中删除不在集合c里包含的元素,返回true
            int size():返回集合中的元素个数
            Object[] toArray():该方法把集合转换成一个数组,所有集合元素变成对应的数组元素

        2.使用方式
            以ArrayList为例
            
            // 创建一个ArrayList对象
            Collection collection = new ArrayList();
            // 判断是否为空
            System.out.println(collection.isEmpty());
            // 已有元素个数
            System.out.println(collection.size());
            // 添加 , 如果添加一个基本类型,则会进行自动装箱为对应的包装类类型,然后再发生多态转型为Object类型
            collection.add(1);
            collection.add(3);
            collection.add(2);
            collection.add("张三");
            System.out.println(collection.size());
            System.out.println(collection);
            // 删除指定元素,注意 不是索引,是根据数据删除
            collection.remove("张三");
            System.out.println(collection);
            // 转换为数组
            Object[] arr = collection.toArray();
            for (int i = 0; i < arr.length; i++) {
                System.out.println(arr[i]);
            }
            // 清空集合中的数据
            collection.clear();
            System.out.println(collection.size());

        3.Iterator
            迭代器:又称光标(cursor)是程序设计的软件设计模式,可在容器对象上遍访的接口,
            
            迭代器是一种模式,它可以使遍历和被遍历的对象相分离,我们就不再关心底层是什么数据结构,
            是如何进行数据存储的只要拿到迭代器对象,就可以进行遍历

            挨个输出集合中的元素
    
            collection中 提供了一个 iterator() 方法 用于获取迭代器对象
                集合.iterator();
            
            迭代器中,有三个方法
                1 boolean  hasNext() : 判断游标下是否还有元素,默认指向顶端,并没有指向第一个元素
                2 E next() : 将迭代器游标向下移动一位,并取出该元素
                3 remove () : 删除当前执行的元素,会把集合中的也删除
            
            迭代器一旦创建,集合不能添加和删除,如果添加和删除了,需要重新生成迭代器
            
            增强for循环forEach 就是迭代器的简写方式

            Collection c = new ArrayList();
            // 添加
            c.add(1);
            c.add(11);
            c.add(12);
            c.add(13);
            c.add(14);
            // 生成迭代器
            Iterator it = c.iterator();
            // 生成迭代器之后,不能添加和删除,除非重新生成
            // c.add(14);
            while (it.hasNext()) {
                Object o = it.next();
                System.out.println(o);
            }
            // 迭代器使用完之后,想要再次使用,需要重新生成,因为光标已经指向最后一个了
            it = c.iterator();
            while (it.hasNext()) {
                Object o = it.next();
                System.out.println(o);
            }

        4.注意
            contains(Object o) : 判断是否包含某个元素
            remove(Object o ) : 删除指定元素
            这两个方法,底层都会去调用equals方法进行比较

            {
                equals方法 p9
            }

    4.forEach
        public static void main(String[] args) {
            int[] arr = {1,2,3};
            for (int i = 0; i < arr.length; i++) {
                System.out.println(arr[i]);
            }
            // ------
            // 会把 数组中每个元素 赋值给 变量 element  不是下标
            for (int element : arr) {
                System.out.println(element);
            }
            Collection c = new ArrayList();
            c.add("a");
            c.add("b");
            c.add("c");
            // foreach是迭代器的简写方式,所以功能有限,只能查询,不能删除
            // 想要在遍历中删除,需要使用迭代器的remove
            for (Object object : c) {
                System.out.println(object);
            }
        }

    5.List 
        1.ArrayList
            List 特性 : 有序 可重复,保证数据的添加顺序和取出顺序一致
            
            List 有三个子类 : 
                ArrayList : 底层是数组,查询和更改效率极高 ,默认初始化容量为10,扩大为原来的1.5倍,非线程安全
                        创建对象的时候,没有容量,就是0 , 当第一次添加数据的时候,才会初始化容量
                        1.5倍 oldCapacity + (oldCapacity >> 1);
                LinkedList : 底层是双向链表,添加和删除效率要高一些
                Vector : 底层也是数组,是线程安全,已废弃,不推荐使用,已被ArrayList代替,默认认初始化容量为10,扩大为原来的2倍

            // 集合中只能保存引用数据类型,如果添加的是基本类型的话,
            // 会先进行自动装箱为对应的包装类,然后发生多态转型为Object类型
            // add(E e) : 尾部添加
            list.add(1);
            list.add(2);
            // add(int index,E e) : 把元素插入到指定位置,非特殊情况,尽量不用,因为其他元素需要向后移位
            list.add(0,3);
            // set(int index,E e) : 更改指定索引的元素值
            list.set(1, 4);
            // get(int index) : 获取对应索引的元素值
            System.out.println(list.get(0));
            // list中 remove方法有重载
            // 如果传入的是 int值 则是删除对应索引的元素 , 根据索引删除
            // 如果传入引用类型的值,则是删除对应的数据 , 根据元素值删除
            // 删除索引为0的元素
            list.remove(0);
            // 删除 值为4的元素
            list.remove(new Integer(4));
            System.out.println(list);

            List list = new ArrayList();
            list.add(1);
            list.add(2);
            list.add(4);
            list.add(11);
            list.add(10);
            // 对list进行升序排序
            Collections.sort(list);
            System.out.println(list);

        2.LinkedList

    为null:没有这个对象,个数为零
    为0:有这个对象
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值