Java容器详解

具体的容器实现都是继承了一个Abstract虚拟类,通过实现这个类中的方法来完成的。这个Abstract类中有部分方法如equalshashCode等在Abstract类中已经有了实现实现,我们在继承的时候可以覆写,但是还有一部分重要的方法如setget(标注为可选操作)方法在Abstract类中没有具体的实现方法,需要我们在子类中覆写(如果我们没在子类中覆写这些可选操作的时候又调用了这些方法,那么会出现UnsupportedOperationException异常)。如果我们想自定义容器类,可以继承Abstract虚拟类并扩展或者重新实现这个类的方法从而达到自定义的目的。

Collection实现了Iterable接口,这个接口有个iterator方法,这个方法会在AbstractList类中具体实现,其实现的过程是返回一个名为str的内部类对象,而这个类有hasNext,next,remove,checkForComodification这4个方法,

所以返回的Iterator类具有这几个方法。

hasNext()  如果仍有元素可以迭代,则返回 true。

next()   返回迭代的下一个元素。

remove() 从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。

再介绍一下foreach和Iterator:我们通常将foreach用于数组的遍历,其实foreach可以用于任何Collection对象。Foreach在java中使用Iterator来移动序列,所以只要你创建的类实现了Iterable接口,都可以用foreach来遍历。

import java.util.*; 
public class Test{	 		
	public static void main(String[] args){
		List<Integer> l=new ArrayList<Integer>();//需要泛型,不然会参数告警信息或者使用@SuppressWarnings抑制告警信息的产生
		List<Integer> l1=new LinkedList<Integer>();
		l.add(3);
		l1.add(1);
		Iterator I=l.iterator();
		Iterator I1=l1.iterator();
		while(I.hasNext()){
			System.out.println(I.next());
		}
		while(I1.hasNext()){
			System.out.println(I1.next());
		}
	}
}

注意,在Iterator有一个子类ListIterator子类专门用于List的遍历,并且可以双向移动。


Collection子类介绍:

List:

ArrayList内部存储数据使用的是数组,当使用add方法的时候,需要新建一个数据并把原来的数据和新添加的数据都复制到这个新的数组里面,ArrayList在随机搜索的程序中比LinkedList的效率高。

LinkedList内部是使用我们常见的链表的数据结构的方式存储的,并且是个双向链表。在添加和删除元素的时候其效率比ArrayList高,LinkedList的另一个重要的功能:因为使用双向链表来实现,所以LinkedList可以用来构造栈stack,队列Queue,或者双向队列。

Vector类部的储存结构也是数组,不过VectorArrayListLinkedList有个显著的区别,那就是Vector里面的方法都是使用了synchronized修饰的,所以Vector类的方法都是同步的。

Java.util.Stack类是继承Vector类来实现的,因此其本质和LinkedList一样

Set:

hashSet使用的是HashMap来实现的。(散列存储)为快速查找而设计的HashSet

TreeSet使用的是TreeMap来实现的。(树形存储)有序的TreeSet

LinkedHashSet继承了HashSet,所以它也是HashMap来实现的。(散列存储)即有序又可以快速查找

 

(良好的编程习惯,你应该在覆盖equals方法的同时总是覆盖hashCode方法)

Map:

hashMap使用散列码来取代一般map中对于键值的缓慢搜索。由于hashCode是根类Object的方法,所以任何对象都有hashCode方法,都可以参数散列码。散列码是相对唯一的并且是通过hashCode的值计算出来的,并不是直接使用hashCode

hashMap使用的是数组来进行存储的,其数组的下标是通过散列码和HashMap长度运算得到的一个int类型的整数,数组的内容一般情况是一个List,可能存储的有多个值。我们查询的时候,首先根据数组下标查询到这个ListEntry对象?),然后再去List里面进行查找。(类似于一个不连续的数组?)


关于collection或者map设置为不可修改和同步控制。

List<String> list = Collections.unmodifiableList( new ArrayList<String>());

List<String> list = Collections.synchronizedCollection(new ArrayList<String>());

容器的快速报错机制;当多个线程同时修改同一个容器的内容的时候,就会抛出ConcurrentModificationException异常。

下面就是一个例子,至于为什么会抛出ConcurrentModificationException异常,可以参考:http://blog.csdn.net/akon405/article/details/22991847

import java.util.*; 
public class Test{	 		
	public static void main(String[] args){
		Collection<String> c=new ArrayList<String>();
		Iterator i=c.iterator();
		c.add("hello");
		try{
		String s=i.next();
		}catch(ConcurrentModificationException e){
			System.out.println(e);
		}
	}
}




 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值