`
fuquan
  • 浏览: 27172 次
文章分类
社区版块
存档分类
最新评论

四.Java 集合

 
阅读更多

4.1 声明为接口类

List list=new ArrayList();

4.2 fast-fail机制

	for (Iterator<Integer> iter = list.iterator(); iter.hasNext();)
	{
		 int i = iter.next();
		 if (i == 3)
		 {
		     list.remove(i);
		 }
	}
如果一边循环List,一边更改list中的数据,就会报错:
java.util.ConcurrentModificationException
API中此异常的解释:当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。
以HashMap为例:
 	 final Entry<K,V> nextEntry() {
   	if (modCount != expectedModCount)
   		throw new ConcurrentModificationException();
   //...

modCount为修改次数,每次更改HashMap(put,remove等等)会使modCount发生改变,
而迭代的时候会检查modCount和expectedModCount是否相等,不相等就抛出ConcurrentModificationException异常。
这也是java Iterator的fast-fail机制。源码中有注释:
int expectedModCount; // For fast-fail

解决方法:
(1)倒过来遍历list
(2)用iterator.remove()方法
(3)每移除一个元素以后再把i移回来




4.3 ArrayList和LinkedList的速度



随机读取:
		List<String> list = new ArrayList<String>();
		for(int i=0;i<1000;i++)
		{
			list.add("ArrayList");
		}
		long start=System.nanoTime();
		String s1=list.get(99);
		long end=System.nanoTime();
		System.out.println("ArrayList 耗时: "+(end-start));

ArrayList 耗时: 4141
LinkedList 耗时: 11150


可以看出来随机读取,ArrayList要快于LinkedList,
通过源码可以看出来:
ArrayList.java
private transient Object[] elementData;
LinkedList.java
transient Node<E> first;
transient Node<E> last;
ArrayList采用数组结构,而LinkedList采用链表数据结构。所以ArrayList要快些。


LinkedList在API中有一句解释:在列表中编索引的操作将从开头或结尾遍历列表(从靠近指定索引的一端)。
所以list.get(p),p越靠近中间,需要的时间越久。
测试:
list.size()=1000 p=7   LinkedList 耗时: 8283
list.size()=1000 p=500 LinkedList 耗时: 18795
list.size()=1000 p=987 LinkedList 耗时: 8601


4.4 ArrayList的实现原理



创建ArrayList:
List<String> list = new ArrayList<String>();
当new 一个ArrayList时,最后会调用这段代码:
	public ArrayList() {
        this(10);
    }
    
		public ArrayList(int initialCapacity) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
    }


可以看到,ArrayList底层使用数组实现,java会默认创建一个长度为10的数组,


添加一个元素:
先计算容量(Capacity)是否合适,在把元素添加到数组末尾,add操作会使modCount增加,源码中也有注释。
  public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

在ensureCapacityInternal()中:
  if (minCapacity - elementData.length > 0)
    grow(minCapacity);


因为底层用的数组实现,所以add时候如果数组容量不够,就去调用grow()给数组扩容,
调整数组容量,具体实现是将老数组按照新的大小copy到新的数组。
elementData = Arrays.copyOf(elementData, newCapacity);
新的大小是按照原来数组大小的1.5倍(不超过最大容量MAX_ARRAY_SIZE):
int newCapacity = oldCapacity + (oldCapacity >> 1);
如果有必要也可以指定ArrayList的实际容量,最后也是通过ensureCapacityInternal()来实现。


删除一个元素:
remove(int index) 最后使元素=null
elementData[--size] = null
remove(Object o)则是通过遍历来确定元素的index,然后用fastRemove(int index)来删除,
所以remove(int index)效率要高于remove(Object o)


4.5 其他集合的实现原理



以HashSet为例:
public HashSet() {
map = new HashMap<>();
}
底层实际上还是一个HashMap。也就是说,其实HashSet底层是采用HashMap实现的。
而HashMap底层又是采用数组实现:
transient Entry<K,V>[] table;
!变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
多看看JDK的源码,也就了解了。
分享到:
评论

相关推荐

    5.java集合概述.zip

    5.java集合概述.zip5.java集合概述.zip5.java集合概述.zip5.java集合概述.zip5.java集合概述.zip5.java集合概述.zip5.java集合概述.zip5.java集合概述.zip5.java集合概述.zip5.java集合概述.zip5.java集合概述.zip5....

    6.java集合框架.zip

    6.java集合框架.zip6.java集合框架.zip6.java集合框架.zip6.java集合框架.zip6.java集合框架.zip6.java集合框架.zip6.java集合框架.zip6.java集合框架.zip6.java集合框架.zip6.java集合框架.zip6.java集合框架.zip6....

    14.java集合转换(了解).zip

    14.java集合转换(了解).zip14.java集合转换(了解).zip14.java集合转换(了解).zip14.java集合转换(了解).zip14.java集合转换(了解).zip14.java集合转换(了解).zip14.java集合转换(了解).zip14.java集合...

    15.java集合工具类(了解)后期扩展.zip

    15.java集合工具类(了解)后期扩展.zip15.java集合工具类(了解)后期扩展.zip15.java集合工具类(了解)后期扩展.zip15.java集合工具类(了解)后期扩展.zip15.java集合工具类(了解)后期扩展.zip15.java集合工具...

    Java集合面试题汇总.pdf

    Java集合面试题汇总.pdfJava集合面试题汇总.pdfJava集合面试题汇总.pdfJava集合面试题汇总.pdfJava集合面试题汇总.pdfJava集合面试题汇总.pdfJava集合面试题汇总.pdfJava集合面试题汇总.pdfJava集合面试题汇总.pdf...

    第03章.java集合框架.ppt

    第03章.java集合框架.ppt

    2.Java集合与数据结构.rar

    2.Java集合与数据结构.rar

    Java集合面试题.docx

    Java 集合框架是什么?说出一些集合框架的优点? 2. 集合框架中的泛型有什么优点? 3. Java 集合框架的基础接口有哪些? 4. 为何 Collection 不从 Cloneable 和 Serializable 接口继承? 5. 为何 Map 接口不...

    2.java高级集合部分.doc

    2.java高级集合部分.doc

    Java集合 练习代码

    Java 集合 集合.rar 集合.rar 集合.rar 集合.rar 集合.rar

    Java集合排序及java集合类详解.pdf

    Java 集合排序 及java集合类 详解.pdf

    Java基础篇:Java集合.pdf

    该文档主要详细总结了Java集合的相关知识,包括Collection和Map接口、Collection接口的子接口List和Set接口以及具体的实现类、存储原理等;Map接口的子接口HashMap、LinkedHashMap、TreeMap、Properties等

    Java集合容器面试题(2024最新版)-重点.docx

    Java集合容器面试题(2024最新版)-重点.docxJava集合容器面试题(2024最新版)-重点.docxJava集合容器面试题(2024最新版)-重点.docxJava集合容器面试题(2024最新版)-重点.docxJava集合容器面试题(2024最新版)...

    2.Java集合-Collection1

    对于例子:对于执行的remove操作,会调用A的equals方法一次与集合元素进行比较,如果该equals()方法以某个集合元素作为参数是返回true,list

    Java开发技术大全(500个源代码).

    HelloWorldApp.java 第一个用Java开发的应用程序。 firstApplet.java 第一个用Java开发的Applet小程序。 firstApplet.htm 用来装载Applet的网页文件 第2章 示例描述:本章介绍开发Java的基础语法知识。 ...

    Java集合框架.ppt

    集合是将多个元素组成一个单元的...Java集合框架,为我们提供了一套性能优良、使用方便的接口和类,我们不必再重新发明轮子,只需学会如何使用它们,就可以处理实际应用中出现的问题了Java集合框架位于java.util包中

    3.java集合面试题1

    2. 底层数据结构Arraylist 底层使用的是Object数组 3. 插入和删除是否受元素位置的影响 ① ArrayList 采用数组存储,所以插入和删除元

    java集合思维导图

    java集合 java集合思维导图 java集合总结

    集合操作工具类 LeyiUtils.java

    集合操作工具类 LeyiUtils.java

Global site tag (gtag.js) - Google Analytics