Java基础-集合框架简要概述


集合简单介绍

集合的由来

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

数组和集合的区别

区别一:

数组既可以存储基本数据类型,又可以存储引用数据类型,基本数据类型存储的是值,引用数据类型存储的是地址值

集合只能存储引用数据类型(对象)集合中也可以存储基本数据类型,但是在存储的时候会自动装箱变成对象

区别二:

数组长度是固定的,不能自动增长

集合的长度的是可变的,可以根据元素的增加而增长

数组和集合什么时候用

如果元素个数是固定的推荐用数组

如果元素个数不是固定的推荐用集合

集合继承简单体系图

迭代器

概述

集合是用来存储元素,存储的元素需要查看,那么就需要迭代(遍历)

迭代器的使用

		Collection<String> collection = new ArrayList<>();
		collection.add("a");
		collection.add("b");
		collection.add("c");
		collection.add("d");
		Iterator<String> iterator = collection.iterator();
		while(iterator.hasNext()) {
			System.out.println(iterator.next());
		}

由上面的代码可知,Iterator为迭代器类,而查看API可得知,集合类中并没有实现Iterator这个接口,却实现了Iterable接口

迭代器原理:

迭代器是对集合进行遍历,而每一个集合内部的存储结构都是不同的,所以每一个集合存和取都是不一样,那么就需要在每一个类中定义hasNext()和next()方法,这样做是可以的,但是会让整个集合体系过于臃肿,迭代器是将这样的方法向上抽取出接口,然后在每个类的内部,定义自己迭代方式,这样做的好处有二,第一规定了整个集合体系的遍历方式都是hasNext()和next()方法,第二,代码有底层内部实现,使用者不用管怎么实现的,会用即可

那Iterator和Iterable有些什么区别?

1.Iterator是迭代器类,而Iterable是为了只要实现该接口就可以使用foreach,进行迭代.

2.Iterable中封装了Iterator接口,只要实现了Iterable接口的类,就可以使用Iterator迭代器了。

那为什么这些集合类不直接实现Iterator呢?

因为Iterator接口的核心方法next()或者hasNext() 是依赖于迭代器的当前迭代位置的。

如果Collection直接实现Iterator接口,势必导致集合对象中包含当前迭代位置的数据(指针)。

当集合在不同方法间被传递时,由于当前迭代位置不可预置,那么next()方法的结果会变成不可预知。

除非再为Iterator接口添加一个reset()方法,用来重置当前迭代位置。

但即时这样,Collection也只能同时存在一个当前迭代位置。

而Iterable则不然,每次调用都会返回一个从头开始计数的迭代器。

多个迭代器是互不干扰的。                               此段文字转载至:http://liuyun025.iteye.com/blog/1321045

ArrayList迭代器简单源码分析(JDK1.8)

	public Iterator<E> iterator() {
        return new Itr();
    }
    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();
            }
        }
    }

并发修改异常

上面提到了并发修改异常,什么是并发修改异常呢?

	public static void main(String[] args) {
		List<String> list = new ArrayList<>();
		list.add("a");
		list.add("b");
		list.add("c");
		list.add("d");
		Iterator<String> iterator = list.iterator();
		while(iterator.hasNext()) {
			System.out.println(iterator.next());
			list.add("e");
		}
	}

异常信息

a
Exception in thread "main" java.util.ConcurrentModificationException
....

某个线程在 Collection 上进行迭代时,通常不允许另一个线性修改该 Collection。通常在这些情况下,迭代的结果是不确定的。如果检测到这种行为,一些迭代器实现(包括 JRE 提供的所有通用 collection 实现)可能选择抛出此异常。执行该操作的迭代器称为快速失败迭代器,因为迭代器很快就完全失败,而不会冒着在将来某个时间任意发生不确定行为的风险。


解决方案

1.迭代器迭代元素,迭代器修改元素(ListIterator的特有功能add)

2.集合遍历元素,集合修改元素( toArray() )

下面就演示下第一种解决方案

	public static void main(String[] args) {
		List<String> list = new ArrayList<>();
		list.add("a");
		list.add("b");
		list.add("c");
		list.add("d");
		ListIterator<String> iterator = list.listIterator();
		while(iterator.hasNext()) {
			String str = iterator.next();
			if(str.equals("c")) {
				iterator.add("e");
			}
		}
		System.out.println(list);
	}

正常输出

[a, b, c, e, d]


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值