1、第第7章章 惯用实用类惯用实用类n1.Date类n2.Calendar类n3.Math类与Biglnteger类n4.LinkedList泛型类n5.HashSet泛型类n6.HashMap泛型类n7.TreeSet泛型类n8.TreeMap泛型类n9.Stack泛型类第1页7.1 Date7.1 Date类类 1Date对象 Date类在java.util包中。使用Date类无参数结构方法创建对象能够获取当地当前时间。用Date结构方法Date(long time)创建Date对象表示相对1970年1月1日0点(GMT)时间,比如参数time取值60*60*1000秒表示Thu Jan 01
2、 01:00:00 GMT 1970。能够用System类静态方法 public long第2页 currentTimeMillis()获取系统当前时间,这个时间是从1970.年1月1日0点(GMT)到当前时刻所走过毫秒数(这是一个不小数)。能够依据currentTimeMillis()方法得到数字,用Date结构方法Date(long time)来创建一个当地日期Date对象。2格式化时间 Date对象表示时间默认次序是:星期、月、日、小时、分、秒、年。比如:Sat Apr 28 21:59:38 CST。我们可能希望按着某种习惯来输出时间,比如时间序:年 月 星期 日或年 月 星期 日 小
3、时 分 秒。第3页这时能够使用DateFormat子类SimpleDateFormat来实现日期格式化。SimpleDateFormat有一个惯用结构方法:public SimpleDateFormat(String pattern)。该结构方法能够用参数pattern指定格式创建一个对象,该对象调用:format(Date date)方法格式化时间对象date。第4页需要注意是,pattern中应该含有一些有效字符序列。比如:ly或yy 表示用2位数字输出年份;yyyy表示用4位数字输出年份。lM 或MM 表示用2为数字或文本输出月份,假如想用汉字输出月份,pattern中应连续包含最少3个
4、M,如:MMM。ld 或dd 表示用2位数字输出日。lH或HH 表示用两位数字输出小时。lm或mm 表示用两位数字输出分。ls或ss 表示用两位数字输出秒。l E 表示用字符串输出星期。第5页n 在下面例子1中,我们用三种格式输出时间。n 上述程序输出结果:n 现在时间:Thu Sep 02 09:33:55 CST n 现在时间:time:-09-02n goodTime:-09月-星期四02日-09:时33:分55:秒 北京时间 现在时间:北京时间02日09时九月 55秒33分星期四-3600秒表示日期时间是:Thu Jan 01 07:59:56 CST 1970n-1800秒表示日期时
5、间是:Thu Jan 01 07:59:58 CST 1970n 返回第6页7.2 Calendar7.2 Calendar类类 Calendar类在java.util包中。使用Calendar类static方法getInstance()能够初始化一个日历对象,如:Calendar calendar=Calendar.getInstance();然后,calendar对象能够调用方法:public final void set(int year,int month,int date)public final void set(int year,int month,int date,int ho
6、ur,int minute)public final void set(int year,int month,int date,int hour,int minute,int second)第7页将日历翻到任何一个时间,当参数year取负数时表示公元前。calendar对象调用方法:public int get(int field)能够获取相关年份、月份、小时、星期等信息,参数field有效值由Calendar静态常量指定,比如:calendar.get(Calendar.MONTH);返回一个整数,假如该整数是0表示当前日历是在一月,该整数是1表示当前日历是在二月等。第8页n 日历对象调用n
7、 public long getTimeInMillis()n 能够将时间表示为毫秒。n 下面例子2使用Calendar来表示时间。并计算了年和1949年之间相隔天数。n 上述程序输出结果:n 现在时间是:n 9月2日 星期4n 9时38分30秒n 年10月1日和1949年10月1日相隔20454天n 下面例子3输出年10月日历页。返回第9页7.3 Math7.3 Math类与类与BigIntegerBigInteger类类 1Math类在编写程序时,可能需要计算一个数平方根、绝对值、获取一个随机数等等。java.lang包中类包含许多用来进行科学计算类方法,这些方法能够直接经过类名调用。另外
8、,Math类还有两个静态常量,E和PI,它们值分别是:2.7182828284590452354和 3.14159265358979323846。第10页以下是Math类惯用方法:lpublic static long abs(double a)返回a绝对值。lpublic static double max(double a,double b)返回a、b最大值。lpublic static double min(double a,double b)返回a、b最小值。lpublic static double random()产生一个0到1之间随机数(不包含0和1)。lpublic stati
9、c double pow(double a,double b)返回ab次幂。第11页l public static double sqrt(double a)返回a平方根。lpublic static double log(double a)返回a对数。lpublic static double sin(double a)返回正弦值。l public static double asin(double a)返回反正弦值。有时我们可能需要对输出数字结果进行必要格式化,比如,对于3.14356789,我们希望保留小数位为3位、整数部分最少要显示3位,即将3.14356789格式化为003.144。
10、能够使用java.text包中NumberFormat类,该类调用类方法:public static final NumberFormat getInstance()第12页l实例化一个NumberFormat对象,该对象调用l public final String format(double number)l方法能够格式化数字number。l NumberFormat类有以下惯用方法:lpublic void setMaximumFractionDigits(int newValue)lpublic void setMinimumFractionDigits(int newValue)lp
11、ublic void setMaximumIntegerDigits(int newValue)l public void setMinimumIntegerDigits(int newValue)第13页在下面例子4中我们用一定格式输出5平方根,经过一个20次循环,每次获取1到8之间一个随机数。2BigInteger类程序有时需要处理大整数,java.math包中BigInteger类提供任意精度整数运算。能够使用结构方法:publicBigInteger(Stringval)结构一个十进制BigInteger对象。该结构方法能够发生NumberFormatException异常,也就是说,
12、字符串参数val中假如含有非数字字母就会发生NumberFormatException异常。第14页 以下是BigInteger类惯用方法:public BigInteger add(BigInteger val)返回当前大整数对象与参数指定大整数对象和。public BigInteger subtract(BigInteger val)返回当前大整数对象与参数指定大整数对象差。public BigInteger multiply(BigInteger val)返回当前大整数对象与参数指定大整数对象积。public BigInteger divide(BigInteger val)返回当前大整
13、数对象与参数指定大整数对象商。第15页 public BigInteger remainder(BigInteger val)返回当前大整数对象与参数指定大整数对象余。public int compareTo(BigInteger val)返回当前大整数对象与参数指定大整数比较结果,返回值是1、-1或0,分别表示当前大整数对象大于、小于或等于参数指定大整数。public BigInteger abs()返回当前大整数对象绝对值。public BigInteger pow(int exponent)返回当前大整数对象exponent次幂。第16页 public String toString()
14、返回当前大整数对象十进制字符串表示。public String toString(int p)返回当前大整数对象p进制字符串表示。在下面例子5中,计算了2个大整数和、差、积和商,并计算出了一个大整数因子个数(因子中不包含1和大整数本身)。返回第17页7.4 LinkedList泛型类 使用LinkedList泛型类能够创建链表结构数据对象。链表是由若干个节点组成一个数据结构,每个节点含有一个数据和下一个节点引用(单链表),或含有一个数据并含有上一个节点引用和下一个节点引用(双链表),节点索引从0开始。链表适合动态地改变它存放数据,如,增加、删除节点等。第18页 1LinkedList对象 ja
15、va.util 包中LinkedList泛型类创建对象以链表结构存放数据,习惯上称LinkedList类创建对象为链表对象。比如,LinkedList mylist=new LinkedList();创建一个空双链表。然后mylist能够使用add(String obj)方法向链表依次增加节点,节点中数据是参数obj指定对象引用。第19页比如:mylist.add(“How”);mylist.add(“Are”);mylist.add(“You”);mylist.add(“Java”);这时,双链表mylist就有了有个节点,节点是自动连接在一起,不需要我们去做连接,也就是说,不需要我们去操作
16、安排节点中所存放下一个或上一个节点引用。第20页 2惯用方法以下是LinkedList泛型类一些惯用方法。public boolean add(E element)向链表末尾添加一个新节点,该节点中数据是参数elememt指定对象。public void add(int index,E element)向链表指定位置添加一个新节点,该节点中数据是参数elememt指定对象。public void addFirst(E element)向链表头添加新节点,该节点中数据是参数elememt指定对象。第21页 public E removeFirst()删除第一个节点,并返回这个节点中对象。publ
17、ic E removeLast()删除最终一个节点对象,并返回这个节点中对象。public E get(int index)得到链表中指定位置处节点中对象。public E getFirst()得到链表中第一个节点中对象。public E getLast()得到链表中最终一个节点中对象。public int indexOf(E element)返回含有数据element节点在链表中首次出现位置,假如链表中无此节点则返回-1。第22页 public int lastIndexOf(E element)返回含有数据element节点在链表中最终出现位置,假如链表中无此节点则返回-1。public
18、E set(int index,E element)将当前链表index位置节点中对象element替换为参数element指定对象。并返回被替换对象。public int size()返回链表长度,即节点个数。public boolean contains(Object element)判断链表节点中是否有节点含有对象element。第23页 public Object clone()得到当前链表一个克隆链表,该克隆链表中节点数据改变不会影响到当前链表中节点数据,反之亦然。下述例子6使用了上述一些方法。3遍历链表例子6借助get方法实现了遍历链表。我们能够借助泛型类Iterator实现遍历链
19、表,一个链表对象能够使用iterator()方法返回一个Iterator类型对象,假如链表是“Student类型”链表,即链表节点中数据是Student类创建对象,那么该链表使用iterator()方法返回一个Iterator类型对象,该对象使用next()方法遍历链表。在下面例子7中,我们把学生成绩存放在一个链表中,并实现了遍历链表。第24页 4LinkedList泛型类实现接口 LinkedList泛型类实现了泛型接口List,而List接口由是Collection接口子接口。LinkedList类中绝大部分方法都是接口方法实现。编程时,能够使用接口回调技术,即把LinkedList对象引
20、用赋值给Collection接口变量或List接口变量,那么接口就能够调用类实现接口方法。第25页5SDK1.5之前LinkedList类 JDK1.5之 前 没 有 泛 型 LinkedList类,能 够 用 普 通 LinkedList创建一个链表对象,比如:LinkedList mylist=new LinkedList();创建了一个空双链表。然后mylist链表能够使用add(Object obj)方法向这个链表依次添加节点。因为任何类都是Object类子类,所以能够把任何一个对象作为链表节点中对象。第26页需要注意是当使用get()获取一个节点中对象,要用类型转换运算符转换回原来类
21、型。Java泛型主要目标是能够建立含有类型安全集合框架,如链表、散列表等数据结构,最主要一个优点就是:在使用这些泛型类建立数据结构时,无须进行强制类型转换,即不要求进行运行时类型检验。SDK1.5是支持泛型编译器,它将运行时类型检验提前到编译时执行,使代码更安全。假如你使用旧版本LinkedList类,1.5编译器会给出警告信息,但程序仍能正确运行。下面是使用旧版本LinkedList例子。返回第27页7.5 HashSet泛型类 HashSet泛型类在数据组织上类似数学上集合,能够进行“交”、“并”、“差”等运算。1HashSet对象 HashSet泛型类创建对象称作集合,比如 HashSe
22、t set=HashSet();那么,set就是一个能够存放String类型数据集合,set能够调用add(String s)方法将String类型数据添加 到集合中,添加到集合中数据称做集合元素。第28页集合不允许有相同元素,也就是说,假如b已经是集合中元素,那么再执行set.add(b)操作是无效。集合对象初始容量是16个字节,装载因子是0.75,也就是说,假如集合添加元素超出总容量75%时,集合容量将增加一倍。2惯用方法publicbooleanadd(Eo)向集合添加参数指定元素。publicvoidclear()清空集合,使集合不含有任何元素。publicbooleancontain
23、s(Objecto)判断参数指定数据是否属于集合。publicbooleanisEmpty()判断集合是否为空。第29页 public boolean remove(Object o)集合删除参数指定元素。public int size()返回集合中元素个数。Object toArray()将集合元素存放到数组中,并返回这个数组。boolean containsAll(HanshSet set)判断当前集合是否包含参数指定集合。public Object clone()得到当前集合一个克隆对象,该对象中元素改变不会影响到当前集合中元素,反之亦然。第30页3集合交、并与差集合对象调用boolea
24、n addAll(HashSet set)方法能够和参数指定集合求并运算,使得当前集合成为两个集合并。集合对象调用boolean boolean retainAll(HashSet set)方法能够和参数指定集合求交运算,使得当前集合成为两个集合交。集合对象调用boolean boolean boolean removeAll(HashSet set)方法能够和参数指定集合求差运算,使得当前集合成为两个集合差参数指定集合必须和当前集合是同种类型集合,不然上述方法返回false。第31页 下面例子10求2个集合A、B对称差集合,即求。上述程序运行结果:A和B对称差集合有4个元素:4,6,3,5,
25、4HashSet泛型类实现接口 HashSet泛型类实现了泛型接口Set,而Set接 口 由 是 Collection接 口 子 接 口。HashSet类中绝大部分方法都是接口方法实现。编程时,能够使用接口回调技术,即把HashSet对象引用赋值给Collection接口变量或Set接口变量,那么接口就能够调用类实现接口方法。返回第32页7.6 HashMap泛型类 HashMap也是一个很实用类,HashMap对象采取散列表这种数据结构存放数据,习惯上称HashMap对象为散列映射对象。散列映射用于存放键/值数据对,允许把任何数量键/值数据对存放在一起。键不能够发生逻辑冲突,即不要两个数据项
26、使用相同键,假如出现两个数据项对应相同键,那么,先前散列映射中键/值对将被替换。散列映射在它需要更多存放空间时会自动增大容量。第33页比如,假如散列映射装载因子是0.75,那么当散列映射容量被使用了75%时,它就把容量增加到原始容量倍。对于数组和链表这两种数据结构,假如要查找它们存放某个特定元素却不知道它位置,就需要从头开始访问元素直到找到匹配为止;假如数据结构中包含很多元素,就会浪费时间。这时最好使用散列映射来存放要查找数据,使用散列映射能够降低检索开销。第34页 1HashMap对象 HashMap泛型类创建对象称作散列映射,比如:HashMap hashtable=HashMap();那
27、么,hashtable就能够存放“键/值”对数据,其中键必须是一个String对象,键对应值必须是Student对象。hashtable能够调用public V put(K key,V value)将键/值对数据存放到散列映射中,该方法同时返回键所对应值。第35页 2惯用方法 public void clear()清空散列映射。public Object clone()返回当前散列映射一个克隆。public boolean containsKey(Object key)假如散列映射有键/值对使用了参数指定键,方法返回true,不然返回false。publicbooleancontainsVal
28、ue(Objectvalue)假如散列映射有键/值正确值是参数指定值,方法返回true,不然返回false。第36页 public V get(Object key)返回散列映射中使用key做键键/值对中值。public boolean isEmpty()假如散列映射不含任何键/值对,方法返回true,不然返回false。public V remove(Object key)删除散列映射中键为参数指定键/值对,并返回键对应值。public int size()返回散列映射大小,即散列映射中键/值正确数目。第37页 3遍历散列映射假如想取得散列映射中全部键/值对中值,首先使用publicColl
29、ectionvalues()方法返回一个实现Collection接口类创建对象引用,并要求将该对象引用返回到Collection接口变量中。values()方法返回对象中存放了散列映射中全部“键/值”对中“值”,这么接口变量就能够调用类实现方法,比如获取Iterator对象,然后输出全部值。下面例子11使用了散列映射惯用方法,并遍历了散列映射。第38页 4HashMap泛型类实现接口 HashMap泛型类实现了泛型接口Map,HashMap类中绝大部分方法都是Map接口方法实现。编程时,能够使用接口回调技术,即把HashMap对象引用赋值给Map接口变量,那么接口就能够调用类实现接口方法。返回
30、第39页7.7 TreeSet泛型类 TreeSet 类是实现Set接口类,它大部分方法都是接口方法实现。TreeSet 泛型类创建对象称作树集,比如 TreeSet tree=TreeSet();那么,tree就是一个能够存放Student类型数据集合,tree能够调用add(String s)方法将Student类型数据添加到树集中,存放到树集中对象按对象串表示升序排列。以下是TreeSet 类惯用方法:第40页 public boolean add(E o)向树集添加加对象,添加成功返回true,不然返回false。public void clear()删除树集中全部对象。public
31、void contains(Object o)假如包含对象o方法返回true,不然返回false。public E first()返回树集中第一个对象(最小对象)。public E last()返回最终一个对象(最大对象)。第41页 public isEmpty()判断是否是空树集,假如树集不含对象返回true。public boolean remove(Object o)删除树集中对象o。public int size()返回树集中对象数目。但很多对象不适合按着字符串排列大小。对象调用toString()方法就能够取得自己字符串表示,比如一个文本框(TextField)字符串表示是:java
32、.awt.TextFieldtextfield0,0,0,0 x0,invalid,text=,editable,selection=0-0假如让文本框按着字符串来比较大小似乎无任何意义。第42页我们在创建树集时可自己要求树集中对象按着什么样“大小”次序排列。假如我们有四个学生对象,他们有姓名和成绩,我们想把这四个对象添加到树集中,并按着成绩高低排列,而不是按着姓名字典序排列节点。首先创建学生Student类能够实现接口:Comparable。Comparable接口中有一个方法:publicintcompareTo(Objectb);Student类经过实现这个接口来要求它创建对象大小关系,
33、以下所表示:第43页class Student implements Comparable int english=0;String name;Student(int e,String n)english=e;name=n;public int compareTo(Object b)Student st=(Student)b;return(this.english-st.english);第44页 Comparator是java.util包中一个接口,compare是接口中方法,所以匿名类方法体必须实现接口中方法(相关匿名类可参见第5章,13节)。当mytree每次添加对象时,都会再调用接口中
34、方法实现对象大小相互比较,mytree调用接口方法过程对编程人员是不可见,Sun企业在编写开发TreeSet类时已经实现了这一机制。下面例子12把Student对象添加到树集中,并按着成绩高低排列。第45页注:树集中不允许出现大小相等两个节点,比如,在上述例子中假如再添加语句 s t5=new Student(76,keng wenyi);mytree.add(st5);是无效。假如允许成绩相同,可把上述例子中Student类中compareTo方法更改为:返回第46页7.8 TreeMap泛型类 TreeMap类实现了Map接口。TreeMap提供了按排序次序存放“关键字/值”正确有效伎俩。
35、应该注意是,不像散列映射(HashMap),树映射(TreeMap)确保它元素按照关键字升序排列。下面是TreeMap结构函数:TreeMap()TreeMap(comparator comp)第47页第一个形式结构树映射,按关键字大小次序来排序树映射中“关键字/值”对,关键字大小次序是按其字符串表示字典次序。第二种形式结构树映射,关键字大小次序按comp接口要求大小次序,树映射按关键字大小次序来排序树映射中“关键字/值”对。TreeMap类惯用方法与HashMap类相同。下面例子13使用了TreeMap,分别按着学生身高和体重排序对象。返回第48页7.9 Stack泛型类 堆栈是一个“后进先
36、出”数据结构,只能在一端进行输入或输出数据操作。堆栈把第一个放入该堆栈数据放在最底下,而把后续放入数据放在已经有数据顶上,如图7.6所表示。数据数据数据数据新数据输出数据压栈弹栈图7.6堆栈结构示意图第49页向堆栈中输入数据操作称为“压栈”,从栈中输出数据操作称为“弹栈”。因为堆栈总是在顶端进行数据输入输出操作,所以弹栈总是输出(删除)最终压入堆栈中数据,这就是“后进先出”来历。使用java.util包中Stack类创建一个堆栈对象,堆栈对象能够使用 public E push(E item);输入数据,实现压栈操作。使用 public E pop();第50页输出数据,实现弹栈操作。使用 p
37、ublic boolean empty();判断堆栈是否还有数据,有数据返回false,不然返回true。使用 public E peek();获取堆栈顶端数据,但不删除该数据。使用 public int search(Object data);获取数据在堆栈中位置,最顶端位置是,向下依次增加,假如堆栈不含此数据,则返回-1。第51页堆栈是很灵活数据结构,使用堆栈能够节约内存开销。比如,递归是一个很消耗内存算法,我们能够借助堆栈消除大部分递归,到达和递归算法一样目标。Fibonacci整数序列是我们熟悉一个递归序列,它第n项是前两项和,第一项和第二项是。下面例子14用堆栈输出该递归序列若干项。返回第52页