Java學習(五).API基礎
?
?
??? Java語言的強大功能主要體現(xiàn)在Java語言完備豐富、功能強大的Java API上。本章介紹Java API的基本結構以及語言包和實用包中的常用類。
?
?
1、Java API 綜述
?
??? Java語言的內(nèi)核非常小,Java語言的強大功能主要體現(xiàn)在Java語言完備豐富、功能強大的Java API上。
??? Java API(Java Application Programming Interface,Java應用程序接口),是Java語言提供的組織成包結構的許多類和接口的集合。Java API為用戶編寫應用程序提供了極大的便利。Java API包含在JDK中,因此用戶只要按照1.3節(jié)介紹的方法安裝了JDK運行環(huán)境就可以使用了。
??? Java API按照內(nèi)容分別組織和存放在不同的包中,Java API中的包及其主要功能按字母順序說明如下:
??????? java.accessibility 接口組件和助手技術的類和接口
??????? java.applet? ?????? Applet所需的類和接口
??????? java.awt?? ???????? 圖形用戶界面所需的類和接口
??????? java.beans? ??????? Java bean所需的類和接口
??????? java.io?? ????????? 系統(tǒng)輸入/輸出所需的類和接口
??????? java.lang?? ??????? Java語言編程的基礎類和接口
??????? java.math?? ??????? 支持任意精度整數(shù)和任意精度小數(shù)的類和接口
??????? java.naming? ?????? 訪問命名服務的類和接口
??????? java.net?? ???????? 網(wǎng)絡應用的類和接口
??????? java.rmi?? ???????? 遠程調(diào)用(RMI)的類和接口
??????? java.security? ???? 用于安全框架的類和接口
??????? java.sql?? ???????? 訪問和處理數(shù)據(jù)源中數(shù)據(jù)的類和接口
??????? java.text?? ??????? 支持按與語言無關方式處理文本、數(shù)據(jù)、數(shù)字和消息的類和接口
??????? java.util?? ??????? 集合框架、事件模型、日期和時間機制、國際化等的類和接口
??????? javax.rmi?? ??????? 支持RMI-IIOP的類和接口
??????? javax.serverlet? ?? 支持serverlet編程的類和接口
??????? javax.sound? ?????? 支持音頻設備數(shù)字接口(MIDI)的類和接口
??????? javax.swing? ?????? 擴充和增強基本圖形用戶界面功能的類和接口
??????? javax.transaction ? 包含有幾個關于事務上下文異常的類
??????? org.omg.CORBA ????? 支持OMG CORBA API到Java語言映射的類和接口
??? 上述大部分的包都又按內(nèi)容組織成子包形式,關于各包的子包這里就不再贅述。
??? Java語言在不斷發(fā)展,這表現(xiàn)在JDK運行環(huán)境的版本在不斷提高。因此,讀者學習本書時,可能Java API中又包含了新的包,或某些包中又增加了新的子包。
打開JDK的幫助文檔,可以看到Java API的詳細說明文檔。
??? Java API包含的內(nèi)容很多,本章主要討論其中兩個最基本的包中的主要類:
??? (1)語言包(java.lang)。主要討論的類有:Object類、Class類、Runtime類、Float類、String類和Math類。
??? (2)實用包(java.util)。主要討論的類和接口有:Arrays類、Vector 類、Data 類和Enumeration接口。
2、語言包(java.lang)簡介
??? java.lang包中包含了Java程序設計語言最基礎的類。本節(jié)討論的java.lang包中的類有Object類、System類、Class類、Runtime類、String類、Math類和Float類。
??? java.lang包是Java語言編程使用最頻繁的包。為了簡化編程,系統(tǒng)固定地默認導入了java.lang包,所以使用java.lang包中的類時可以不用import語句導入。
?
1、Object類
?
??? Object類是Java中所有類的根,所有其他的類都是由Object類派生出來的,因此,根據(jù)繼承的特點,在Object類中定義的成員變量和方法,在其他類中都可以使用。
??? Object類常用方法有:
? ??? equals(Object obj) 比較兩個對象是否相等
? ??? getClass()??????? 獲取對象的運行時類
? ??? toString()??????? 把對象轉換為字符串
??? Object類中還有一組關于線程同步的方法:wait()方法和notify()方法。
??? equals(Object obj)方法與Java運算符"=="的含義相同,但用法不同。當兩個值比較、對象或變量與值比較、兩個變量比較時,使用運算符"==";當比較兩個對象時,使用equals()方法。該方法調(diào)用返回true時表示兩個對象相等(或稱相同),返回false時表示兩個對象不相等。
【例5.1】equals()方法應用舉例。
public class EqualsTest
{
?? public static void main(String args[])
?? {
????? char ch='A';
? ??? if ((ch=='A') || (ch=='a'))??? //變量與值比較
?? ?? System.out.println("true");
? ??? String str1="abc",str2=null;
? ??? if (str1!=null)?????? //對象與值比較
????? System.out.println(str1.equals(str2)); //兩個對象比較
?? }
}
程序運行顯示結果如下:
true
false
2、System類
??? System類提供了許多獲取或重新設置系統(tǒng)資源的靜態(tài)方法。
??? System類的常用方法有:
??????? static Properties getProperty()???? ??????? 獲取系統(tǒng)屬性
??????? static Properties getProperty(String key)?? 獲取由key指定的系統(tǒng)屬性
??????? static void setProperty(Properties props)?? 設置由props指定的系統(tǒng)屬性
??????? static void load(String fileName)??? ?????? 加載本地文件系統(tǒng)中由文件名fileName指定的動態(tài)庫
??????? static void exit(int status)? ????????????? 中斷當前運行的Java虛擬機,status為狀態(tài)碼,非0的狀態(tài)碼表示不正常中斷
??? 其中,獲取系統(tǒng)屬性方法的返回值類型為Properties,Properties是java語言包中定義的一個類。該類定義了系統(tǒng)屬性集合,每個屬性用字符串表示,其常用的幾個屬性值以及含義如下:
??????? java.version??? java運行時環(huán)境版本
??????? java.vm.version? java虛擬機實現(xiàn)的版本
??????? java.class.path? java類的路徑
??????? os.version??? ?? 操作系統(tǒng)的版本
??????? user.name??? ??? 用戶名
??????? user.dir???? ??? 用戶路徑
??????? user.home??? ??? 用戶HOME路徑
【例5.2】用System類獲得當前系統(tǒng)屬性示例。
public class SystemTest
{
public static void main(String args[])
??? {
??????? String str;
??????? //java運行時環(huán)境版本
??????? str = System.getProperty("java.version");
??????? System.out.println("java.version: " + str);???????
?
??????? //java虛擬機實現(xiàn)的版本
??????? str = System.getProperty("java.vm.version");
??????? System.out.println("java.vm.version: " + str);
???????????????
??????? //java類的路徑
??????? str = System.getProperty("java.class.path");
??????? System.out.println("java.class.path: " + str);
???????????????
??????? //操作系統(tǒng)的版本
??????? str = System.getProperty("os.version");
??????? System.out.println("os.version: " + str);
???????????????
??????? //用戶名
??????? str = System.getProperty("user.name");
??????? System.out.println("user.name: " + str);
???????????????
??????? //用戶路徑
??????? str = System.getProperty("user.dir");
??????? System.out.println("user.dir: " + str);
???????????????
??????? //用戶HOME路徑
??????? str = System.getProperty("user.home");
??????? System.out.println("user.home: " + str);
??? }
}
程序的運行結果為:
java.version: 1.4.1_02
java.vm.version: 1.4.1_02-b06
java.class.path: D:\JBuilder9\jdk1.4\lib;D:\;.;
os.version: 5.0
user.name: administrator
user.dir: E:\Java\chapt5
user.home: C:\Documents and Settings\Administrator.ZXB
另外,System類中定義了三個和輸入輸出流有關的靜態(tài)成員變量in、out和err。
?
3、Class類
?
??? Class類的實例代表一個正在運行的Java應用程序的類或接口。Java的基本數(shù)據(jù)類型(boolean,byte,char,shart,int,long,float,double)以及數(shù)組和關鍵字void都是由Class對象來表達。
??? Class類沒有公共的構造方法,Class對象由Java虛擬機自動構造。
??? Class類的常用方法有:
??????? String static getName()?? ?????????????? 返回對象的類名
??????? class static forName(String ClassName) ? 使用ClassName指定的、與類或接口相聯(lián)系的class對象
??????? class static forName(String name,boolean initialize,ClassLoader loader)?? 使用loader指定的類裝載器Class類的forName()方法可用于安裝驅動程序。
??????????? 例如,安裝JDBC-ODBC驅動程序,可以使用下面語句:
??????????? Class.forName("sun.jdbc.odbc.JdbcOdcDriver");
??????? ??? 要安裝Oracle Jdbc驅動程序,可以使用下面語句:
??????????? Class.forName("oracle.jdbc.driver.OracleDriver");
?
4、Runtime類
?
??? 每一個Java應用程序都有一個Runtime類的實例,從而允許應用程序與其運行的環(huán)境進行交互。可利用Runtime類直接訪問運行時環(huán)境資源。
??? Runtime類常用方法有:
??????? static Runtime getRuntime()? ? 返回與當前應用程序相聯(lián)系的運行時環(huán)境
??????? void exit(int status) ???????? 中斷當前運行的Java虛擬機,status為狀態(tài)碼,非0的狀態(tài)碼表示不正常中斷
??????? native void traceInstructions(Boolean on)? 設置對指令的追蹤,如果參數(shù)on為 true,則Java虛擬機對于其上執(zhí)行的每一條指令都發(fā)出調(diào)試信息
??????? native void traceMethodCalls(Boolean on)? ? 設置對調(diào)用方法的追蹤,如果參數(shù)on為 true,則支持指令的追蹤
??????? totalMemory()????? ??????????? 返回系統(tǒng)的內(nèi)存總數(shù)
??????? freeMemory()????? ???????????? 返回系統(tǒng)當前內(nèi)存的剩余空間總數(shù)
??????? gc ()????? ??????????????????? 運行垃圾回收程序
【例5.3】用Runtime類獲得當前系統(tǒng)運行狀況示例。
public class RuntimeTest
{
public static void main(String args[])
??? {
??????? Runtime rtime = Runtime.getRuntime();
??????? long totalMemory = rtime.totalMemory()/1024;
??????? long freeMemory = rtime.freeMemory()/1024;???????
??????? System.out.println("totalMemory: " + totalMemory + "k");
??????? System.out.println("freeMemory: " + freeMemory+ "k");???????
??? }
}
程序運行結果為:
totalMemory: 1984k
freeMemory: 1734k
5、Float類
?
??? 為了方便學習過C語言的人員學習Java語言,Java語言也像C語言一樣,有數(shù)據(jù)類型的概念。但數(shù)據(jù)類型與類不等同。Java是一種純面向對象程序設計語言,為了達到這個目標,語言包中提供了8個稱為數(shù)據(jù)類型包裝類的類,專門完成把Java語言的8個基本數(shù)據(jù)類型包裝為相應的類。
??? Java語言中的8種基本數(shù)據(jù)類型是:byte、short、int、long、float、double、char、boolean,對應的8個數(shù)據(jù)類型包裝類是:Byte、Short、Integer、Long、Float、Double、Character、Boolean。這里僅介紹Float類,其余的相似。
??? Float類的幾個構造方法如下:
??????? Float (double value)?? 以double類型的參數(shù)value創(chuàng)建一個對象
??????? Float (float value)?? 以float類型的參數(shù)value創(chuàng)建一個對象
??????? Float (String s)??? 以String類型的參數(shù)s創(chuàng)建一個對象
??? Float類的幾個方法如下:
??????? compareTo(Float anotherF) ? 比較兩個對象的大小,大于返回1,相等返回0,小于返回-1
??????? floatValue()??? ??????????? 返回對象的float數(shù)據(jù)類型的數(shù)值
??????? doubleValue()??? ?????????? 返回對象的double數(shù)據(jù)類型的數(shù)值
??????? intValue()???? ???????????? 返回對象的int數(shù)據(jù)類型的數(shù)值,小數(shù)部分丟掉
?
6、String類
?
??? 我們說過,定義字符串變量所使用的String不是一個基本數(shù)據(jù)類型,而是Java API中提供的類。
??? String類的構造方法和常用方法有:
??????? String()? ???? 構造方法,初始化創(chuàng)建一個字符為空的String對象
??????? String(byte[] bytes)? ?????????? 構造方法,初始化創(chuàng)建一個string對象,其值由指定bytes轉換而來
??????? compareTo(String anotherString)? 比較字符串,返回兩者之間的差值
??????? length()? ???? 獲取字符串的長度
??????? substring(int beginIndex)? ????? 返回當前字符串的由beginIndex開始到結尾的子串
??????? substring(int beginIndex,int endIndex)? 返回當前字符串的由beginIndex開始到endIndex結尾的子串
??????? toLowerCase()? 返回小寫字符串,即返回的對象中所有的字符均為小寫字符
??????? toUpperCase()? 返回大寫字符串,即返回的對象中所有的字符均為大寫字符
【例5.4】String類應用舉例。
要求:在程序中進行字符串的連接(+)、取子串等操作。
public class StringTest
{
??? public static void main(String args[])
??? {????
????? System.out.println("abc");
????? String cde = "cde";
????? System.out.println("abc" + cde);
????? String c = "abc";
????? c = c.substring(2,3);
????? System.out.println("c = " + c);
????? String d = cde.substring(1, 2);
????? System.out.println("d = " + d);
??? }
}
程序運行顯示結果如下:
abc
abccde
c = c
d = d
7、Math類
?
??? Math類包含了一組基本的數(shù)學運算的方法和常數(shù)。如求絕對值的abs()方法,計算三角函數(shù)的sin()方法和cos()方法,求兩個數(shù)中的較小值和較大值的min()方法和max()方法,求隨機數(shù)的random()方法等。Math類中的所有方法都定義為靜態(tài)的。另外,Math類還把E和PI定義為類的靜態(tài)成員變量,其中,E和PI代表數(shù)學上的相應常數(shù)。
??? Math類是最終類(final),所以不能從Math類中派生其他的新類。
??? Math類的幾個常用方法如下:
??????? double abs(double a)? 求a的絕對值
??????? float abs(float a)?? 求a的絕對值
??????? int abs(int a)??? ??? 求a的絕對值
??????? long abs(long a)?? ?? 求a的絕對值
??????? double random()?? ??? 返回一個(0.0,1.0)區(qū)間的隨機數(shù)
??? abs()方法有4個,包括了4種基本的數(shù)值類型(double,float,int,long),其他方法(如sin()方法 等)類同,為節(jié)省篇幅,這里不再列出。
??? random()方法是非常有用的方法。把random()的返回值乘上一個整數(shù),可以得到任意區(qū)間的、double類型的隨機數(shù);把random()的返回值乘上一個整數(shù)再轉換成int類型,可以得到任意區(qū)間的、int類型的隨機數(shù)。
【例5.5】求10個數(shù)中的最小數(shù)。
要求:用Math類的random()方法產(chǎn)生隨機數(shù)來給數(shù)組賦值。
程序設計如下:
public class Exam5_6
{
??? public static void main(String args[])
??? {
??????? final int SIZE = 10;?????????????? //常量
??????? int i, min;
??????? int a[] = new int[SIZE];
?
??????? for(i = 0; i < a.length; i++)
??????????? a[i] = (int)(Math.random() * 100); //產(chǎn)生隨機數(shù)并賦值
???????????
??????? System.out.print("數(shù)組元素為:");?????? //輸出一維數(shù)組
??????? for(i = 0; i < a.length; i++)
??????????? System.out.print("? " + a[i]);
?
??????? min = a[0];???????????????????????
??????? for(i = 1; i < a.length; i++)
??????????? if(a[i] < min)? min = a[i];??? //尋找最小數(shù)
?
??????? System.out.println("\n最小數(shù)為:" + min);
??? }
}
程序運行結果如下:
數(shù)組元素為:? 64? 99? 44? 94? 28? 82? 39? 19? 6? 41
最小數(shù)為:6
?
3、實用包(java.util)簡介
??? java.util包主要包含集合框架、事件模型、日期和時間機制、國際化等的類和接口。本節(jié)介紹的java.util包的類和接口有Arrays類、Vector類、Data類和Enumeration接口。
?
1、 Arrays類
?
??? Arrays類中包含有數(shù)組操作的一些常用方法(如排序和查找),這可以大大簡化程序設計人員的設計過程。
??? Arrays類的常用方法有:
??????? static void sort(byte[] a)?
??????????? 把byte類型的數(shù)組a中的元素按升序排序
??????? static void sort(byte[] a,int fromIndex,int toIndex)?
??????????? 把byte類型的數(shù)組a中的、從fromIndex到toIndex的元素按升序排序
??????? static void sort(int[] a)? ?
??????????? 把int類型的數(shù)組a中的元素按升序排序
??????? static void sort(int[] a,int fromIndex,int toIndex)? ?
??????????? 把int類型的數(shù)組a中的、從fromIndex到toIndex的元素按升序排序
??????? static void sort(double[] a)
??????????? 把double類型的數(shù)組a中的元素按升序排序
??????? static void sort(double[] a,int fromIndex,int toIndex)
??????????? 把double類型的數(shù)組a中的、從fromIndex到toIndex的元素按升序排序
??????? static int binarySearch(byte[] a,byte key) ?
??????????? 在byte類型的數(shù)組a 中、使用折半查找算法查找指定元素key是否存在,若存在返回該元素的數(shù)組下標;若不存在返回-1
??????? static int binarySearch(int[] a,int key)?
??????????? 在int類型的數(shù)組a 中、使用折半查找算法查找指定元素key是否存在,若存在返回該元素的數(shù)組下標;若不存在返回-1
??????? static int binarySearch(double[] a,double key)?
??????????? 在double類型的數(shù)組a 中、使用折半查找算法查找指定元素key是否存在,若存在返回該元素的數(shù)組下標;若不存在返回-1
說明:
(1)除了上面列出的sort()方法和binarySearch()外,還有char、float、long、Object等類型的sort()方法和binarySearch(),這里不再列出。
(2)在使用binarySearch()時,要求數(shù)組a中的元素已經(jīng)有序排列,否則返回值未定義。
?
2、Vector 類
?
??? Vector類稱作向量類,它實現(xiàn)了動態(tài)的數(shù)組,使用于元素數(shù)量變化的對象數(shù)組。像數(shù)組一樣,Vector類也用從0開始的下標表示元素的位置;但和數(shù)組不同的是,當Vector對象創(chuàng)建后,數(shù)組的元素個數(shù)會隨著Vector對象元素個數(shù)的增大和縮小變化。
??? Vector類的成員變量有:
??????? elementData??? ???? 存放對象元素的數(shù)組
??????? elementCount??? ??? 當前對象元素的個數(shù)
??????? capacityIncreament? 元素個數(shù)變大時自動增大數(shù)組空間的個數(shù)
??? Vector類的構造方法有:
??????? Vector ()?
??????????? 創(chuàng)建元素為空的對象,且elementCount=10,capacityIncreament=0
??????? Vector (int initialC)?
??????????? 創(chuàng)建元素為空的對象,且elementCount= initialC,capacityIncreament=0
??????? Vector (int initialC,int capacityI)?
??????????? 創(chuàng)建元素為空的對象,且elementCount= initialC,capacityIncreament= capacityI
??? Vector類的常用方法有:
??????? void add( int index,Object elem)
??????????? 在Vector對象的index下標處插入元素elem,index下標以后的元素依次后移
??????? boolean add(Object elem)
??????????? 在Vector對象的尾部添加元素elem,添加成功返回true,失敗返回false
??????? boolean addAll(Collection c)
??????????? 在Vector對象的尾部、依次添加集合對象c中的所有元素,添加成功返回true,失敗返回false
??????? void addElement(Object obj)
??????????? 在Vector對象的尾部、增加對象obj,且對象的元素個數(shù)加1
??????? boolean removeElement(Object obj)
??????????? 如果對象非空,則刪除Vector對象obj第一次出現(xiàn)的元素
??????? copyInto(Object[] anArray)
??????????? 把Vector對象指針所指位置的成分復制給數(shù)組anArray,要求數(shù)組anArray要足夠大,否則會拋出異常
??????? Enumeration elements()????
??????????? 返回對象的序列化元素
??????? int size()??????
??????????? 返回對象的元素個數(shù)
??? 和Arrays類相比,Vector類的最主要特點是長度可隨對象成分個數(shù)的增加或減少任意變化。
?
3、Data 類和Calendar類
?
??? Data 類提供了獲取當前精確到毫秒時間的方法,并提供了許多方法截取當前時間的年、月、日等數(shù)值。
??? Data 類的構造方法有:
??????? Data ()??? 創(chuàng)建一個可精確到毫秒的當前時間的對象
??????? Data (long date)? 創(chuàng)建一個可精確到毫秒的參數(shù)date指定時間的對象,date表示從GMT(格林威治)時間1970-1-1 00:00:00開始至某時刻的毫秒數(shù)。
???
Calendar類定義了許多如YEAR、MONTH、DAY、HOUR、MINUTE、SECOND、DAY_OF_WEEK等成員變量,Calendar類的get()方法可以獲取這些成員變量的數(shù)值。
【例5.6】設計程序獲取本地計算機上的當前時間并顯示。
程序設計如下:
import java.util.*;
public class MyDate
{
public static void main(String args[])
{
? Date date = new Date();? //創(chuàng)建對象,其值為當前時間
? System.out.println(date); //輸出顯示當前時間
?
? //分項輸出顯示當前時間
????? Calendar now = Calendar.getInstance();???????? //獲得當前時間
????? int year =now.get(Calendar.YEAR);????????????? //年份
????? int month=now.get(Calendar.MONTH)+1;?????????? //月份
????? int day = now.get(Calendar.DATE);????????????? //日期
????? System.out.print(year+"年"+month+"月"+day+"日 ");
?
????? int hour = now.get(Calendar.HOUR);???????????? //時
????? int minute = now.get(Calendar.MINUTE);???????? //分
????? int second = now.get(Calendar.SECOND);???????? //秒
????? System.out.print(hour+"時"+minute+"分"+second+"秒 ");
????????
????? int week = now.get(Calendar.DAY_OF_WEEK);??? ? //星期1~7
????? String str = "日一二三四五六";
????? int i=2*(week-1);???????????????????????????? //對應中文的下標
????? System.out.println("星期"+str.substring(i,i+2));
}
}
程序運行結果如下:
Tue Sep 28 10:32:29 CST 2004
2004年9月28日 10時32分29秒 星期二
4、Enumeration接口
?
??? Enumeration接口主要用于集合類對象的序列化。一個集合類對象中包含有許多元素,所謂對象是序列化的,就是說可以依次取出該對象中的元素。
??? Enumeration接口定義如下:
??? public interface Enumeration
??? {
??? ? Object nextElement();???? ? //返回后續(xù)元素
??? ? boolean hasMoreElements();? //是否還有后續(xù)元素
??? }
??? nextElement()方法返回后續(xù)元素;hasMoreElements()方法判斷是否還有后續(xù)元素。
??? 任何一個類,只要實現(xiàn)了Enumeration接口,其對象就是序列化的。所謂對象是序列化的,就是說若連續(xù)調(diào)用nextElement()方法,每次將返回該集合對象當前元素的后續(xù)元素。
??? 例如,Vector類是一個集合類,Vector類就實現(xiàn)了Enumeration接口。因此,若要輸出一個Vector類的對象v中的所有元素,就可以編寫如下代碼:
??? Enumeration e = v.elements();
??? while (e.hasMoreElements())
??? {
????? System.out.println(e.nextElement());
??? }
?
4、綜合應用舉例
?
??? 為了讓讀者更好地理解Java API的使用方法,本節(jié)給出兩個簡單的Java API的應用例子。
【例5.7】把10個數(shù)按從小到大的次序排序。
要求:用 Arrays類的sort()方法實現(xiàn)排序。
程序設計如下:
import java.util.*;
public class Exam5_7
{
??? public static void main(String args[])
??? {
??????? final int SIZE = 10;???????????????????????? //常量
??????? int i, min;
??????? int a[] = new int[SIZE];
?
??????? for(i = 0; i < a.length; i++)
??????????? a[i] = (int)(Math.random() * 100);?????? //產(chǎn)生隨機數(shù)并賦值
??????
??????? System.out.println("排序前數(shù)組元素為:");
??????? for(i = 0; i < a.length; i++)
??????????? System.out.print(a[i] + "? ");
?
? ????? Arrays.sort(a);??????? //排序
?
??????? System.out.println("\n排序后數(shù)組元素為:");
??????? for(i = 0; i < a.length; i++)
??????????? System.out.print(a[i] + "? ");
??? }
}
程序運行結果如下:
排序前數(shù)組元素為:
40? 96? 31? 20? 85? 58? 40? 89? 18? 18
排序后數(shù)組元素為:
18? 18? 20? 31? 40? 40? 58? 85? 89? 96
【例5.8】使用Vector類和Integer類求解約瑟夫環(huán)問題。
約瑟夫環(huán)(Josephus)問題:古代某法官要判決N個犯人的死刑,他有一條荒唐的法律,將犯人站成一個圓圈,從第S個人開始數(shù)起,每數(shù)到第D個犯人,就拉出來處決,然后再數(shù)D個,數(shù)到的人再處決,……,直到剩下的最后一個可赦免。
當N=5,S=0,D=2時,約瑟夫環(huán)問題執(zhí)行過程示意圖如下圖所示。
??? .01_thumb.jpg)
設計:
1.初始化,創(chuàng)建一個Vector類的向量對象v,調(diào)用v的add()方法依次將N個人的序號添加到v中。由于v的元素類型為Object,所以add()的參數(shù)必須使用new Integer(i+1)將int值轉化為Integer對象。
2.設current為當前欲刪除元素的下標,如果從第1個人開始數(shù)起,則current的初值應該設置為第1個人的前一個位置,即current=S-1。
3.循環(huán),當v中元素多于一個時(v.size()>0),調(diào)用v.remove()方法刪除下標為current的元素。current的值一直在增加,但既不能超出數(shù)組下標范圍,又要實現(xiàn)環(huán)形結構,所以current的變化規(guī)律是current=(current + 1) % v.size(),其中v.size()是v的實際元素個數(shù),每刪除一個元素,v.size()的值少1。
4.為了更好地了解向量中的元素情況,每次循環(huán)都輸出了向量中的全部元素值,調(diào)用(Integer)v.get(i))方法將獲得的下標為i的Object類元素轉化為Integer類對象,再調(diào)用Integer類的intValue()方法輸出相應的int值。
5.當循環(huán)停止時,向量v中只剩下一個元素,這就是我們要找的最后一個人。
程序如下:
import java.util.*;
public class Josephus??????????????? //使用Vector類求解約瑟夫環(huán)問題
{
??? public static void main(String args[])
??? {
??????? int n=5,s=0,d=2;
??????? Vector v = new Vector(n); //創(chuàng)建向量對象v
??????? for(int i = 0; i < n; i++)
??????????? v.add(new Integer(i+1)); //向量對象v中添加Integer對象
?
??????? int current = s - 1;???????? //設置當前元素下標current的初值
??????? while (v.size()>1)??????????? //向量對象v中多于一個元素時循環(huán)
??????? {
??????????? System.out.print("Vector:? ");
??????????? for(int i = 0; i < v.size(); i++)//輸出向量對象v中全部元素值
?????????????? System.out.print(((Integer)v.get(i)).intValue() + "? ");
??????????? int j=0;
??????????? while (j<d)???????????????? //計數(shù)
??????????? {
???????????????? current = (current + 1) % v.size();
???????????????? j++;
??????????? }
??????????? System.out.println("\tcurrent = " + current + "??? ");
??????????? v.remove(current);???????? //刪除向量v中下標為current的元素
??????? }
??????? System.out.println("赦免者是" +((Integer)v.get(0)).intValue());
???????
??? }
}
程序運行結果如下:
Vector:? 1? 2? 3? 4? 5?? current = 1???
Vector:? 1? 3? 4? 5??? current = 3???
Vector:? 1? 3? 4??? current = 2???
Vector:? 1? 3???? current = 0???
赦免者是3
?