Java进阶之Collection、泛型要点讲解

前言:

这一章先不讲各个集合底层的一些原理,先将Collection这个对象存在哪些方法都尝试一遍。

Collection

    public static void main(String[] args) {
        Collection<Integer> collection = new ArrayList<>(16);
        collection.add(1);
        Collections.addAll(collection, 2,3,4,5,6);
        // 函数式编程的遍历,后面会说到函数式编程
        collection.forEach((a)->System.out.print(a));// 123456 
        collection.remove(2);// 删除元素
        System.out.println(collection.contains(2));// false 是否包含2这个元素
        System.out.println(collection.isEmpty());// false 是否为空
        System.out.println(collection.size());// 5 元素的数量
        // 返回一个数组,没有在括号中传入指定的类型,返回的是Object类型的数组
        System.out.println(collection.toArray());// [Ljava.lang.Object;@20c684
        System.out.println();
        // 迭代器遍历,增强for循环的内部也是个iterator迭代器
        Iterator<Integer> it = collection.iterator();
        while (it.hasNext()) {
            System.out.print(it.next());// 13456
        }
    }

这个里面别的没什么好说的,主要就是在用迭代器遍历元素时,不能用集合删除一个元素,还是使用上面的集合。

        while (it.hasNext()) {
            if (it.next()== 4) {
               // collection.remove(4); // ConcurrentModificationException
               it.remove();
            } 
        }

应该使用迭代器的remove方法,为什么会报错呢?我debug了一下,主要就是modCount != expectedModCount实际修改的计数器和预期修改的计数器不相等(每修改一次,计数器就会加一),至于为什么计算器不相等呢?小伙伴们可以去网上在搜一搜,我看了半天也没发现哪里悄悄更改了二者的值,反正一开始是相等的,奈何本人初学能力有限见谅,源码在这里

private class Itr implements Iterator<E> {
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;

        public boolean hasNext() {
            return cursor != size;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }

        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }
        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

泛型

定义:可以在类或方法中预支地使用未知的类型。
好处:

  1. 将运行期间的异常提升到了编译期间,这个很好理解,我定义一个集合,然后不指定其泛型,也就是说什么引用类型都可以往里面放(其实他们都被提升为了Object类型),然后取出来的时候进行类型转换(假设都转为String),就会发现类型转换异常,如果你只是要打印输出一下,那不转也没事,我的意思是如果你想将这些元素遍历然后由于某一需要,进行类型转换时,你不可能保证所有的都能正常转为String,那时候就报错,而泛型由于在编程时就将该集合的类型早早确定下来了,后续你不可能往里面加的了不是String的数据的,会编译报错的。
  2. 避免了类型强转的麻烦。一开始都定义好了类型,还要什么后续强转呢。
  3. 如果不指定集合以什么类型存储元素,则默认都以Object类型存储,这就带来了一个严重的问题,用Object元素来表示元素类型没有问题,但每次进行一些操作都要拆箱、装箱占用了大量的计算机资源,导致程序性能低下。而使用泛型则在编译阶段就告诉编译器,数据结构中元素的种类,既然编译器知道元素的种类,自然就避免了重复的拆箱、装箱的操作,从而显著提高程序的性能

泛型通配符

当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素的自身方法无法使用。

通配符高级使用----泛型受限

Collection<Integer> list1 = new ArrayList<>();
Collection<String> list2 = new ArrayList<>();
Collection<Number> list3 = new ArrayList<>();
Collection<Object> list4 = new ArrayList<>();

getElement(Collection<? extends Number> coll){}// 这是上限
getElement2(Collection<? super Number> coll){}// 这是下限

getElement(list1);// 编译正确
getElement(list3);// 编译正确
getElement(list2);// 编译错误
getElement(list4);// 编译错误

getElement2(list3);// 编译正确
getElement2(list4);// 编译正确
getElement2(list1);// 编译错误
getElement2(list2);// 编译错误

所谓上限是指括号中接收的类的类型最多是Number类型或者Number子类
所谓下限是指括号中接收的类的类型至少是Number类型或者Number父类

这个估计用的也不多,了解了解就可以了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值