首页
登录 | 注册

Java集合排序及java集合类详解

               

Java集合排序及java集合类详解

(Collection, List, Set, Map)

 

摘要内容

集合是Java里面最常用的,也是最重要的一部分。能够用好集合和理解好集合对于做Java程序的开发拥有无比的好处。本文详细解释了关于Java中的集合是如何实现的,以及他们的实现原理。

 

目录

1        集合框架........................................................................................................2

1.1         集合框架概述.....................................................................................2

1.1.1         容器简介...................................................................................2

1.1.2       容器的分类.................................................................................5

1.2        Collection..............................................................................................6

1.2.1        常用方法....................................................................................6

1.2.2         迭代器........................................................................................9

1.3        List.......................................................................................................11

1.3.1       概述.............................................................................................11

1.3.2        常用方法...................................................................................12

1.3.3         实现原理..................................................................................17

1.4        Map......................................................................................................20

1.4.1       概述.............................................................................................20

1.4.2        常用方法...................................................................................21

1.4.3        Comparable接口.....................................................................27

1.4.4         实现原理..................................................................................29

1.4.5       覆写hashCode()........................................................................34

1.5       Set..........................................................................................................39

1.5.1       概述.............................................................................................39

1.5.2       常用方法.....................................................................................39

1.5.3         实现原理..................................................................................45

1.6       总结:集合框架中常用类比较..............................................................46

2       练习.................................................................................................................47

3       附录:排序.....................................................................................................48

 

从头至尾遍历集合,并安全的从底层Collection中除去元素。

下面,我们看一个对于迭代器的简单使用:

import java.util.ArrayList;

import java.util.Collection;

import java.util.Iterator;

 

publicclass IteratorDemo {

   publicstaticvoid main(String[] args) {

      Collection collection =new ArrayList();

      collection.add("s1");

      collection.add("s2");

      collection.add("s3");

      Iterator iterator =collection.iterator();//得到一个迭代器

      while (iterator.hasNext()) {//遍历

         Object element =iterator.next();

         System.out.println("iterator = " + element);

      }

      if(collection.isEmpty())

         System.out.println("collection is Empty!");

      else

         System.out.println("collection is not Empty! size="+collection.size());

      Iterator iterator2 =collection.iterator();

      while (iterator2.hasNext()) {//移除元素

         Object element =iterator2.next();

         System.out.println("remove: "+element);

         iterator2.remove();

      }    

      Iterator iterator3 =collection.iterator();

      if (!iterator3.hasNext()) {//察看是否还有元素

         System.out.println("还有元素");

     

      if(collection.isEmpty())

         System.out.println("collection is Empty!");

      //使用collection.isEmpty()方法来判断

   }

}

程序的运行结果为:

iterator = s1

iterator = s2

iterator = s3

collection is not Empty! size=3

remove: s1

remove: s2

remove: s3

还有元素

collection is Empty!

可以看到,JavaCollectionIterator能够用来,:

1)     使用方法 iterator()要求容器返回一个Iterator .第一次调用Iteratornext()方法时,它返回集合序列的第一个元素。

2)     使用next()获得集合序列的中的下一个元素。

3)     使用hasNext()检查序列中是否元素。

4)     使用remove()将迭代器新返回的元素删除。

需要注意的是:方法删除由next方法返回的最后一个元素,在每次调用next时,remove方法只能被调用一次

大家看,Java实现的这个迭代器的使用就是如此的简单。Iterator(跌代器)虽然功能简单,但仍然可以帮助我们解决许多问题,同时针对List还有一个更复杂更高级的ListIterator。您可以在下面的List讲解中得到进一步的介绍。

[i1] 接口实际上并没有直接的实现类。而List是容器的一种,表示列表的意思。当我们不知道存储的数据有多少的情况,我们就可以使用List来完成存储数据的工作。例如前面提到的一种场景。我们想要在保存一个应用系统当前的在线用户的信息。我们就可以使用一个List来存储。因为List的最大的特点就是能够自动的根据插入的数据量来动态改变容器的大小。下面我们先看看List接口的一些常用方法。

1.3.2        常用方法

List就是列表的意思,它是Collection的一种,继承了接口,以定义一个允许重复项的有序集合。该接口不但能够对列表的一部分进行处理,还添加了面向位置的操作。List是按对象的进入顺序进行保存对象,而不做排序或编辑操作。它除了拥有Collection接口的所有的方法外还拥有一些其他的方法。

面向位置的操作包括插入某个元素或Collection的功能,还包括获取、除去或更改元素的功能。在List中搜索元素可以从列表的头部或尾部开始,如果找到元素,还将报告元素所在的位置。

u      void add(intindex, Object element):添加对象element到位置index

u      booleanaddAll(int index, Collection collection):在index位置后添加容器collection中所有的元素

u      Object get(intindex):取出下标为index的位置的元素

u      intindexOf(Object element):查找对象elementList中第一次出现的位置

u      intlastIndexOf(Object element):查找对象elementList中最后出现的位置

u      Objectremove(int index):删除index位置上的元素

u      Object set(intindex, Object element):将index位置上的对象替换为element并返回老的元素。

先看一下下面表格:

 

 

简述

实现

操作特性

成员要求

List

提供基于索引的对成员的随机访问

ArrayList 

提供快速的基于索引的成员访问,对尾部成员的增加和删除支持较好

成员可为任意Object子类的对象

LinkedList 

对列表中任何位置的成员的增加和删除支持较好,但对基于索引的成员访问支持性能较差

成员可为任意Object子类的对象

集合框架中有两种常规的List实现:ArrayListLinkedList。使用两种List实现的哪一种取决于您特定的需要。如果要支持随机访问,而不必在除尾部的任何位置插入或除去元素,那么,ArrayList提供了可选的集合。但如果,您要频繁的从列表的中间位置添加和除去元素,而只要顺序的访问列表元素,那么,LinkedList实现更好。

我们以ArrayList为例,先看一个简单的例子:

例子中,我们把12个月份存放到ArrayList中,然后用一个循环,并使用get()方法将列表中的对象都取出来。

LinkedList添加了一些处理列表两端元素的方法(下图只显示了新方法):

使用这些新方法,您就可以轻松的把LinkedList当作一个堆栈、队列或其它面向端点的数据结构。

我们再来看另外一个使用LinkedList来实现一个简单的队列的例子

import java.util.*;

 

publicclass ListExample {

  publicstaticvoid main(String args[]) {

    LinkedList queue =new LinkedList();

    queue.addFirst("Bernadine");

    queue.addFirst("Elizabeth");

    queue.addFirst("Gene");

   queue.addFirst("Elizabeth");        

    queue.addFirst("Clara");

    System.out.println(queue);

    queue.removeLast();

    queue.removeLast();

    System.out.println(queue);

 }

}

运行程序产生了以下输出。请注意,Set不同的是List允许重复。

[Clara, Elizabeth, Gene,Elizabeth, Bernadine]

[Clara, Elizabeth, Gene]

该的程序演示了具体List类的使用。第一部分,创建一个由ArrayList支持的List。填充完列表以后,特定条目就得到了。示例的LinkedList部分把LinkedList当作一个队列,从队列头部添加东西,从尾部除去。

List接口不但以位置友好的方式遍历整个列表,还能处理集合的子集:

u      ListIterator listIterator():返回一个ListIterator跌代器,默认开始位置为0

u      ListIterator listIterator(int startIndex):返回一个ListIterator跌代器,开始位置为startIndex

u      List subList(int fromIndex, int toIndex):返回一个子列表List,元素存放为从 fromIndextoIndex之前的一个元素。

处理subList()时,位于fromIndex的元素在子列表中,而位于toIndex的元素则不是,提醒这一点很重要。以下for-loop测试案例大致反映了这一点:

for (int i=fromIndex;i<toIndex; i++) {

  // process element at position i

}

此外,我们还应该提醒的是:对子列表的更改(如add()remove()set()调用)对底层List也有影响。

ListIterator 接口

接口继承接口以支持添加或更改底层集合中的元素,还支持双向访问

以下源代码演示了列表中的反向循环。请注意最初位于列表尾之后(),因为第一个元素的下标是0

正常情况下,不用改变某次遍历集合元素的方向向前或者向后。虽然在技术上可能实现时,但在后立刻调用,返回的是同一个元素。把调用 next() previous()的顺序颠倒一下,结果相同。

我们看一个List的例子:

import java.util.*;

 

publicclass ListIteratorTest {

   publicstaticvoid main(String[] args) {

      List list =new ArrayList();

      list.add("aaa");

      list.add("bbb");

      list.add("ccc");

      list.add("ddd");  

      System.out.println("下标0开始:"+list.listIterator(0).next());//next()

      System.out.println("下标1开始:"+list.listIterator(1).next());

      System.out.println("List 1-3:"+list.subList(1,3));//子列表

      ListIterator it =list.listIterator();//默认从下标0开始

      //隐式光标属性add操作 ,插入到当前的下标的前面

      it.add("sss");

      while(it.hasNext()){

         System.out.println("next Index="+it.nextIndex()+",Object="+it.next());

      }    

      //set属性

      ListIterator it1 =list.listIterator();

      it1.next();

      it1.set("ooo");

      ListIterator it2 =list.listIterator(list.size());//下标

      while(it2.hasPrevious()){

         System.out.println("previous Index="+it2.previousIndex()+",Object="+it2.previous());

      }

   }

}

程序的执行结果为:

下标0开始:aaa

下标1开始:bbb

List 1-3:[bbb, ccc]

next Index=1,Object=aaa

next Index=2,Object=bbb

next Index=3,Object=ccc

next Index=4,Object=ddd

previous Index=4,Object=ddd

previous Index=3,Object=ccc

previous Index=2,Object=bbb

previous Index=1,Object=aaa

previous Index=0,Object=ooo

我们还需要稍微再解释一下操作。添加一个元素会导致新元素立刻被添加到隐式光标的前面。因此,添加元素后调用会返回新元素,而调用则不起作用,返回添加操作之前的下一个元素。下标的显示方式,如下图所示:

对于List的基本用法我们学会了,下面我们来进一步了解一下List的实现原理,以便价升我们对于集合的理解。

1.3.3        实现原理

前面已经提了一下Collection的实现基础都是基于数组的。下面我们就已ArrayList为例,简单分析一下ArrayList列表的实现方式。首先,先看下它的构造函数。

下列表格是在SUN提供的API中的描述:

 

ArrayList()            Constructs an  empty list with an initial capacity of ten.

ArrayList(Collection c)            Constructs a list  containing the elements of the specified collection, in the order they are  returned by the collection's iterator.

ArrayList(int initialCapacity)           Constructs  an empty list with the specified initial capacity.

其中第一个构造函数ArrayList()和第二构造函数ArrayList(Collection c)是按照Collection接口文档所述,所应该提供两个构造函数,一个无参数,一个接受另一个Collection

3个构造函数:

ArrayList(int initialCapacity)ArrayList实现的比较重要的构造函数,虽然,我们不常用它,但是某认的构造函数正是调用的该带参数:



2020 jeepxie.net webmaster#jeepxie.net
10 q. 0.009 s.
京ICP备10005923号