关于Java容器list、set的洋洋洒洒

来源:互联网 发布:51单片机时钟电路 编辑:程序博客网 时间:2024/06/01 03:57

 

Part One

再说List , Set之前,我们首先了解一些小知识:

1 , 认识类集框架,这里所谓的框架是指一些操作的集合。是其他类或者接口需要继承并实现具体方法的操作集合。

我们叫它 :Collection  (集合之意),其特点便是被JDK开发者定义成接口(interface),无法直接实例化(可以使用匿名类实例化),需要定义其子类或接口去实现它的功能。

例如:

子类接口继承实现 :

Set publicinterface Set<E>extends Collection<E>

Listpublicinterface List<E>extends Collection<E>

2 , 稍微了解Collection之后,我们可以略懂一些数组操作类Arrays的知识。

2.1  此操作类(Arrays)包含操作数组的各种方法,详细内容请读者自行查阅官方文档,与Collection集合进行类比学习,进而达到加深印象的作用。

Part Two

读者了解以上知识后,我们可以对Collection的了解再深入一点。首先Collection作为层次结构中的根接口,这里我们姑且认为是Set和List的源头。它继承实现了Iterable接口,还有各种实现子类。

          1 ,详细具体实现子类见下图(1.1):

          2 ,由于上图全是英文,而且各种子类单词有又长,尽管语义简单易翻译,但对于英文不好和有密集恐惧症的人来说,颇显得有些许无聊没趣。

既然如此,那好,咱们就抛开上图,集中精力去专研,我们需要了解的子类就行了。这里笔者仅是起到抛砖引玉的作用,更多的知识需要读者自行去拓补。

                  2.1 AbstractCollection 实现大多数Collection接口具体实现类

                  2.2   AbstractList  扩展(2.1)类并实现大多数List接口方法

                  2.3  LinkedList 通过实现AbstractSequentialList来实现连接表

                  2.4  ArrayList 通过扩展AbstractList来实现动态数组

                  2.5  HashSet 为了使用散列表而扩展的AbstractSet

                  2.6  TreeSet 实现存储在树中的一个集合,扩展AbstractSet

                  

         3,好了。写了一大推没用的,就是为了引出Set和List。

3.1 Set :

3.1.1 不允许重复的接口(Set)。其完整的继承了Collection,并且未有对Collection进行大量的扩充。当然Set接口处理使用匿名类外,一般程序中无法正常实例化,也就是无法直接使用Set关键字创建集合。

 所以,Set接口便实现诸多子接口,其中HashSet、TreeSet尤为常见眼熟。

 顺便一提,什么是不允许重复?顾名思义装入集合的元素(对象),不可重复,一旦重复后来者便会覆盖前来者。

 大量的文字不好理解,不如咱们来点小例子咋样?

         Code1:

Set set = new HashSet();set.add(1);set.add(2);set.add(1);//获取迭代器 遍历SetIterator<Integer> it = set.iterator();while(it.hasNext()){System.out.print(it.next());}

                                                                 无序不可重复的HashSet:

3.1.2  熟悉完Set接口后,我们来学习其实现子类HashSet。由上图(1.1)也就是Collection那张具体实现类的图,可知,HashSet是为了使用散列表而扩展AbstractSet的子类。

 散列集合是无法确定其元素的排序顺序,这就是HashSet元素无序的由来了。

 如果笔者没猜错,这里的散列表(哈希表)涉及到JDK的底层实现,具体底层实现读者若有兴趣,可自行动手,丰衣足食。

 

有序且不可重复TreeSet:

3.1.3 有序:放入集合TreeSet中的元素会自行按照升序(缺省),进行排序。当然我们可以自己规定排序规则,更多的TreeSet排序规则,读者需要自行去了解业务排序接口Comparable/Comparator,这里不再做过多的叙述。

         Code2:

Set set = new TreeSet();//装入元素set.add('C');set.add('A');set.add('B');set.add('F');set.add('D');set.add('E');Iterator it = set.iterator();while(it.hasNext()){System.out.print(it.next());}

3.2  List :

3.2.1 允许重复的接口(List)。List接口对Collection进行了大量的扩充,譬如开发人员可以使用类似数组下标的方式,通过位置对元素进行访问和插入操作。

当然List仅是接口,我们重点了解的便是其具体实现子类ArrayList、LinkedList和Vector。

                                     有先后顺序且可重复的ArrayList

3.2.2 注意这里的有先后顺序,不是那种按元素大小、价格之类的自然排序。而是当我们调用add(Object)方法的时候,每次加入的对象,可以把它们想象成在地铁站排队上厕所的人,人们(对象们)不管自身属性,先加入集合者(厕所)排前面,反之排后面。

3.2.3  ArrayList容器包含有关键词Array,这说明该容器跟数组(Array)之间,肯定有什么不为人知的联系。在揭开它们间联系之前,我们可以稍微对比一下两者的不同点。

 我们知道Array数组是静态(定长)的,也就是说标准数组一旦创建,其长度就不可增长或者缩小,这意味着开发人员若想使用Array,则必须知道数组可以容纳多少元素,一旦超出数组的极限,则会造成各种不必要的麻烦。

但一般情况下,只有在程序运行的时候,我们才知道需要的数组有多大。为了解决这个尴尬的问题,JDK开发人员便引入了ArrayList。Arraylist与Array不同,它支持动态改变自身的长度,以适应开发人员需求的改变。

综上所述,Array是不可变数组,ArrayList是动态数组。

Code3 : ArrayList中的主要方法使用,我会写在注释中。

        ArrayList list = new ArrayList();ArrayList list2 = new ArrayList();//ArrayList.add()list.add('B'); //将'B'加入到列表尾部list.add(1, 'A'); //把'A'插入到数组下标为0的位置,被取代的位置向后移动一位//ArrayList.set()list.set(1, 'C'); //把1位置的元素替换成元素'C'//list2list2.add('a'); //ArrayList.addAll()list.addAll(list2); //将容器list2中的所有元素,追加到list1尾部//ArrayList.get() char context = (char)list.get(1); //根据索引,获取元素//ArrayList.remove(Object Or Index) list.remove('A'); //移除指定元素list.remove(1); //移除位置1的元素for(Object c : list){System.out.print((char)c + "\t");}System.out.println(context);

3.3特性与ArrayList相同的LinkedList。但该容器提供了一个链接列表(链表)的数据结构。由于具有链表数据结构,该容器在增删操作上效率高的吓人,当然是相对于龟速而言。
由于LinkedList除了方法与ArrayList略有不同外,笔者是在是懒得在写,直接贴上方法代码:

   Code4:LinkedList list = new LinkedList();list.add('A');list.add('B');list.add('C');//LinkedList.addFrist()list.addFirst('A'); //将'A'元素插入到列表的开头list.addLast('A'); //将'B'元素插入到列表的末尾/* * 同理可得: * LinkedList.getFirst() 获取头元素 * LinkedList.getLast() 获取尾元素 *  * LinkedList.removeFirst() 移除尾元素 * LinkedList.removeLast() 移除尾元素 */for(Object c : list){System.out.print((char)c + "\t");
}




3.4 关于Vector容器,特性与使用方法与ArrayList相同。但两者不同点是关于线程同步与否和效率高低的问题,这里不再做过多的论述。若读者想要了解线程相关知识,笔者自行学习线程知识。

                                             
0 0
原创粉丝点击