现在的位置: 首页 > 综合 > 正文

对象容器 – Java对数据结构的封装 – List, ArrayList, LinkedList, Set, SortedSet, HashSet, Map, TreeMap

2012年09月12日 ⁄ 综合 ⁄ 共 3963字 ⁄ 字号 评论关闭

在实际编程当中,很多时候我们要把数据暂时储存起来,以便实现某种特定的功能。在纯C语言中,我们需要自己去实现一个数据结构(如链表、队列等)来进行元素的存取,不仅繁琐,而且效率也不高(类库对数据结构的封装往往都是优化过的,有着较好的性能)。在Java中,我们可以使用对象容器(Container)来方便地存取数据。

1、List接口(List interface)

List接口是java.util.Collction接口的子接口,它在Collection接口的基础上增加了根据索引获取对象的方法。因此List结构的特定是,每个加入List中的元素是按顺序加入的,并可指定索引存取元素,类似于数组。

ArrayList是实现了List接口的类,ArrayList使用数组结构来实现List数据结构。所以对于需要频繁随机访问对象的操作来说,ArrayList可以获得较好的效率,但如果进行删除、添加,效率就会很低,因为ArrayList内部需要移动大量的元素。下面是使用ArrayList的一个示例:

package cls;
import java.util.*;

/**
* ArrayList数组测试
* 2013.3.22
**/
public class ArrayListTest
{
    public static void main(String[] args)
    {
        ArrayList<String> list = new ArrayList<String>();
        Scanner scan = new Scanner(System.in);
        
        while(true)
        {
            String input = scan.next();
            if(input.equals("q"))
                break;
            list.add(input); //使用add()方法添加元素
        }
        
        // 使用迭代器遍历输出
        Iterator it = list.iterator();
        while(it.hasNext())
            System.out.println(it.next());
    }
}

LinkedList类用链表实现了List接口。这就意味着LinkedList在进行添加、删除、插入操作时会获得较好的效率。但对于存取操作,则不如ArrayList效率高。

我们可以使用LinkedList来实现栈(Strack),队列(Queue_)等数据结构 。如:

package cls;
import java.util.*;

/**
* 用LinkedList实现栈
* 2013.3.22
**/
public class LinkedListStack
{
    LinkedList<String> list;
    
    public LinkedListStack()
    {
        this.list = new LinkedList<String>();
    }
    public void push(String str) //压栈
    {
        list.addFirst(str);
    }
    public String top()
    {
        return list.getFirst();
    }
    public String pop() //出栈
    {
        return list.removeFirst();
    }
    public boolean isEmpty()
    {
        return list.isEmpty();
    }
    
    public static void main(String[] args)
    {
        LinkedListStack stack = new LinkedListStack();
        Scanner sc = new Scanner(System.in);
        
        String str;
        while(true)
        {
            str = sc.next();
            if(str.equals("q"))
                break;
            stack.push(str); //压栈
        }
        
        while(!stack.isEmpty())
            System.out.println(stack.pop());
    }
}

package cls;
import java.util.*;

/**
* 用LinkedList实现队列
* 2013.3.22
**/
public class LinkedListQueue
{
    public static void main(String[] args)
    {
        LinkedList<String> Q = new LinkedList<String>();
        Scanner sc = new Scanner(System.in);
        
        String str;
        while(true)
        {
            str = sc.next();
            if(str.equals("q"))
                break;
            // offer() 入队
            Q.offer(str);
        }
        
        // poll();取得并删除队列中的元素
        // 队列为空时返回null
        while((str = Q.poll()) != NULL)
        {
            System.out.println(str);
        }
    }
}

2、Set接口

Set接口也是Collection的子接口。但List容器中的对象允许重复,但Set容器中的对象必须都是唯一的。

HashSet类实现了Set接口。HashSet使用哈希法对元素进行插入、排序等操作,因而能够高效地查找,插入。如:

package cls;
import java.util.*;

/**
* 使用HashSet进行快速查找、插入操作
* 2013.3.22
**/
public class HashSetTest
{
    public static void main(String[] args)
    {
        HashSet<String> set = new HashSet<String>();
        Scanner sc = new Scanner(System.in);
        
        String str;
        while(true) //插入元素
        {
            str = sc.next();
            if(str.equals("quit"))
                break;
            set.add(str);       
        }
        
        while(true) //查找元素
        {
            str = sc.next();
            if(str.equals("quit"))
                break;
                
            // 调用contains()方法查找是否存在该元素
            if(set.contains(str))
                System.out.println("Yes");
            else
                System.out.println("No");
        }
    }
}

3、SortedSet接口

SortedSet是实现了排序功能的接口,实现该接口的类都是有序的。

TreeSet是Java SE中唯一实现SortedSet接口的类,它使用红黑树结构来对插入的元素进行排序。如将输入的字符串按字典序输出 :

package cls;
import java.util.*;

/**
* 使用TreeSet类实现排序
* 2013.3.22
**/
public class TreeSetTest
{
    public static void main(String[] args)
    {
        /**
        * 使用TreeSet的默认方式进行排序
        **/
        TreeSet<String> set = new TreeSet<String>();
        
        set.add("zoo");
        set.add("bird");
        set.add("pear");
        set.add("iPod");
        
        // 使用 enhanced for loop 显示排序后的对象
        for(String str : set)
            System.out.println(str);
            
        System.out.println("----------------------------------------");
        /**
        * 使用自定义方式进行排序
        **/
        Set<String> s = new TreeSet<String>(new TreeSetCustom());
        
        s.add("zoo");
        s.add("bird");
        s.add("pear");
        s.add("iPod");
        
        for(String str : s)
            System.out.println(str);
    }
}

/**
* 自定义排序规则进行排序
* 2013.3.22
**/
class TreeSetCustom implements Comparator
{
    public int compare(Object o1,Object o2)
    {
        // 反字典序
        return ((String)o1).compareTo((String)o2) * (-1);
    }
}

我们还可以自定义排序的规则,以适应在实际应用中的实际需要。要定义自己的排序规则,必须定义一个实现java.util.Comparator接口的对象,实现该接口中的comare()方法。如上例

4、Map接口

实现 java.util.Map接口的对象会将键(key)映射至值(value)。 在将对象存入map中时,需要同时给定一个键,在取回对象时指定键。Map中的每一个键都是唯一的,不得重复。

HashMap实现了Map接口。HashMap在内部使用哈希法,因些能得到很高的查找效率。如:

package cls;
import java.util.*;

/**
* 使用HashMap类实现key - value 的存储结构
* 2013.3.22
**/
public class HashMapTest
{
    public static void main(String[] args)
    {
        HashMap<String,String> set = new HashMap<String,String>();
        
        // put([key],[value]);
        set.put("animal","cat");
        set.put("food","hotdog");
        
        System.out.println(set.get("animal"));
        System.out.println(set.get("food"));
    }
}

TreeMap也实现了Map接口,它使用红黑树对插入的对象进行排序。它的操作与HashMap类似,在此不再赘述。。

PS:学完这章,就一个感觉---碉堡了!!

抱歉!评论已关闭.