Java学习(五).API基础
1、
Java语言的内核非常小,Java语言的强大 功能主要体现在Java语言完备丰富、功能强大的Java API上。
Java API(Java Application Programming Interface ,Java应用程序接口),是Java语言提供的组织成包结构的许多类和接口的集合。Java API为用户编写应用程序提供了极大的便利。Java API包含在JDK中,因此用户只要按照1.3节介绍的方法安装了JDK运行环境就可以使用了。
Java API按照内容分别组织和存放在不同的包中,Java API中的包及其主要功能按字母顺序说明如下:
java.accessibility 接口组件和助手技术的类和接口
java.applet Applet所需的类和接口
java.awt 图形用户界面所需的类和接口
java.beans Java bean所需的类和接口
java.io 系统输入/输出所需的类和接口
java.lang Java语言编程的基础类和接口
java.math 支持任意精度整数和任意精度小数的类和接口
java.naming 访问命名服务的类和接口
java.net 网络应用的类和接口
java.rmi 远程调用(RMI)的类和接口
java.security 用于安全框架的类和接口
java.sql 访问和处理数据源中数据的类和接口
java.text 支持按与语言无关方式处理文本、数据、数字和消息的类和接口
java.util 集合框架、事件模型、日期和时间机制、国际化等的类和接口
javax.rmi 支持RMI-IIOP的类和接口
javax.serverlet 支持serverlet编程的类和接口
javax.sound 支持音频设备数字接口(MIDI)的类和接口
javax.swing 扩充和增强基本图形用户界面功能的类和接口
javax.transaction
org.omg.CORBA
上述大部分的包都又按内容组织成子包形式,关于 各包的子包这里就不再赘述。
Java语言在不断发 展,这表现在JDK运行环境的版本在不断提高。因此,读者学习本书时,可能Java API中又包含了新的包,或某些包中又增加了新的子包。
打开 JDK的帮助文档,可以看到Java API的详细说明文档。
Java API包含的内容很多,本章主要讨论其中两个最基本的包中的主要类:
( 1) 语言包(java.lang)。 主 要讨论的类有:Object类、Class类、Runtime类、Float类、String类和Math类。
( 2) 实用包(java.util)。 主要讨论的类和接口有:Arrays类、Vector 类、Data 类和Enumeration接口。
2、
java.lang包中包含了Java程序设计 语言最基础的类。本节讨论的java.lang包中的类有Object 类、System 类、Class 类、Runtime 类、String 类、Math 类和Float 类。
java.lang包是Java语言编程使用最频繁的包。为了简化编 程,系统固定地默认导入了java.lang包,所以使用java.lang包中的类时可以不用import语句导入。
1、
Object类是Java中所有类的根,所有其 他的类都是由Object类派生出来的,因此,根据继承的特点,在Object类中定义的成员变量和方法,在其他类中都可以使用。
Object类常用方法有:
equals(Object obj) 比较两个对象是否相等
getClass() 获取对象的运行时类
toString() 把对象转换为字符串
Object类中还有一组关于线程同步的方法:wait() 方法和notify() 方 法。
equals(Object obj)方法与Java运算符"=="的含义相同,但用法不同。当两个值比较、对象或变量与值比较、两个变量比较时,使用运算符"==";当比较两个对象 时,使用equals()方法。该方法调用返回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类的常用方法有:
static Properties getProperty() 获 取系统属性
static Properties getProperty(String key) 获取由key指定的系统属性
static void setProperty(Properties props) 设置由props指定的系统属性
static void load(String fileName) 加载本地文件系统中由文件 名fileName指定的动态库
static void exit(int status)
其中,获取系统属性方法的返回值类型为Properties ,Properties是java语言包中定 义的一个类。该类定义了系统属性集合,每个属性用字符串表示,其常用的几个属性值以及含义如下:
java.version java运行时环境版本
java.vm.version java虚拟机实现的版本
java.class.path java类的路径
os.version 操作系统的版本
user.name 用户名
user.dir 用户路径
user.home
【例5.2】用System类获得当前系统属性示例。
public class SystemTest
{
public static void main(String args[])
{
String str;
//java运行时环境版本
str = System.getProperty("java.version");
System.out.println("java.version: " + str);
//java虚拟机实现的版本
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);
//操作系统的版本
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类中定义了三个和输入输出流有关的静态成员变量in、out和err。
3、 Class类
Class类的实例代表一个正在运行的Java 应用程序的类或接口。Java的基本数据类型(boolean,byte,char,shart,int,long,float,double)以及数组 和关键字void都是由Class对象来表达。
Class 类没有公共的构造方法,Class对象由Java虚拟机自动构造。
Class 类的常用方法有:
String static getName() 返回对象的类名
class static forName(String ClassName) 使 用ClassName指定的、与类或接口相联系的class对象
class static forName(String name,boolean initialize,ClassLoader loader)
例如,安装JDBC-ODBC 驱动程序,可以使用下面语句:
Class.forName("sun.jdbc.odbc.JdbcOdcDriver");
要安装Oracle Jdbc驱动程序,可以使用下面语句:
Class.forName("oracle.jdbc.driver.OracleDriver");
4、
每一个Java应用程序都有一个Runtime 类的实例,从而允许应用程序与其运行的环境进行交互。可利用Runtime类直接访问运行时环境资源。
Runtime类常用方法有:
static Runtime getRuntime() 返回与当前应用程序相联系的运行时环境
void exit(int status) 中断当前运行的Java虚拟机,status为状态码,非0的 状态码表示不正常中断
native void traceInstructions(Boolean on) 设 置对指令的追踪,如果参数on为 true,则Java虚拟机对于其上执行的每一条指令都发出调试信息
native void traceMethodCalls(Boolean on) 设 置对调用方法的追踪,如果参数on为 true,则支持指令的追踪
totalMemory() 返 回系统的内存总数
freeMemory() 返回系统当前内存的剩余空间总数
gc () 运行垃圾回收程序
【例5.3】用Runtime类获得当前系统运行状况示例。
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、
为了方便学习过C语言的人员学习Java语 言,Java语言也像C语言一样,有数据类型的概念。但数据类型与类不等同。Java是一种纯面向对象程序设计语言,为了达到这个目标,语言包中提供了8 个称为数据类型包装类的类,专门完成把Java语言的8个基本数据类型包装为相应的类。
Java语言中的8种基本数据类型是:byte、short、int、 long、float、double、char、boolean,对应的8个数据类型包装类是:Byte、Short、Integer、Long、 Float、Double、Character、Boolean。这里仅介绍Float类,其余的相似。
Float类的几个构造方法如下:
Float (double value) 以double类型的参数value创建一个对象
Float (float value) 以float类型的参数value创建一个对象
Float类的几个方法如下:
compareTo(Float anotherF) 比较两个对象的大小,大于返回1,相等返 回0,小于返回-1
floatValue() 返回对象的float数据类型的数值
doubleValue() 返回对象的double数据类型的数值
intValue()
6、String类
我们说过,定义字符串变量所使用的String 不是一个基本数据类型,而是Java API中提供的类。
String 类的构造方法和常用方法有:
String() 构造方法,初始化创 建一个字符为空的String对象
String(byte[] bytes) 构造方法,初始化创建一个 string对象,其值由指定bytes转换而来
compareTo(String anotherString) 比较字符串,返回两者之间的差值
length() 获取字符串的长度
substring(int beginIndex) 返回当前字符串的由beginIndex开始到结尾的子串
substring(int beginIndex,int endIndex) 返回当前字符串的由beginIndex开始到endIndex结尾的子串
toLowerCase() 返回小写字符串,即返回的对象中所有的字符均为小写字符
【例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类包含了一组基本的数学运算的方法和常 数。如求绝对值的abs()方法,计算三角函数的sin()方法和cos()方法,求两个数中的较小值和较大值的min()方法和max()方法,求随机 数的random()方法等。Math类中的所有方法都定义为静态的。另外,Math类还把E和PI定义为类的静态成员变量,其中,E和PI代表数学上的 相应常数。
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()
abs()方法有4个,包括了4种基本的数值类型 (double,float,int,long),其他方法(如sin()方法 等)类同,为节省篇幅,这里不再列出。
random()方法是非常有用的方法。把random()的返回值乘上 一个整数,可以得到任意区间的、double类型的随机数;把random()的返回值乘上一个整数再转换成int类型,可以得到任意区间的、int类型 的随机数。
【例5.5】求10个数中的最小数。
要求:用Math类的 random()方法产生随机数来给数组赋值。
程序设计如下:
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); //产生随机数并赋值
System.out.print("数组元素为:"); //输出一维数组
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]; //寻找最小数
System.out.println("/n最小数为:" + min);
}
}
程序运行结果如下:
数组元素为: 64 99 44 94 28 82 39 19 6 41
最小数为:6
3、
java.util包主要包含集合框架、事件模 型、日期和时间机制、国际化等的类和接口。本节介绍的java.util包的类和接口有Arrays 类、Vector 类、Data 类和Enumeration 接口。
1、
Arrays类中包含有数组操作的一些常用方法 (如排序和查找),这可以大大简化程序设计人员的设计过程。
Arrays 类的常用方法有:
把byte类型的数组a中 的元素按升序排序
把byte类型的数组a中 的、从fromIndex到toIndex的元素按升序排序
static void sort(int[] a)
把int类型的数组a中的 元素按升序排序
static void sort(int[] a,int fromIndex,int toIndex)
把int类型的数组a中 的、从fromIndex到toIndex的元素按升序排序
把double类型的数组 a中的元素按升序排序
把double类型的数组 a中的、从fromIndex到toIndex的元素按升序排序
static int binarySearch(byte[] a,byte key)
在byte类型的数组a 中、使用折半查找算法查找指定元素key是否存在,若存在返回该元素的数组下标;若不存在返回-1
在int类型的数组a 中、使用折半查找算法查找指定元素key是否存在,若存在返回该元素的数组下标;若不存在返回-1
static int binarySearch(double[] a,double key)
说明:
( 1) 除了上面列出的sort()方法和binarySearch()外,还有char、float、long、Object 等类型的sort()方法和 binarySearch(),这里不再列出。
( 2) 在使用binarySearch()时,要求数组a中的元素已经有序排列,否 则返回值未定义。
2、
Vector类称作向量类,它实现了动态的数 组,使用于元素数量变化的对象数组。像数组一样,Vector类也用从0开始的下标表示元素的位置;但和数组不同的是,当Vector对象创建后,数组的 元素个数会随着Vector对象元素个数的增大和缩小变化。
Vector 类的成员变量有:
elementData 存放对象元素的数组
elementCount 当前对象元素的个数
Vector类的构造方法有:
Vector ()
创建元素为空的对象,且 elementCount=10,capacityIncreament=0
Vector (int initialC)
创建元素为空的对象,且elementCount= initialC,capacityIncreament=0
Vector (int initialC,int 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,且对象的 元素个数加1
boolean removeElement(Object obj)
如果对象非空,则删除Vector对象obj第一次出现的元素
copyInto(Object[] anArray)
把Vector对象指针所指位置的成分复制给数组 anArray,要求数组anArray要足够大,否则会抛出异常
返回对象的序列化元素
和Arrays类相比,Vector类的最主要 特点是长度可随对象成分个数的增加或减少任意变化。
3、
Data 类提供了获取当前精确到毫秒时间的方法,并提供了许多方法截取当前时间的年、月、日等数值。
Data 类的构造方法有:
Data () 创建一个可精确到毫秒的当前时间的对象
Calendar 类定义了许多如YEAR、MONTH、DAY、HOUR、 MINUTE、SECOND、DAY_OF_WEEK 等成员变 量,Calendar类的get()方法可以获取这些成员变量的数值。
【例5.6】设计程序获取本地计算机上的当前时间并显示。
程序设计如 下:
import java.util.*;
public class MyDate
{
public static void main(String args[])
{
Date date = new Date(); //创建对象,其值为当前时间
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接口定义如下:
public interface Enumeration
{
Object nextElement(); //返回后续元素
boolean hasMoreElements(); //是否还有后续元素
nextElement()方法返回后续元 素;hasMoreElements()方法判断是否还有后续元素。
任何一个类,只要实现了Enumeration接口,其对象就是序列化的。所谓对象是序列化的,就是说若连续调用 nextElement()方法,每次将返回该集合对象当前元素的后续元素。
例如,Vector类是一个集合类,Vector类就实现了Enumeration接口。因此,若要输出一个Vector类的对象v中的 所有元素,就可以编写如下代码:
Enumeration e = v.elements(); while (e.hasMoreElements())
{
System.out.println(e.nextElement());
4、
为了让读者更好地理解Java API的使用方法,本节给出两个简单的Java API的应用例子。
【例5.7】把10个数按从小到大的次序排序。
要求:用 Arrays类的sort()方法实现排序。
程序设计如下:
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); //产生随机数并赋值
System.out.println("排序前数组元素为:");
for(i = 0; i < a.length; i++)
System.out.print(a[i] + " ");
System.out.println("/n排序后数组元素为:");
for(i = 0; i < a.length; i++)
System.out.print(a[i] + " ");
}
}
程 序运行结果如下:
排序前数组元素为:
40 96 31 20 85 58 40 89 18 18
排序后数组 元素为:
18 18 20 31 40 40 58 85 89 96
【例5.8】使用Vector类和Integer类求解约瑟夫环问题。
约 瑟夫环(Josephus)问题:古代某法官要判决N个犯人的死刑,他有一条荒唐的法律,将犯人站成一个圆圈,从第S个人开始数起,每数到第D个犯人,就 拉出来处决,然后再数D个,数到的人再处决,……,直到剩下的最后一个可赦免。
当N=5,S=0,D=2时,约瑟夫环问题执行过程示意图如下图所 示。
设计:
1. 初始化,创建一个Vector类的向量对象v,调用v的add()方法依次将 N个人的序号添加到v中。由于v的元素类型为Object,所以add()的参数必须使用new Integer(i+1)将int值转化为Integer对象。
2. 设 current为当前欲删除元素的下标,如果从第1个人开始数起,则current的初值应该设置为第1个人的前一个位置,即current=S-1。
3. 循环,当v中元素多于一个时(v.size()>0),调用 v.remove()方法删除下标为current的元素。current的值一直在增加,但既不能超出数组下标范围,又要实现环形结构,所以 current的变化规律是current=(current + 1) % v.size(),其中v.size()是v的实际元素个数,每删除一个元素,v.size()的值少1。
4. 为了更好地了解向量中的元素情况,每次循环都输出了向量中的全部元素值,调用 (Integer)v.get(i))方法将获得的下标为i的Object类元素转化为Integer类对象,再调用Integer类的 intValue()方法输出相应的int值。
5. 当循环停 止时,向量v中只剩下一个元素,这就是我们要找的最后一个人。
程序如下:
import java.util.*;
public class Josephus //使用Vector类求解约瑟夫环问题
{
public static void main(String args[])
{
int n=5,s=0,d=2;
Vector v = new Vector(n); //创建向量对象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中多于一个元素时循环
{
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) //计数
{
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