自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

用J2SE 5.0創(chuàng)建定制的泛型集合

開發(fā) 后端
J2SE 5.0引入了許多新型的集合API-你需要了解它們以便能夠正確地實現(xiàn)泛型定制的集合-它可以無縫地與多種類型和新型的"for each"結(jié)構(gòu)一起工作。本文將向你展示示怎樣創(chuàng)建與J2SE最新特征相兼容的集合。

一、 創(chuàng)建支持泛型的類

首先,你必須學習如何創(chuàng)建一個允許存在"泛型類型"的類。這意味著無論何時實例化你的類,你都能夠指定一個或多個Java類型與該類相關(guān)聯(lián)。為了說明這個問題,請考慮列表1中的一個簡單示例類。

注意,列表1中的類是如何聲明的。它在尖括號之間指定三個泛型。這些泛型是真實類型的占位符。當你聲明一個這種類型的類時,你可以指定一個類來代替ONE,TWO和THREE。如果你不這樣做,那么該類將使用Object的默認類型。

這個類顯示出怎樣設(shè)計一個類來接收三個泛型類型。當你創(chuàng)建一個這種類型的類時你要支持準確的類型。

列表1.泛型類:

package com.heatonresearch.examples.collections;
public class Example {
 private ONE one;
 private TWO two;
 private THREE three;
 public ONE getOne() { return one; }
 public void setOne(ONE one) { this.one = one; }
 public THREE getThree() { return three; }
 public void setThree(THREE three) { this.three = three; }
 public TWO getTwo() { return two; }
 public void setTwo(TWO two) { this.two = two; }
 public static void main(String args[]) {
  Example example = new
  Example();
  example.setOne(1.5);
  example.setTwo(2);
  example.setThree("Three");
 }
}

下面是如何實例化一個Example類型的類的情形:

Example example=new Example();

前面的代碼將代替具體的Double,Integer和String類型-相當于在列表1中的"ONE"、"TWO"和"THREE"占位符。你可以看到這些變量都有這些類型,通過下面三行設(shè)置它們的值。

example.setOne(1.5);
example.setTwo(2);
example.setThree("Three");

現(xiàn)在,既然你已經(jīng)知道如何創(chuàng)建一個使用泛型的定制類,那么創(chuàng)建一個使用泛型的定制集合類則更為簡單些。

二、 創(chuàng)建一個Queue類

一個隊列是一個很有用的數(shù)據(jù)結(jié)構(gòu)。為了理解一個隊列的功能,你可以想像在一個娛樂公園人們排隊騎馬的情形。人們從隊的后面進入到隊中。為此,他們等待而***到達隊伍的前端。其順序不能改變。

這種情形可以被應(yīng)用到一個隊列類上去。它共有兩個方法,分別是"push"和"pop"。你使用push方法來把對象放置到隊列中,而使用pop方法從隊列中刪除一項。例如,如果你使用push方法把三個對象添加到隊列上,那么連續(xù)調(diào)用pop三次將以同樣順序從隊列中刪除這三個元素。這正與娛樂公園的情形相一致。如果有三個人以一特定的順序進入隊中,他們將以相同的順序得到騎馬娛樂。

下列代碼顯示出怎么實現(xiàn)一個使用泛型的Java隊列。

package com.heatonresearch.examples.collections;
import java.util.*;
public class Queue {
private ArrayList list = new ArrayList();
public void push(T obj) { list.add(obj); }
public T pop() throws QueueException {
if (size() == 0)
throw new QueueException(
"Tried to pop something from the queue, " +
"when it was empty");
T result = list.get(0);
list.remove(0);
return result;
}
public boolean isEmpty() { return list.isEmpty(); }
public int size() { return list.size(); }
public void clear() { list.clear(); }
}

前面的代碼聲明了隊列類,這樣它可以接收一個泛型類型。

public class Queue

泛型類型"T"是該類類型-它將被放入到該隊列中去。為了把這些項存儲到一個隊列中,該類還要創(chuàng)建一個接收"T"類型的ArrayList。
push方法很簡單的。它接收單一的類型為泛型"T"的對象,并且把它添加到ArrayList上。

pop方法稍微復雜些。首先,如果你要從隊列中彈出一個對象,并且如果在隊列中沒有對象,那么該類將拋出一個QueueException類型的異常。下面是QueueException類。

package com.heatonresearch.examples.collections;
public class QueueException extends Exception {
 public QueueException(String msg) {
  super(msg);
 }
}

下面是拋出QueueException類型異常的代碼:

if (size() == 0)
throw new QueueException("Tried to pop something from the queue, " +
"when it was empty");

如果隊列不空,該方法將從隊列中檢索***一個元素,在一個名叫result的變量中存儲它,然后從該列表中刪除這個項。下面幾行代碼實現(xiàn)了這一功能:

T result = list.get(0);
list.remove(0);
return result;

注意,該臨時變量也是泛型類型"T"。當這個類與真實的代表泛型類型的Java類型一起使用時,為了實現(xiàn)***程度上的兼容性,無論你何時存取這些變量,確??偸鞘褂梅盒皖愋褪欠浅V匾?/P>

#p#

三、 測試Queue類

下列類用于測試"泛型"隊列。

package com.heatonresearch.examples.collections;
 public class TestQueue {
  public static void main(String args[]) {
   Queue queue = new Queue();
   queue.push(1);
   queue.push(2);
   queue.push(3);
   try {
    System.out.println("Pop 1:" + queue.pop());
    System.out.println("Pop 2:" + queue.pop());
    System.out.println("Pop 3:" + queue.pop());
   }
   catch (QueueException e) { e.printStackTrace(); }
  }
 }

前面的代碼中創(chuàng)建的隊列僅接收整型對象。

Queue queue = new Queue();

接下來的測試把三個整數(shù)添加到該隊列上。

queue.push(1);
queue.push(2);
queue.push(3);

 

注意,添加到該隊列中的這些數(shù)字都是原始的類型。因為J2SE的自動裝箱特性,這些原始的int類型被自動地轉(zhuǎn)變成Integer對象。

接下來,該測試使用pop方法檢索對象。在該隊列為空的情況下,該測試捕獲到QueueException異常。從隊列中彈出三個數(shù)字的結(jié)果是:

1
2
3

 

盡管在這里作為一接收的整數(shù)隊列顯示,但是因為泛型,所以隊列類對于任何Java對象情況都能正常工作。

四、 創(chuàng)建一個可預(yù)知的Stack集合

這里是一個更復雜的集合類型-它實現(xiàn)了一個堆棧以使你在實際刪除一個對象之前能夠預(yù)知或"可偷看"。你可以或者通過使用一個迭代算子或使用J2SE 5.0的新的"for each"結(jié)構(gòu)語句來進行預(yù)知。

這個PeekableStack類是一個先進后出(FILO)棧-讓你遍歷當前棧中的內(nèi)容。它的實現(xiàn)使用了兩個類。首先,PeekableStack類實現(xiàn)實際的棧部分。其次,PeekableStackIterator類實現(xiàn)一個"Java標準的"Iterator類-你可以用它來遍歷整個棧。列表2(見所附源代碼文件)顯示出PeekableStack類的具體編碼。

注意,列表2中的PeekableStack類實現(xiàn)了Iterable接口。這對于支持新型的J2SE 5.0"for-each"結(jié)構(gòu)語句是必要的。該Iterable接口用于指定你的集合支持"iterator"方法-它返回一個迭代算子。如果沒有這個接口,你的類將無法與新型的"for-each"結(jié)構(gòu)語句相兼容。

這個可預(yù)知的棧包含push和pop方法,就象隊列一樣。該push方法僅僅是比隊列稍微復雜些。而push方法負責把對象添加到棧上去并增加版本數(shù)(version)。

這個version變量允許PeekableStackIterator類保證沒有修改操作發(fā)生。在迭代算子創(chuàng)建時,這個算子保留一份當前版本數(shù)。如果棧上通過調(diào)用push方法發(fā)生任何變化,那么這個版本數(shù)就不會匹配;此不匹配將導致算子拋出一個ConcurrentModificationException異常。

pop方法稍微復雜些。首先,它必須決定在該列表中的***一個元素,這是通過獲得列表的大小并且減去1而得到的。

int last = list.size() - 1;

如果這個結(jié)果是一個小于零的數(shù)字,那么該棧就是空的,因此pop方法就返回null。

if (last < 0) return null;

如果在棧中存在***一個元素,那么就從列表中檢索它。在從列表中成功地檢索這個項后,你可以把它刪除。

T result = list.get(last);
list.remove(last);

***,返回從列表中檢索的對象。

return result;

為支持"for each"迭代,PeekableStack類的iterator方法返回一個"Java標準的"Iterator類-你可以用它來遍歷包含在棧中的所有對象。iterator方法創(chuàng)建一個新的iterator并且返回之。

PeekableStackIterator peekableStackIterator=new
PeekableStackIterator(this, list);

 

如你所見,該iterator類接收當前棧和棧的項目列表作為構(gòu)造器參數(shù)。這些值將為PeekableStackIterator所用-下一節(jié)將討論之。

五、 創(chuàng)建一個可預(yù)知的Stack迭代算子

如果PeekableStack類將要同Java中新的"for each"結(jié)構(gòu)語句一起使用,那么你必須創(chuàng)建一個"Java標準的"Iterator。列表3顯示出一個PeekableStackIterator類的實現(xiàn)。

在列表3中,迭代子實際上并沒有以任何方式改變棧的值;代之的是,該迭代子追蹤它在元素列表中的當前位置并且總是返回下一個元素。因為這個信息被存儲在iteration類本身,所以有可能存在多個算子運行于相同的棧上。

下列程序用于測試可預(yù)知的棧。

package com.heatonresearch.examples.collections;
 import java.util.*;
 public class TestPeekableStack {
  public static void main(String args[]) {
   PeekableStack stack = new
   PeekableStack();
   stack.push(1);
   stack.push(2);
   stack.push(3);
   for (int i : stack) { System.out.println(i); }
   System.out.println("Pop 1:" + stack.pop());
   System.out.println("Pop 2:" + stack.pop());
   System.out.println("Pop 3:" + stack.pop());
  }
}

如你所見,有三個項被添加到棧上去。然后,這三個項被使用新的"for each"結(jié)構(gòu)語句顯示出來。

for( int i: stack)
{
 System.out.println( i );
}

因此,你看到怎樣成功地實現(xiàn)一集合-它支持新型的J2SE慣例-既有泛型也有"for each"結(jié)構(gòu)語句。如你所見,創(chuàng)建與J2SE 5.0中新型的結(jié)構(gòu)相兼容的集合是相當容易的-這只需要利用泛型并且實現(xiàn)恰當?shù)慕涌诩纯?。你會發(fā)現(xiàn)這樣的集合類被無縫地集成到J2SE 5.0中。

【編輯推薦】

  1. Java中泛型的理解與等價實現(xiàn)
  2. 關(guān)于Java 泛型的基本使用簡介
  3. 泛型編程與設(shè)計新思維
    責任編輯:book05 來源: 天新網(wǎng)
    相關(guān)推薦

    2009-07-08 16:46:54

    J2SE 5.0

    2009-06-08 21:34:09

    J2EEJ2SEJ2ME

    2010-09-29 13:50:31

    J2MEJ2SE

    2010-09-29 10:15:35

    JDKJ2EEJ2SE

    2009-07-09 16:06:10

    JDK J2EE J2

    2009-06-19 16:39:54

    J2EEJ2SEJ2ME

    2009-06-30 15:02:43

    J2SE5.0中的注釋

    2011-07-22 16:25:42

    J2SE

    2010-09-29 14:01:10

    J2MEJ2SE

    2010-09-29 10:22:47

    J2SEJ2EEJ2ME

    2009-07-08 14:38:27

    JDK 1.1J2SE歷史

    2009-07-08 16:00:57

    J2SE 1.2Java2

    2011-04-02 13:47:01

    2009-08-24 18:15:24

    C# Dictiona

    2012-02-16 10:36:43

    Java

    2009-08-24 17:58:19

    C# 泛型集合

    2011-05-25 08:23:58

    JAVAJ2SEJ2ME

    2009-08-24 17:39:21

    C# 泛型集合

    2009-08-28 15:16:18

    C#泛型集合

    2021-09-29 18:17:30

    Go泛型語言
    點贊
    收藏

    51CTO技術(shù)棧公眾號