黑马程序员---Java 容器集合

-----------android培训java培训、java学习型技术博客、期待与您交流!------------

集合:

1.map

映射表的基本思想是它维护的是键-值(对)关联,因此程序员可以用键来查找值。标准的java类库中包含了map的集中基本实现,包括:hashmap,treemap,linkedhashmap,weakhashmap,concurrenthashmap,identityhashmap。他们都有相同的基本接口map,但是行为特性各不相同,这表现在效率、键值对的保存及呈现次序、对象的保存周期、映射表如何在多线程程序中工作和判定“键”等价的策略等方面。Map接口实现的数量应该可以让程序员感觉到这种工具的重要性。

 Map适配器现在可以使用各种不同的Generator、Iterator和常量值的组合来填充map初始化对象。

2.Arrays

因为Arrays.asList()会生成一个List,它基于一个固定大小的数组,仅支持那些不会改变数组大小的操作,对他而言是有道理的。任何会引起对底层数据结构的尺寸进行修改的方法都会产生一个UnsupportedOperationException异常,以表示对未获得支持操作的调用。

值得提醒的是,应该把Arrays.asList()的结果作为构造器的参数传递给任意Collection,这样可以生成允许使用所有方法的普通容器。Collections类中的“不可修改”的方法将容器包装到一个代理中,只要你执行任何试图修改容器的操作,这个代理都会产生UnsupportedOperationException异常。使用这些方法的目标就产生“常量”容器对象,

3.List

基本的List很容易使用:大多数情况下只是调用add()添加对象,使用get()一次取出一个元素,以及调用iterator(0获取用于该序列的Iterator。

4.set和存储顺序

当程序员创建自己的类型时,要意识到set需要一种方式来维护存储顺序,而存储顺序如何维护,则是在set的不同实现之间会有所变化,因此不同的set实现不仅具有不同的行为,而且他们对于可以在特定的set中放置的元素的类型也有不同的要求:

(1)set(interface):存入set的每个元素都必须是唯一的,因为set不保存重复元素。加入set的元素必须定义equals()方法以确保对象的唯一性。Set与collection有完全一样的接口。Set接口不保证维护元素的次序。

(2)hashset:为快速查找而设计的set,存入hashset的元素必须定义hashcode()。

(3)treeset:基于treemap,保持次序的set,底层为树结构,使用它可以从set中提取有序的序列,元素必须实现Comparable接口。

(4)linkedhashset:具有hashset的查询速度,且内部使用链表维护元素的顺序,也就是插入的次序,于是在使用迭代器遍历set时,结果会按元素插入的次序显示。元素也必须定义hashcode方法。

程序员必须为三列存储和树形存储都创建一个equals()方法,但是hashCode()只有在这个类将会被置于hashset或者linkedhashset中时才是必须的。但是,对于良好的编程风格而言,应该在覆盖equals()方法时,同时覆盖hashcode()方法。

5.SortedSet

SortedSet中的元素可以保证处于排序状态,这使得他可以通过SortedSet的接口中的下列方法提供附加功能:Comparator comparator()返回当前set使用的comparator;或者返回null,表示已自然方式排序。

(1)Object first():返回容器中的第一个元素。

(2)object last():返回容器中的最后一个元素。

(3)SortedSet subset(fromElement,toElement):生成此set的子集,范围从fromElement(包含)到toElement(不包含)。

(4)SortedSet headset(toElement):生成此set的子集,由小于toElement的元素组成。

(5)SortedSettailSet(fromElement):生成此set的子集,由大于或等于fromElement的元素组成。

6.Queue

除了并发应用,queue在java中还有的两个实现是linkedlist和priorityqueue,他们的差异在于排序行为而不是性能。程序员可以将元素从队列的一段插入,并与另一端将他们去除:

案例:

public class QueueBehaver {

     /**

      * @param args

      */

     private static int count = 10;

     static <T> void test(Queue<T>queue,Generator<T>gen){

           for(int i=0;i<count;i++){

                queue.offer(gen.next());            

           }

           while(queue.peek() !=null){

                System.out.println(queue.remove()+"   ");

           }

           System.out.println();

     }

    

     static class Gen implements Generator<String>{

           String[]s = ("one two threefour five six seven"+"eight nine ten").split("");

           int i;

           public String next(){

                return s[i++];

           }

     }

    

     public static void main(String[] args){

           test(newLinkedList<String>(),new Gen());

           test(newPriorityQueue<String>(),new Gen());

           test(newArrayBlockingQueue<String>(count),new Gen());

           test(newConcurrentLinkedQueue<String>(),new Gen());

           test(newLinkedBlockingQueue<String>(),new Gen());

           test(newPriorityBlockingQueue<String>(),new Gen());

 

     }

 

}

 

选择接口的不同实现:

现在已经知道了,尽管实际上只有四种容器:map,list,set和queue,但是每个接口都有不止一种的实现版本,如果需要使用某种接口的功能,应该如火如何选择使用哪一个实现呢?

每种不同的实现各自的特征、优点和缺点。例如:hashtable、vector和stack的特征是,它们是过去遗留下来了的类,目前只是为了支持老的程序。

容器之间的区别通常鬼节为有什么在背后“支持”它们。也就是说,所使用的接口是由什么样的数据结构实现的。例如,因为ArrayList和LinkedList都实现了list接口,所以无论选择哪一个,基本的list的操作都是相同的。然而,arraylist底层由数组支持,而linkedList是由双向链表实现的,其中的每个对象包含数据的同事还包含指向链表中前一个与后一个元素的引用。因此如果要经常插入或删除元素,linkedlist就比较合适,否则就应该使用速度更快的arraylist。

再举个例子,set可被实现为treeset、hashset或linkedhashset,每一种都有不同的行为:hashset是最常用的,查询速度快;linkedhashset保持元素插入的次序;treeset基于treemap,生成一个总是处于排序状态的set,程序员可以根据所需的行为来选择不同的接口。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值