`
yaya_wiscom
  • 浏览: 48196 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

集合类复习

 
阅读更多

集合在Java中占据着举足轻重的位置,在平时的开发中,选择不同是数据结构会导致其实现风格以及性能存在很大的差异。我很喜欢Jquery的广告词:多学一点知识,就少写一行代码。有时候你费尽心机的去实现一个功能,如果选用的方法不对可能200行的代码也不见得来的比20行的代码强(有点扯远!!)。

(引用下图)


由上图可知,集合类的基本接口是:Collection接口。其中有两个最基本的方法:add方法和iterator方法。iterator()返回一个实现了Iterator接口的对象。可以使用这个对象依次访问集合中的元素。

遍历集合的常用方法:


//方式一 直接用迭代器遍历
Collection<Student> col = new LinkedList<Student>();
Iterator<Student> iter = col.iterator();
while(iter.hasNext()){
	String xh = iter.next().getXh();
	if("31083022".equals(xh)){
		throw new Exception("不能输出30183022学生的信息!");
	}
	//System.out.println(xh);
}
//方式二 用for循环
for(Student stu : col){
      System.out.println("学生信息:"+stu.toString());
}

 大部分人习惯用ArrayList,支持动态的增长和缩减的索引序列。如果需要从数组中间位置删除一个元素或是中间位置插入一个元素,则要付出很大的代价,其原因就是数组中处于被删除元素之后的所有元素都要向数组前端或后端移动。

链表的使用就不在这里记录了,这里需要说一下java.util.Iterator接口和ListIterator接口的区别:

1) Iterator又称迭代器,在使用List或是Set的时候我们进行使用迭代器取出集合中的数据,我们不需要干涉遍历的过程,只需要对取出的数据进行处理就行。

ListIterator有add()方法,可以向List中添加对象;Iterator不可以add;

2) ListIterator有hasNext()、next()方法以及hasPrevious()、previous()方法实现顺序遍历和逆向遍历;而Iterator只支持顺序遍历。

3) ListIterator可以定位当前索引的位置,通过nextIndex()、previousIndex()方法实现;而Iterator不支持此功能。

4) 都可以删除对象remove()方法。ListIterator可以实现修改对象。set()方法可以实现,

Iterator只能遍历,不能修改。

注意:set()方法API上面写的很清楚,用新元素取代next或previous上次访问的元素。否则的话将抛出IllegalStateException。


关于Vector和ArrayList的比较这里就不记录了。区别很简单Vector类的所有方法都是同步的。但是ArrayList方法不是同步的。在不需要同步时使用ArrayList,因为Vector要在同步操作上消耗大量时间。可以写一个简单的线程类分别用ArrayList和Vector测试一下。


需要知道java.util.Collection是一个集合类的接口,它提供了对集合对象基本操作的通用接口方法;java.util.Collections是一个包装类,它包含有关集合操作的静态方法,此类不能实例化。用Collections类可以按照特定发业务语义将对象进行排序。我们常用的方法是写一个比较器实现Comparator接口。通过Collections中的以下方法实现对象的排序:


public static <T> void sort(List<T> list, Comparator<? super T> c) {
	Object[] a = list.toArray();
	Arrays.sort(a, (Comparator)c);
	ListIterator i = list.listIterator();
	for (int j=0; j<a.length; j++) {
	    i.next();
	    i.set(a[j]);
}

 

对于集合平时常用的就是HashSet和TreeSet,HashSet类实现了基于散列表的集,访问集合中的元素是无序的,且不能添加重复的元素。TreeSet比HashSet有所改进,它是一个有序的集合,可以以任意的顺序将元素插入到集合中,在对集合遍历的时候每个值将自动按排序后的顺寻呈现。如果不需要对数据排序就没有必要付出排序的开销。一般情况下,使用TreeSet需要对数据进行排序,如果是整数的比较直接可以返回差值:


Set set = new java.util.TreeSet(new Comparator() {
	@Override
	public int compare(Object o1, Object o2) {
		// 结果按照降序排列
		return (Integer)o2 - (Integer)o1;
	}
			
});

 

Map接口下两个常用的实现类:HashMap、TreeMap。HashMap是基于哈希表的Map接口的非同步实现,此类允许使用null键和null值但不保证映射的顺序不变。HashMap是一种"链表散列"的数据结构,即数组和链表的结合体。可以简单是理解为HashMap底层就是一个数组结构,数组中每一项又是一个链表。

Map有三种常用的遍历方式:

方式一、entrySet


for(Map.Entry<String, String> entry:map.entrySet()){
	String key = entry.getKey();
	String value = entry.getValue();
	System.out.println("Map中的键:"+ key +"值:"+value);
}

 

方式二、keySet


Set<String> keys = map.keySet();
for(String k:keys){
	System.out.println("Map中的键:"+ k +"值:"+ map.get(k));
}

方式三、直接遍历values

 //直接遍历Map中的值
Collection values = map.values();  
Iterator iter = values.iterator();  
while(iter.hasNext()){  
     System.out.println(iter.next());  
}  

使用HashMap需要主要在多线程环境下的并发问题,都知道HashMap是非线程安全的,也就是说在多线程的环境中get()、put()、remove()等操作都是非线程安全的,在不能保证数据一致性的情况下迭代器会抛出ConcurrentModificationException异常。


一些资料显示,当需要使用同步时用Hashtable,否则用HashMap避免不必要的同步开销。HashMap和Hashtable存在一些区别:

1、Hashtable中的方法是同步的,可以不采用任何特殊的行为就可以在一个多线程的应用程序中使用Hashtable;

2、HashMap是JDK1.2引入进来的类,而Hashtable是继承于Dictionary类;

3、还有一点是HashMap如果put(null,null)之后进行get(null)是不会抛出空指针异常;而Hashtable则会抛出空指针异常。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics