一路拾遗
Collect By Finding All The Way ......
posts - 81,comments - 41,trackbacks - 0

    自java1.2之后java版本统称为java2,java2中的容器类库才可以说是一种真正意义上的集合框架的实现。基本完全重新设计,但是又对java1中的一些容器类库在新的设计上进行了保留,这主要是为了向下兼容的目的,当用java2开发程序时,应尽量避免使用它们,java2的集合框架已经完全可以满足你的需求。有一点需要提醒的是,在java1中容器类库是同步化的,而java2中的容器类库都是非同步化,这可能是对执行效率进行考虑的结果。
java2中的集合框架提供了一套设计优良的接口和类,使程序员操作成批的数据或对象元素极为方便。这些接口和类有很多对抽象数据类型操作的api,而这是我们常用的且在数据结构中熟知的。例如maps,sets,lists,arrays等。并且java用面向对象的设计对这些数据结构和算法进行了封装,这就极大的减化了程序员编程时的负担。程序员也可以以这个集合框架为基础,定义更高级别的数据抽象,比如栈、队列和线程安全的集合等,从而满足自己的需要。
java2的集合框架,抽其核心,主要有三类:list、set和map。

    其中,list和set继承了collection,而map则独成一体。初看上去可能会对map独成一体感到不解,它为什么不也继承collection呢?但是仔细想想,这种设计是合理的。一个map提供了通过key对map中存储的value进行访问,也就是说它操作的都是成对的对象元素,比如put()和get()方法,而这是一个set或list所不就具备的。当然在需要时,你可以由keyset()方法或values()方法从一个map中得到键的set集或值的collection集。
1、collection接口提供了一组操作成批对象的方法,用uml表示的方法列表如下:
它提供了基本操作如添加、删除。它也支持查询操作如是否为空isempty()方法等。为了支持对collection进行独立操作,java的集合框架给出了一个iterator,它使得你可以泛型操作一个collection,而不需知道这个collection的具体实现类型是什么。它的功能与java1中的enumeration类似,只是更易掌握和使用,功能也更强大。在建立集合框架时,SUN的开发团队考虑到需要提供一些灵活的接口,用来操作成批的元素,又为了设计的简便,就把那些对集合进行可选操作的方法与基本方法放到了一起。因为一个接口的实现者必须提供对接口中定义的所有方法的实现,这就需要一种途径让调用者知道它正在调用 的可选方法当前不支持。最后开发团队选择使用一种信号,也即抛出一种不支持操作例外(unsupportedoperationexception),如果你在使用一个collection中遇到一个上述的例外,那就意味着你的操作失败,比如你对一个只读collection添加一个元素时,你就会得到一个不支持操作例外。在你实现一个集合接口时,你可以很容易的在你不想让用户使用的方法中抛出unsupportoperationexception来告诉使用者这个方法当前没有实现,unsupportoperationexception是runtimeexception的一个扩展。
另外java2的容器类库还有一种fail fast的机制。比如你正在用一个iterator遍历一个容器中的对象,这时另外一个线程或进程对那个容器进行了修改,那么再用next()方法时可能会有灾难性的后果,而这是你不愿看到的,这时就会引发一个concurrentmodificationexception例外。这就是fail-fast。
2、list接口对collection进行了简单的扩充,它的具体实现类常用的有arraylist和linkedlist。你可以将任何东西放到一个list容器中,并在需要时从中取出。arraylist从其命名中可以看出它是一种类似数组的形式进行存储,因此它的随机访问速度极快,而linkedlist的内部实现是链表,它适合于在链表中间需要频繁进行插入和删除操作。在具体应用时可以根据需要自由选择。前面说的iterator只能对容器进行向前遍历,而listiterator则继承了iterator的思想,并提供了对list进行双向遍历的方法。
3、set接口也是collection的一种扩展,而与list不同的时,在set中的对象元素不能重复,也就是说你不能把同样的东西两次放入同一个set容器中。它的常用具体实现有hashset和treeset类。hashset能快速定位一个元素,但是你放到hashset中的对象需要实现hashcode()方法,它使用了前面说过的哈希码的算法。而treeset则将放入其中的元素按序存放,这就要求你放入其中的对象是可排序的,这就用到了集合框架提供的另外两个实用类comparable和comparator。一个类是可排序的,它就应该实现comparable接口。有时多个类具有相同的排序算法,那就不需要在每分别重复定义相同的排序算法,只要实现comparator接口即可。
集合框架中还有两个很实用的公用类:collections和arrays。collections提供了对一个collection容器进行诸如排序、复制、查找和填充等一些非常有用的方法,arrays则是对一个数组进行类似的操作。
4、map是一种把键对象和值对象进行关联的容器,而一个值对象又可以是一个map,依次类推,这样就可形成一个多级映射。对于键对象来说,像set一样,一个map容器中的键对象不允许重复,这是为了保持查找结果的一致性;如果有两个键对象一样,那你想得到那个键对象所对应的值对象时就有问题了,可能你得到的并不是你想的那个值对象,结果会造成混乱,所以键的唯一性很重要,也是符合集合的性质的。当然在使用过程中,某个键所对应的值对象可能会发生变化,这时会按照最后一次修改的值对象与键对应。对于值对象则没有唯一性的要求。你可以将任意多个键都映射到一个值对象上,这不会发生任何问题(不过对你的使用却可能会造成不便,你不知道你得到的到底是那一个键所对应的值对象)。map有两种比较常用的实现:hashmap和treemap。hashmap也用到了哈希码的算法,以便快速查找一个键,treemap则是对键按序存放,因此它便有一些扩展的方法,比如firstkey(),lastkey()等,你还可以从treemap中指定一个范围以取得其子map。键和值的关联很简单,用pub(object key,object value)方法即可将一个键与一个值对象相关联。用get(object key)可得到与此key对象所对应的值对象。
本文来自学习网(www.gzu521.com),原文地址:http://www.gzu521.com/campus/article/program/200602/14354.htm

posted on 2009-11-16 19:05 胖胖泡泡 阅读(101) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: