集合Collection

1. 集合    Collection  单列集合


    集合就是一种容器,不同的容器有不同特点;
    特点:
        1. 集合长度可变   【扩容机制】
        2. 集合只能存引用数据类型

    - Collection   没有带索引的方法
        - List  1.有序(存取有序)2.有索引3.可重复
            - ArrayList    数组(jdk1.2产物)
            - LinkedList   链表
            - Vector       数组(jdk1.0已被ArrayList取代)
        - Set    1.无序(存取无序)2.无索引3.不可重复
            - HashSet  哈希表(数组+链表+红黑树)   特点:去重
                - LinkedHashSet
            - TreeSet  红黑树   特点:查询快,排序

    常用方法:
        Collection<E>
        boolean add(E e);      向集合中添加元素
        void clear();          清空集合元素
        boolean contains(E e);  判断是否包含指定元素
        boolean isEmpty();     判断集合是否为空
        boolean remove(E e);   判断是否删除指定元素
        Object[] toArray();    将集合转成数组   Object[] arr = {1,true,"abc"};
        T[] toArray(T[] arr);  将集合转为指定类型的数组
            Student[] arr = c.toArray(new Student[0]);  
            //参数数组的长度:如果长度大于集合的元素个数,那么集合填充数组前面的位置
            //如果数组长度小于集合个数,那么数组长度为集合的长度

2. 迭代器


    iterator
    就是一种遍历的方式;
    每个不同的集合,都有它自己的内部迭代器;

    创建迭代器对象:
        Iterator<E> it = list.iterator();

    常用方法:
        boolean hasNext();    判断是否有下一个元素
        E next();             取出元素
        void remove();        删除元素

    注意事项:
        1. 不能在使用迭代器遍历集合的同时,去通过集合对象,操作集合的元素个数;(并发修改异常)  modCount++;
        2. 只能通过迭代器自己的方法去删除或者增加元素;iterator.remove()   listIterator.add()/remove()
        3. 在使用迭代器拿元素的时候,it.next()只需要调用一次即可,不能调用两次;

        
    NoSuchElementsException:找不到元素异常
    ConcurrentModificationException:并发修改异常
        产生的原因:
            在使用迭代器遍历集合的同时,操作原集合的个数;
        解决方案:
            别这么干!
            使用迭代器自己的方法,对集合进行操作;
                如果是删除元素,可以使用Iterator自己的remove()方法;
                如果是添加元素,可以使用ListIterator自己的remove()方法;

3. 增强for


    foreach就是一个使用了迭代器的普通for循环,但是我们还看不到迭代器;
    增强for循环,只能遍历集合,不能做其它任何操作;

    格式:
        for(容器的数据类型  变量  :  容器(集合/数组)){
            变量; //就是集合或数组中的每一个元素
        }

注意事项:

// 遍历思路1  将集合转换成数组  遍历数组  【如果需求是将元素转换成大写】
Object[] objects = coll.toArray();//得到的是Object对象  其没有toUpperCase方法
for (Object object : objects) {
    String string = (String) object;  
    System.out.println(string.toUpperCase());
}
// 改进方案
// new String[0]这个时候会自动给你分配有个coll.size 大小的数组
//或者new String[coll.size()]

String[] strings = coll.toArray(new String[0]);
for (int i = 0; i < strings.length; i++) {
    System.out.println(strings[i].toUpperCase());
}

4. 泛型
    就是一种容器上的【标签】;
    只在编译期有效;

    好点:
        1. 把运行时期的异常,提前到了编译期;
        2. 避免的类型的强转;

    自定义泛型:
        类:
            class A<W>{
                public void show(W s){
                System.out.println(s);
                }
            }
            使用:创建对象的时候,确定类的泛型
                A<String> a = new A<>();
                a.show("123");

            class A<S,W>{
                public void show(S s){
                System.out.println(s);
                }
                
                public void add(W w){
                
                }
            }
            使用:
                A<String,Integer> a = new A<>();
                a.show("123");

        接口:
            interface Inter<A>{
                void show(A a);

                A getSomething();
            }
            // 实现类确定接口泛型
            class InterImpl implements Inter<String>{
                @Override
                    public void show(String s) {

                    }

                    @Override
                    public String getSomething() {
                    return null;
                    }
            }
            // 实现类也不确定接口泛型,所以实现类和接口泛型保持一致
            // 在创建实现类对象时,确定泛型
            class InterImpl<E> implements Inter<E>{
                @Override
                    public void show(E s) {

                    }

                    @Override
                    public E getSomething() {
                    return null;
                    }
            }        InterImpl<String> s = new InterImpl<>();
            // 类有类的泛型,接口的泛型依旧不确定,所以类只能定义两个泛型
            class InterImpl<E,W> implements Inter<E>{
                @Override
                    public void show(E s) {

                    }

                    @Override
                    public E getSomething() {
                    return null;
                    }

                public void method(W w){
                
                }
            }
            InterImpl<String,Integer> i = new InterImpl<>();    

        方法:
            public static <T> T method(){
                T t = new T();
                return t;
                
            }
            使用:在调用方法的时候,确定方法泛型的类型

    泛型通配符:【了解】
        通配符通常使用在方法的参数位置;
        相当于告诉调用者,这个方法限定是什么,以及限定了什么;
        <?>
        ? : 无边界通配符,不能添加数据,也不能获取数据,只能通过增强for遍历
        ? extends C : 限定你能传入的上限类型  C  我们只能传C及其C的子类     ? extends Animal
        ? super C :   限定你能传入的下限类型  C  我们只能传C及其C的父类      ? super Animal  Object
 
        上界类型通配符:add方法受限
        下界类型通配符:get方法受限
        如果你想从一个数据结构里获取数据,使用 ? extends 通配符
        如果你想把对象写入一个数据结构里,使用 ? super 通配符
        如果你既List想存,又想取,那就别用通配符

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值