Free Will

Java学习笔记(8):常用库类、向量与哈希

一、Java基础类库

Java 的类库是 Java 语言提供的已经实现的标准类的集合,是 Java 编程的 API(Application Program Interface),它可以帮助开发者方便、快捷地开发 Java 程序。这些类根据实现的功能不同,可以划分为不同的集合,每个集合组成一个包,称为类库。Java 类库中大部分都是由Sun 公司提供的,这些类库称为基础类库。

Java 语言中提供了大量的类库共程序开发者来使用,了解类库的结构可以帮助开发者节省大量的编程时间,而且能够使编写的程序更简单更实用。Java 中丰富的类库资源也是 Java 语言的一大特色,是 Java 程序设计的基础。

Java 常用包的简单介绍如下:

  • java.lang 包:主要含有与语言相关的类。java.lang 包由解释程序自动加载,不需要显示说明。
  • java.io 包:主要含有与输入/输出相关的类,这些类提供了对不同的输入和输出设备读写数据的支持,这些输入和输出设备包括键盘、显示器、打印机、磁盘文件等。
  • java.util 包:包括许多具有特定功能的类,有日期、向量、哈希表、堆栈等,其中 Date类支持与时间有关的操作。
  • java.swing 包和 java.awt 包:提供了创建图形用户界面元素的类。通过这些元素,编程者可以控制所写的 Applet 或 Application 的外观界面。包中包含了窗口、对话框、菜单等类。
  • java.net 包:含有与网络操作相关的类,如 TCP Scokets、URL 等工具。
  • java.applet 包:含有控制 HTML 文档格式、应用程序中的声音等资源的类,其中 Applet类是用来创建包含于 HTML 的 Applet 必不可少的类。
  • java.beans 包:定义了应用程序编程接口(API),Java Beans 是 Java 应用程序环境的中性平台组件结构。

二、Java语言包(java.lang)简介

Java语言包(java.lang)定义了Java中的大多数基本类,由Java语言自动调用,不需要显示声明。该包中包含了Object类,Object类是整个类层次结构的根结点,同时还定义了基本数据类型的类,如:String、Boolean、Byter、Short等。这些类支持数字类型的转换和字符串的操作等,下面将进行简单介绍。

Math类提供了常用的数学运算方法以及Math.PI和Math.E两个数学常量。该类是final的,不能被继承,类中的方法和属性全部是静态,不允许在类的外部创建Math类的对象。因此,只能使用Math类的方法而不能对其作任何更改。表8-1列出了Math类的主要方法。

2.1 Math类

Math类的主要方法

方法 功能
int abs(int i) 求整数的绝对值(另有针对long、float、double的方法)
double ceil(double d) 不小于d的最小整数(返回值为double型)
double floor(double d) 不大于d的最大整数(返回值为double型)
int max(int i1,int i2) 求两个整数中最大数(另有针对long、float、double的方法)
int min(int i1,int i2) 求两个整数中最小数(另有针对long、float、double的方法)
double random() 产生0~1之间的随机数
int round(float f) 求最靠近f的整数
long round(double d) 求最靠近d的长整数
double sqrt(double a) 求平方根
double sin(double d) 求d的sin值(另有求其他三角函数的方法如cos,tan,atan)
double log(double x) 求自然对数
double exp(double x) 求e的x次幂(ex)
double pow(double a, double b) 求a的b次幂

例如:产生10个10~100之间的随机整数。

1
2
3
4
5
6
7
8
9
10
11
12
//********** ep8_2.java **********
class Demo{
public static void main(String args[]){
int a;
System.out.print("随机数为:");
for(int i=1;i<=10;i++){
a=(int)((100-10+1)*Math.random()+10);
System.out.print(" "+a);
}
System.out.println();
}
}

2.2 字符串类

字符串是字符的序列。在 Java 中,字符串无论是常量还是变量都是用类的对象来实现的。java.lang 提供了两种字符串类:String 类和 StringBuffer 类。

1.String 类

按照 Java 语言的规定,String 类是 immutable 的 Unicode 字符序列,其作用是实现一种不能改变的静态字符串。例如,把两个字符串连接起来的结果是生成一个新的字符串,而不会使原来的字符串改变。实际上,所有改变字符串的结果都是生成新的字符串,而不是改变原来字符串。

字符串与数组的实现很相似,也是通过 index 编号来指出字符在字符串中的位置的,编号从0 开始,第 2 个字符的编号为 1,以此类推。如果要访问的编号不在合法的范围内,系统会产生 StringIndexOutOfBoundsExecption 异常。如果 index 的值不是整数,则会产生编译错误。

String 类提供了如下表所示的几种字符串创建方法。

方法 功能
String s=”Hello!” 用字符串常量自动创建 String 实例。
String s=new String(String s) 通过 String 对象或字符串常量传递给构造方法。
public String(char value[]) 将整个字符数组赋给 String 构造方法。
public String(char value[], int offset, int count) 将字符数组的一部分赋给 String 构造方法,offset 为起始下标,count为子数组长度。

2.StringBuffer 类

String 类不能改变字符串对象中的内容,只能通过建立一个新串来实现字符串的变化。如果字符串需要动态改变,就需要用 StringBuffer 类。StringBuffer 类主要用来实现字符串内容的添加、修改、删除,也就是说该类对象实体的内存空间可以自动改变大小,以便于存放一个可变的字符序列。

StringBuffer 类提供的三种构造方法:

构造方法 说明
StringBuffer() 使用该无参数的构造方法创建的 StringBuffer 对象,初始容量为 16 个字符,当对象存放的字符序列大于 16 个字符时,对象的容量自动增加。该对象可以通过 length()方法获取实体中存放的字符序列的长度,通过 capacity()方法获取当前对象的实际容量。
StringBuffer(int length) 使用该构造方法创建的 StringBuffer 对象,其初始容量为参数 length 指定的字符个数,当对象存放的字符序列的长度大于 length 时,对象的容量自动增加,以便存放所增加的字符。
StringBuffer(Strin str) 使用该构造方法创建的 StringBuffer 对象,其初始容量为参数字符串 str 的长度再加上 16 个字符。

几种 StringBuffer 类常用的方法

方法 说明
append() 使用 append() 方法可以将其他 Java 类型数据转化为字符串后再追加到 StringBuffer 的对象中。
insert(int index, String str) insert() 方法将一个字符串插入对象的字符序列中的某个位置。
setCharAt(int n, char ch) 将当前 StringBuffer 对象中的字符序列 n 处的字符用参数 ch 指定的字符替换,n 的值必须是非负的,并且小于当前对象中字符串序列的长度。
reverse() 使用 reverse()方法可以将对象中的字符序列翻转。
delete(int n, int m) 从当前 StringBuffer 对象中的字符序列删除一个子字符序列。这里的 n 指定了需要删除的第一个字符的下标,m 指定了需要删除的最后一个字符的下一个字符的下标,因此删除的子字符串从 n~m-1。
replace(int n, int m, String str) 用 str 替换对象中的字符序列,被替换的子字符序列由下标 n 和 m 指定。

三、日期和时间类

Java 的日期和时间类位于 java.util 包中。利用日期时间类提供的方法,可以获取当前的日期和时间,创建日期和时间参数,计算和比较时间。

3.1 Date 类

Date 类是 Java 中的日期时间类,其构造方法比较多,下面是常用的两个:

  • Date():使用当前的日期和时间初始化一个对象。
  • Date(long millisec):从1970年01月01日00时(格林威治时间)开始以毫秒计算时间,计算 millisec 毫秒。如果运行 Java 程序的本地时区是北京时区(与格林威治时间相差 8 小时),Date dt1=new Date(1000);,那么对象 dt1 就是1970年01月01日08时00分01秒。

请看一个显示日期时间的例子:

1
2
3
4
5
6
7
8
9
import java.util.Date;
public class Demo{
public static void main(String args[]){
Date da=new Date(); //创建时间对象
System.out.println(da); //显示时间和日期
long msec=da.getTime();
System.out.println("从1970年1月1日0时到现在共有:" + msec + "毫秒");
}
}

运行结果:

1
2
Mon Feb 05 22:50:05 CST 2007
从1970年1月1日0时到现在共有:1170687005390 毫秒

一些比较常用的 Date 类方法:

方法 功能
boolean after(Date date) 若调用 Date 对象所包含的日期比 date 指定的对象所包含的日期晚,返回 true,否则返回 false。
boolean before(Date date) 若调用 Date 对象所包含的日期比 date 指定的对象所包含的日期早,返回 true,否则返回 false。
Object clone() 复制调用 Date 对象。
int compareTo(Date date) 比较调用对象所包含的日期和指定的对象包含的日期,若相等返回 0;若前者比后者早,返回负值;否则返回正值。
long getTime() 以毫秒数返回从 1970 年 01 月 01 日 00 时到目前的时间。
int hashCode() 返回调用对象的散列值。
void setTime(long time) 根据 time 的值,设置时间和日期。time 值从 1970 年 01 月 01 日 00 时开始计算。
String toString() 把调用的 Date 对象转换成字符串并返回结果。
public Static String valueOf(type variable) 把 variable 转换为字符串。

Date 对象表示时间的默认顺序是星期、月、日、小时、分、秒、年。若需要修改时间显示的格式可以使用“SimpleDateFormat(String pattern)”方法。

例如,用不同的格式输出时间:

1
2
3
4
5
6
7
8
9
10
11
12
import java.util.Date;
import java.text.SimpleDateFormat;
public class Demo{
public static void main(String args[]){
Date da=new Date();
System.out.println(da);
SimpleDateFormat ma1=new SimpleDateFormat("yyyy 年 MM 月 dd 日 E 北京时间");
System.out.println(ma1.format(da));
SimpleDateFormat ma2=new SimpleDateFormat("北京时间:yyyy 年 MM 月 dd 日 HH 时 mm 分 ss 秒");
System.out.println(ma2.format(-1000));
}
}

运行结果:

1
2
3
Sun Jan 04 17:31:36 CST 2015
2015 年 01 月 04 日 星期日 北京时间
北京时间:1970 年 01 月 01 日 07 时 59 分 59 秒

3.2 Calendar 类

抽象类 Calendar 提供了一组方法,允许把以毫秒为单位的时间转换成一些有用的时间组成部分。Calendar 不能直接创建对象,但可以使用静态方法 getInstance() 获得代表当前日期的日历对象,如:

1
Calendar calendar=Calendar.getInstance();

该对象可以调用下面的方法将日历翻到指定的一个时间:

1
2
3
void set(int year,int month,int date);
void set(int year,int month,int date,int hour,int minute);
void set(int year,int month,int date,int hour,int minute,int second);

若要调用有关年份、月份、小时、星期等信息,可以通过调用下面的方法实现:

1
int get(int field);

其中,参数 field 的值由 Calendar 类的静态常量决定。其中:YEAR 代表年,MONTH 代表月,HOUR 代表小时,MINUTE 代表分,如:

1
calendar.get(Calendar.MONTH);

如果返回值为 0 代表当前日历是一月份,如果返回 1 代表二月份,依此类推。

由 Calendar 定义的一些常用方法如下表所示:

方法 功能
abstract void add(int which,int val) 将 val 加到 which 所指定的时间或者日期中,如果需要实现减的功能,可以加一个负数。which 必须是 Calendar 类定义的字段之一,如 Calendar.HOUR
boolean after(Object calendarObj) 如果调用 Calendar 对象所包含的日期比 calendarObj 指定的对象所包含的日期晚,返回 true,否则返回 false
boolean before(Object calendarObj) 如果调用 Calendar 对象所包含的日期比 calendarObj 指定的对象所包含的日期早,返回 true,否则返回 false
final void clear() 对调用对象包含的所有时间组成部分清零
final void clear(int which) 对调用对象包含的 which 所指定的时间组成部分清零
boolean equals(Object calendarObj) 如果调用 Calendar 对象所包含的日期和 calendarObj 指定的对象所包含的日期相等,返回 true,否则返回 false
int get(int calendarField) 返回调用 Calendar 对象的一个时间组成部分的值,这个组成部分由 calendarField指定,可以被返回的组成部分如:Calendar.YEAR,Calendar.MONTH 等
static Calendar getInstance() 返回使用默认地域和时区的一个 Calendar 对象
final Date getTime() 返回一个和调用对象时间相等的 Date 对象
final boolean isSet(int which) 如果调用对象所包含的 which 指定的时间部分被设置了,返回 true,否则返回 false
final void set(int year,int month) 设置调用对象的各种日期和时间部分
final void setTime(Date d) 从 Date 对象 d 中获得日期和时间部分
void setTimeZone(TimeZone t) 设置调用对象的时区为 t 指定的那个时区

3.3 GregorianCalendar 类

GregorianCalendar 是一个具体实现 Calendar 类的类,该类实现了公历日历。Calendar 类的 getInstance() 方法返回一个 GregorianCalendar,它被初始化为默认的地域和时区下的当前日期和时间。

GregorianCalendar 类定义了两个字段:AD 和 BC,分别代表公元前和公元后。其默认的构造方法 GregorianCalendar() 以默认的地域和时区的当前日期和时间初始化对象,另外也可以指定地域和时区来建立一个 GregorianCalendar 对象,例如:

1
2
3
GregorianCalendar(Locale locale);
GregorianCalendar(TimeZone timeZone);
GregorianCalendar(TimeZone timeZone,Locale locale);

GregorianCalendar 类提供了 Calendar 类中所有的抽象方法的实现,同时还提供了一些附加的方法,其中用来判断闰年的方法为:

1
Boolean isLeapYear(int year);

如果 year 是闰年,该方法返回 true,否则返回 false。

四、哈希表及其应用

哈希表也称为散列表,是用来存储群体对象的集合类结构。

4.1 什么是哈希表

数组和向量都可以存储对象,但对象的存储位置是随机的,也就是说对象本身与其存储位置之间没有必然的联系。当要查找一个对象时,只能以某种顺序(如顺序查找或二分查找)与各个元素进行比较,当数组或向量中的元素数量很多时,查找的效率会明显的降低。

一种有效的存储方式,是不与其他元素进行比较,一次存取便能得到所需要的记录。这就需要在对象的存储位置和对象的关键属性(设为 k)之间建立一个特定的对应关系(设为 f),使每个对象与一个唯一的存储位置相对应。在查找时,只要根据待查对象的关键属性 k 计算f(k)的值即可。如果此对象在集合中,则必定在存储位置 f(k)上,因此不需要与集合中的其他元素进行比较。称这种对应关系 f 为哈希(hash)方法,按照这种思想建立的表为哈希表。

Java 使用哈希表类(Hashtable)来实现哈希表,以下是与哈希表相关的一些概念:

  • 容量(Capacity):Hashtable 的容量不是固定的,随对象的加入其容量也可以自动增长。
  • 关键字(Key):每个存储的对象都需要有一个关键字,key 可以是对象本身,也可以是对象的一部分(如某个属性)。要求在一个 Hashtable 中的所有关键字都是唯一的。
  • 哈希码(Hash Code):若要将对象存储到 Hashtable 上,就需要将其关键字 key 映射到一个整型数据,成为 key 的哈希码。
  • 项(Item):Hashtable 中的每一项都有两个域,分别是关键字域 key 和值域 value(存储的对象)。Key 和 value 都可以是任意的 Object 类型的对象,但不能为空。
  • 装填因子(Load Factor):装填因子表示为哈希表的装满程度,其值等于元素数比上哈希表的长度。

4.2 哈希表的使用

哈希表类主要有三种形式的构造方法:

  • Hashtable(); //默认构造函数,初始容量为 101,最大填充因子 0.75
  • Hashtable(int capacity);
  • Hashtable(int capacity,float loadFactor)

哈希表类的主要方法如下表所示。

方法 功能
void clear() 重新设置并清空哈希表
boolean contains(Object value) 确定哈希表内是否包含了给定的对象,若有返回 true,否则返回 false
boolean containsKey(Object key) 确定哈希表内是否包含了给定的关键字,若有返回 true,否则返回 false
boolean isEmpty() 确认哈希表是否为空,若是返回 true,否则返回 false
Object get(Object key) 获取对应关键字的对象,若不存在返回 null
void rehash() 再哈希,扩充哈希表使之可以保存更多的元素,当哈希表达到饱和时,系统自动调用此方法
Object put(Object key,Object value) 用给定的关键字把对象保存到哈希表中,此处的关键字和元素均不可为空
Object remove(Object key) 从哈希表中删除与给定关键字相对应的对象,若该对象不存在返回 null
int size() 返回哈希表的大小
String toString() 将哈希表内容转换为字符串

哈希表的创建也可以通过 new 操作符实现。其语句为:

1
HashTable has=new HashTable();

哈希表的遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//*** ep8_12.java **********
import java.util.*;
class Demo{
public static void main(String args[]){
Hashtable has=new Hashtable();
has.put("one",new Integer(1));
has.put("two",new Integer(2));
has.put("three",new Integer(3));
has.put("four",new Double(12.3));
Set s=has.keySet();
for(Iterator<String> i=s.iterator();i.hasNext();){
System.out.println(has.get(i.next()));
}
}
}


应统联盟


连接十万名应统专业同学


阿药算法


打通算法面试任督二脉