1、第第7章章 常用实用类常用实用类n Date类和Calendar类n Math类与Biglnteger类n数字格式化n LinkedList泛型类n HashSet泛型类n HashMap泛型类n TreeSet泛型类n TreeMap泛型类n Stack泛型类17.1 Date7.1 Date类类 1Date对象Date类在java.util包中。使用Date类的无参数构造方法创建的对象可以获取本地当前时间。用Date的构造方法Date(long time)创建的Date对象表示相对1970年1月1日0点(GMT)的时间,如参数time取值60601000秒,表示Thu Jan 01 01:
2、00:00 GMT 1970。System类的静态方法 public long currentTimeMillis()可以获取系统当前时间,这个时间是从1970年1月1日0点(GMT)到目前时刻所走过的毫秒数(这是一个不小的数)。可以根据currentTimeMillis()方法方法得到的数字,用Date的构造方法Date(long time)来创建一个本地日期的Date对象。2 2格式化时间 Date对象表示时间的默认顺序是:星期、月、日、小时、分、秒、年,如 Sat Apr 28 21:59:38 CST 2001 可以使用DateFormat的子类SimpleDateFormat来实现日
3、期的格式化。SimpleDateFormat有一个常用构造方法:public SimpleDateFormat(String pattern)该构造方法可以用参数pattern指定的格式创建一个对象sdf,sdf调用 public String format(Date date)方法格式化时间参数date指定的时间对象,format方法将根据创建sdf对象时所使用的参数pattern返回一个字符串对象 formatTime:String formatTime=sdf.format(new Date();需要注意的是,当使用SimpleDateFormatSimpleDateFormat(Str
4、ing pattern)(String pattern)构造对象sdf时,参数pattern中应当含有“时间元字符”,例如,对于:pattern=yyyy-mm-dd,如果当前机器的时间是2008年8月12日,那么sdfsdf.format(new Date().format(new Date()返回的字符串就是2008-08-12,也就是说sdfsdf.format(new Date().format(new Date()返回的字符串就是将pattern中的时间元字符:yyyy,mm和dd替换相应的时间数据之后的一个字符串。3常用时间元字符:y,yy:2位数字年份,如98。yyyy:4位数字
5、年份,如2008。M,MM:2位数字月份,如08MMM:汉字月份,如八月。d,dd:2位数字日期,如09、22。a:上午或下午。H,HH:2位数字小时(00-23)。h,,hh:2位数字小时(am/pm,01-12)m,mm:2位数字分。s,ss:2位数字秒。E,EE:星期。例7-1中,用3种格式输出时间。47.2 Calendar7.2 Calendar类类 Calendar类在java.util包中。Calendar类的static方法getInstancegetInstance()()可以初始化一个日历对象,如如 Calendar calendar=Calendar.getInstanc
6、eCalendar 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 hour,int minute)public final void set(int year,int month,int date,int hour,int minute,int second)将日历翻到任何一个时间,当参数year取负数时表示公元前。publi
7、c int get(int field)可以获取有关年份、月份、小时、星期等信息,参数field的有效值由Calendar的静态常量指定。例如,例如,calendar.get(Calendar.MONTH);calendar.get(Calendar.MONTH);返回一个整数(0表示当前日历是在一月,1表示当前日历是在二月等)。日历对象调用 public long getTimeInMillis()可以将时间表示为毫秒。例7-2使用Calendar来表示时间,并计算了1931年9月18日和1945年8月15日之间相隔的天数。效果图 例7-3输出1931年9月的日历(效果如图7.1所示)。5例
8、子7-2,例子7-3效果图例子7-2效果图67.3 Math7.3 Math类与类与BigIntegerBigInteger类类 1Math类类 java.lang包中的类包含许多用来进行科学计算的类方法,这些方法可以直接通过类名调用。Math类还有两个静态常量:E和PI,它们的值分别是2.7182828284590452354和3.14159265358979323846。7Math类的常用方法:public static long abs(double a)返回a的绝对值。public static double max(double a,double b)返回a、b的最大值。public
9、 static double min(double a,double b)返回a、b的最小值。public static double random()产生一个0到1之间的随机数(不包括0和1)。public static double pow(double a,double b)返回a的b次幂。public static double sqrt(double a)返回a的平方根。public static double log(double a)返回a的对数。public static double sin(double a)返回正弦值。public static double asin(d
10、ouble a)返回反正弦值8对数字格式化-NumberFormat类 java.text包中的NumberFormat类,该类调用类方法 public static final NumberFormat getInstance()实例化一个NumberFormat对象,该对象调用 public final String format(double number)方法可以格式化数字number。NumberFormat类有如下常用方法:public void setMaximumFractionDigits(int newValue)public void setMinimumFraction
11、Digits(int newValue)public void setMaximumIntegerDigits(int newValue)public void setMinimumIntegerDigits(int newValue)例7-4用一定的格式输出10的平方根,通过一个20次的循环,每次获取18之间的一个随机数(效果如图7.2所示)。例7-5使用自己编写的MyNumberFormat类中的方法格式化10的平方根(效果如图7.3所示)。9例子7-4,例子7-5效果图102BigInteger类 java.math包中的BigInteger类提供任意精度的整数运算。可以使用构造方法 p
12、ublic BigInteger(String val)构造一个十进制的BigInteger对象。该构造方法可以发生NumberFormatException异常。也就是说,字符串参数val中如果含有非数字字母就会发生NumberFormatException异常.11BigInteger类的常用方法public BigInteger add(BigInteger val)返回当前大整数对象与参数指定的大整数对象的和。public BigInteger subtract(BigInteger val)返回当前大整数对象与参数指定的大整数对象的差。public BigInteger multip
13、ly(BigInteger val)返回当前大整数对象与参数指定的大整数对象的积。public BigInteger divide(BigInteger val)返回当前大整数对象与参数指定的大整数对象的商。public BigInteger remainder(BigInteger val)返回当前大整数对象与参数指定的大整数对象的余。public int compareTo(BigInteger val)返回当前大整数对象与参数指定的大整数的比较结果,返回值是1、-1或0,分别表示当前大整数对象大于、小于或等于参数指定的大整数。public BigInteger abs()返回当前大整数对
14、象的绝对值。public BigInteger pow(int exponent)返回当前大整数对象的exponent次幂。public String toString()返回当前大整数对象十进制的字符串表示。public String toString(int p)返回当前大整数对象p进制的字符串表示。例7-6计算了2个大整数的和、差、积和商,并计算出了一个大整数的因子个数。12例子7-6效果图137.4 数字格式化 所谓数字格式化,就是按着指定格式得到一个字符串。例如,希望3.141592最多保留2位小数,那么得到的格式化字符串应当是3.14;希望整数1234789按“千”分组,那么得到的
15、格式化字符串应当是1,234,789;数字59.88887的小数保留3位小数、整数部分至少要显示3位,那么得到的格式化字符串应当是059.889。141Formatter类 Formatter类提供了一个和C语言printf函数类似的format方法:format(格式化模式,值列表格式化模式,值列表)该方法按着“格式化模式格式化模式”返回“值列表值列表”的字符串表示。1)格式化模式格式化模式:用双引号括起的字符序列(字符串),该字符序列中的字符由格式符和普通字符所构成。例如:输出结果%d,%f,%d中的%d和%f是格式符号;开始的4个汉字、中间的两个逗号是普通字符。格式符将被替换。例如:St
16、ring s=String.format(%.2f,3.141592);那么s就是3.14。2)值列表值列表:是用逗号分隔的变量、常量或表达式。要保证format方法“格式化模式”中的格式符的个数与“值列表”中列出的值的个数相同。例如:String s=format(%d元元%0.3f公斤公斤%d台台,888,999.777666,123);那么s就是:888元999.778公斤123台。3)格式化顺序格式化顺序:format方法默认按从左到右的顺序使用“格式化模式”中的格式符来格式化“值列表”中对应的值,而“格式化模式”中的普通字符保留原样。例如,假设int型变量x和double型变量的值分
17、别是888和3.1415926,那么对于 String s=format(从左向右:从左向右:%d,%.3f,%d,x,y,100);字符串s就是:从左向右:888,3.142,100152格式化整数 1)%d,%o,%x和和%X可格式化byte、Byte、short、Short、int、Integer、long和Long型数据,如,String s=String.format(%d,%o,%x,%X,703576,703576,703576,703576);字符串s就是:703576,2536130,abc58,ABC582)修饰符)修饰符:加号修饰符加号修饰符“+”,逗号修饰符逗号修饰符“
18、,”如 String s=String.format(按千分组按千分组:%,d。按千分组带正号。按千分组带正号%+,d,1235678,9876);字符串s就是:按千分组:1,235,678。按千分组带正号+9,8763)数据的宽度)数据的宽度:%md,或%-md,String s=String.format(%8d,59);字符串s就是:59,其长度(s.length())为8,s在59左面添加了6个空格字符。注:如果实际数字的宽度大于格式中指定的宽度,就按数字的实际宽度进行格式化。可以在宽度的前面增加前缀0,表示用数字0来填充宽度左面的富裕部分,如:String s=String.form
19、at(%08d,12);字符串s就是:00000012,其长度(s.length())为8,即s在12的左面添加了6个数字0。163格式化浮点数 1)%f,%e(%E),),%g(%G)和)和%a(%A)可格式化float、Float、double和Double,如:如:String s=String.format(%f,%e,13579.98,13579.98);字符串s就是13579.980000,1.357998e+042)修饰)修饰:加号修饰符加号修饰符“+”,逗号修饰符,逗号修饰符“,”如:如:String s=String.format(整数部分按千分组整数部分按千分组:%,f。按
20、千分组带正。按千分组带正%+,f,1235678.9876);字符串s就是整数部分按千分组:+1,235,678.9876003)限制小数位数与数据的)限制小数位数与数据的“宽度宽度”%.nf n是保留的小数位数,如如%.3f将将6.1256格式化为格式化为3.126(保留保留3位小数位小数)。%mf,%-md规定宽度(在数字的左,右面增加空格)如:如:String s=String.format(%11f,59.88);字符串s就是 59.880000,s在数字左面添加了2个空格字符.%m.n 指定宽度的同时也可以限制小数位数,如:如:String s=String.format(%11.2
21、f,59.88);字符串s就是:59.88,即s在59.88左面添加了6个空格字符。例7-7格式化数字,运行效果如图7.4。17例子7-7效果图187.5 LinkedList泛型类 使用LinkedList泛型类可以创建链表结构的数据对象。链表是由若干个节点组成的一种数据结构,每个节点含有一个数据和下一个节点的引用(单链表),或含有一个数据以及上一个节点的引用和下一个节点的引用(双链表),节点的索引从0开始。链表适合动态改变它存储的数据,如增加、删除节点等。19 1LinkedList对象 java.util包中的LinkedList泛型类创建的对象以链表结构存储数据,习惯上称LinkedL
22、ist类创建的对象为链表对象。例如,LinkedList mylist=new LinkedListLinkedList mylist=new LinkedList();();创建一个空双链表。然后mylist可以使用add(String objadd(String obj)方法方法向链表依次增加节点,节点中的数据是参数obj指定对象的引用,如mylist.add(How);mylist.add(How);mylist.add(Are);mylist.add(Are);mylist.add(You);mylist.add(You);mylistmylist.add(Java);.add(Jav
23、a);这时,双链表mylist就有了有个节点,节点是自动连接在一起的,不需要我们去做连接。也就是说,不需要我们去操作安排节点中所存放的下一个或上一个节点的引用。20 2常用方法-1*public boolean add(E element)向链表末尾添加一个新的节点,该节点中的数据是参数elememt指定的对象。*public void add(int index,E element)向链表的指定位置添加一个新的节点,该节点中的数据是参数elememt指定的对象。*public void addFirst(E element)向链表的头添加新节点,该节点中的数据是参数elememt指定的对象。
24、*public void addLast(E element)向链表的末尾添加新节点,该节点中的数据是参数elememt指定的对象。*public void clear()删除链表的所有节点,使当前链表成为空链表。*public E remove(int index)删除指定位置上的节点。*public boolean remove(E element)删除首次出现含有数据element的节点。*public E removeFirst()删除第一个节点,并返回这个节点中的对象。*public E removeLast()删除最后一个节点对象,并返回这个节点中的对象。*public E get
25、(int index)得到链表中指定位置处节点中的对象。*public E getFirst()得到链表中第一个节点中的对象。*public E getLast()得到链表中最后一个节点中的对象。21 2常用方法-2*public int indexOf(E element)返回含有数据element的节点在链表中首次出现的位置,如果链表中无此节点则返回-1。*public int lastIndexOf(E element)返回含有数据element的节点在链表中最后出现的位置,如果链表中无此节点则返回-1。*public E set(int index,E element)将当前链表ind
26、ex位置节点中的对象element替换为参数element指定的对象。并返回被替换的对象。*public int size()返回链表的长度,即节点的个数。*public boolean contains(Object element)判断链表节点中是否有节点含有对象element。*public Object clone()得到当前链表的一个克隆链表,该克隆链表中节点数据的改变不会影响到当前链表中节点的数据,反之亦然。例7-8使用了上述一些方法(效果如图7.5所示)。22例子7-8效果图233遍历链表 可以借助泛型类Iterator实现遍历链表,一个链表对象可以使用iterator()方法返
27、回一个Iterator类型的对象,该对象中每个数据成员刚好是链表节点中的数据,而且这些数据成员是按顺序存放在Iterator对象中的。Iterator对象使用next()方法可以得到它中的数据成员。显然,使用Iterator对象遍历链表要比链表直接使用get()方法遍历链表的速度快。例7-9中,我们把学生的成绩存放在一个链表中,并实现了遍历链表。244LinkedList泛型类实现的接口 LinkedList泛型类实现了泛型接口List,而List接口是Collection接口的子接口。LinkedList类中的绝大部分方法都是接口方法的实现。编程时,可以使用接口回调技术,即把LinkedLi
28、st对象的引用赋值给Collection接口变量或List接口变量,那么接口就可以调用类实现的接口方法。255JDK1.5之前的LinkedList类 JDK 1.5之前没有泛型的LinkedList类,可以用普通的LinkedList创建一个链表对象,如 LinkedList mylist=new LinkedList();创建了一个空双链表,然后mylist链表可以使用add(Object obj)方法向这个链表依次添加节点。由于任何类都是Object类的子类,因此可以把任何一个对象作为链表节点中的对象。需要注意的是,使用get()获取一个节点中的对象时,要用类型转换运算符转换回原来的类型
29、。Java泛型的主要目的是可以建立具有类型安全的集合框架,如链表、散列表等数据结构,最重要的一个优点就是:在使用这些泛型类建立的数据结构时,不必进行强制类型转换,即不要求进行运行时类型检查。JDK 1.5是支持泛型的编译器,它将运行时类型检查提前到编译时执行,使代码更安全。如果使用旧版本的LinkedList类,JDK 1.5编译器会给出警告信息,但程序仍能正确运行。下面是使用旧版本LinkedList的例子。例7-10267.6 HashSet泛型类 HashSet泛型类在数据组织上类似数学上的集合,可以进行“交”、“并”、“差”等运算。1HashSet对象对象HashSet泛型类创建的对象
30、称为集合,如HashSet set=HashSet();那么set就是一个可以存储String类型数据的集合,set可以调用add(String s)方法将String类型的数据添加到集合中,添加到集合中的数据称做集合的元素。集合不允许有相同的元素,也就是说,如果b已经是集合中的元素,那么再执行set.add(b)操作是无效的。集合对象的初始容量是16个字节,装载因子是0.75。也就是说,如果集合添加的元素超过总容量的75%时,集合的容量将增加一倍。27 2常用方法public boolean add(E o)向集合添加参数指定的元素。public void clear()清空集合,使集合不含
31、有任何元素。public boolean contains(Object o)判断参数指定的数据是否属于集合。public boolean isEmpty()判断集合是否为空。public boolean remove(Object o)集合删除参数指定的元素。public int size()返回集合中元素的个数。Object toArray()将集合元素存放到数组中,并返回这个数组。boolean containsAll(HanshSet set)判断当前集合是否包含参数指定的集合。public Object clone()得到当前集合的一个克隆对象,该对象中元素的改变不会影响到当前集合中
32、元素,反之亦然。可以借助泛型类Iterator实现遍历集合,一个集合对象可以使用iterator()方法返回一个Iterator类型的对象。如果集合是“Student类型”的集合,即集合中的元素是Student类创建的对象,那么该集合使用iterator()方法返回一个Iterator类型的对象,该对象使用next()方法遍历集合。例7-11中,把学生的成绩存放在一个集合中,并实现了遍历集合(效果如图7.6所示)。28例子7-11效果图29 3集合的交、并与差 集合对象调用boolean addAll(HashSet set)方法可以和参数指定的集合求并运算,使得当前集合成为两个集合的并。集合
33、对象调用boolean boolean retainAll(HashSet set)方法可以和参数指定的集合求交运算,使得当前集合成为两个集合的交。集合对象调用boolean boolean boolean removeAll(HashSet set)方法可以和参数指定的集合求差运算,使得当前集合成为两个集合的差 参数指定的集合必须和当前集合是同种类型的集合,否则上述方法返回false。例7-12求2个集合A、B的对称差集合,即求,(效果如图7.7所示)。304HashSet泛型类实现的接口 HashSet泛型类实现了泛型接口Set,而Set接口是Collection接口的子接口。HashSe
34、t类中的绝大部分方法都是接口方法的实现。编程时,可以使用接口回调技术,即把HashSet对象的引用赋值给Collection接口变量或Set接口变量,那么接口就可以调用类实现的接口方法。返回317.7 HashMap泛型类 HashMap也是一个很实用的类,HashMap对象采用散列表这种数据结构存储数据,习惯上称HashMap对象为散列映射对象。散列映射用于存储键/值数据对,允许把任何数量的键/值数据对存储在一起。键不可以发生逻辑冲突,两个数据项不要使用相同的键,如果出现两个数据项对应相同的键,那么先前散列映射中的键/值对将被替换。散列映射在它需要更多的存储空间时会自动增大容量。最好使用散列
35、映射来存储要查找的数据,使用散列映射可以减少检索的开销。321HashMap对象 HashMap泛型类创建的对象称为散列映射,如HashMap hashtable=HashMap();那么,hashtable就可以存储键/值对数据,其中的键必须是一个String对象,键对应的值必须是Student对象。hashtable可以调用public V put(K key,V value)将键/值对数据存放到散列映射中,该方法同时返回键所对应的值。33 2常用方法*public void clear()清空散列映射。*public Object clone()返回当前散列映射的一个克隆。*public
36、 boolean containsKey(Object key)如果散列映射有键/值对使用了参数指定的键,方法返回true,否则返回false。*public boolean containsValue(Object value)如果散列映射有键/值对的值是参数指定的值,方法返回true,否则返回false。*public V get(Object key)返回散列映射中使用key作为键的键/值对中的值。*public boolean isEmpty()如果散列映射不含任何键/值对,方法返回true,否则返回false。*public V remove(Object key)删除散列映射中键为
37、参数指定的键/值对,并返回键对应的值。*public int size()返回散列映射的大小,即散列映射中键/值对的数目。343遍历散列映射 如果想获得散列映射中所有键/值对中的值,首先使用public Collection values()方法返回一个实现Collection接口类创建的对象的引用,并要求将该对象的引用返回到Collection接口变量中。values()values()方法返回的对象中存储了散列映射中所有键/值对中的“值”,这样接口变量就可以调用类实现的方法,如获取Iterator对象,然后输出所有的值。例7-13使用了散列映射的常用方法,并遍历了散列映射(效果如图7.8所
38、示)。354HashMap泛型类实现的接口 HashMap泛型类实现了泛型接口Map,HashMap类中的绝大部分方法都是Map接口方法的实现。编程时,可以使用接口回调技术,即把HashMap对象的引用赋值给Map接口变量,那么接口就可以调用类实现的接口方法。367.8 TreeSet泛型类 TreeSet 类是实现Set接口的类,TreeSet 泛型类创建的对象称为树集,如 TreeSet tree=TreeSet();那么tree就是一个可以存储Student对象的集合,tree可以调用add(Student s)方法将Student对象添加到树集中。树集用add()方法增加节点,节点会按
39、其存放的数据的“大小”顺序一层一层地依次排列,在同一层中的节点从左到右按“大小”顺序递增排列,下一层的都比上一层的小。为了能使树集按大小关系排列节点,要求添加到树集中的节点中的对象必须是实现Comparable接口类所创建的对象,这样树集就可以按对象的大小关系排列节点。如:TreeSet mytree=new TreeSe();然后使用add()方法为树集添加节点:mytree.add(boy);mytree.add(zoo);mytree.add(apple);mytree.add(girl);当一个树集中的数据是实现Comparable接口类创建的对象时,节点就按对象的大小关系顺序排列。3
40、7TreeSet 类的常用方法*public boolean add(E o)向树集添加加对象,添加成功返回true,否则返回false。*public void clear()删除树集中的所有对象。*public void contains(Object o)如果包含对象o方法返回true,否则返回false。*public E first()返回树集中的第一个对象(最小的对象)。*public E last()返回最后一个对象(最大的对象)。*public isEmpty()判断是否是空树集,如果树集不含对象返回true。*public boolean remove(Object o)删除
41、树集中的对象o。*public int size()返回树集中对象的数目。例7-14使用了树集,其中的Student类实现了Comparable接口,按成绩的高低规定了Student对象的大小关系。树集将Student对象作为节点中数据添加到该树集中(效果如图7.10所示)。38使用树集注意事项注:树集中不允许出现大小相等的两个节点。例如,在上述例子中如果再添加语句st4=new Student(90,zhan ying);mytree.add(st4);是无效的。如果允许成绩相同,可把上述例子中Student类中的compareTo方法更改为:public int compareTopubl
42、ic int compareTo(Object b)(Object b)Student st Student st=(Student)b;=(Student)b;if(this.english-st if(this.english-st.English)=0)return 1;.English)=0)return 1;else return(this.english-st.english else return(this.english-st.english););397.9 TreeMap泛型类 reeMap类实现了Map接口。TreeMap提供了按排序顺序存储关键字/值对的有效手段。应该注
43、意的是,不像散列映射(HashMap),树映射(TreeMap)保证它的元素按照关键字升序排列。下面是TreeMap的构造函数:TreeMapTreeMap()()TreeMap TreeMap(Comparator comp)(Comparator comp)第一种形式构造的树映射,按关键字的大小顺序来排序树映射中的关键字/值对,关键字的大小顺序是按其字符串表示的字典顺序。第二种形式构造的树映射,关键字的大小顺序按Comparator 接口规定的大小顺序,树映射按关键字的大小顺序来排序树映射中的关键字/值对。TreeMap类的常用方法与HashMap类相似。例7-15使用了TreeMap,分
44、别按照学生的身高和体重排序对象(效果如图7.11所示)。40例子7-15效果图417.10 Stack泛型类 堆栈是一种“后进先出”的数据结构,只能在一端进行输入或输出数据的操作。堆栈把第一个放入该堆栈的数据放在最底下,而把后续放入的数据放在已有数据的上面,如图7.12所示。使用java.util包中的Stack类创建一个堆栈对象,堆栈对象可以使用如下方法public E push(E item);public E push(E item);输入数据,实现入栈操作;public E pop();public E pop();输出数据,实现出栈操作;public booleanpublic boolean empty();empty();判断堆栈是否还有数据,有数据返回false,否则返回true;public E peek();public E peek();获取堆栈顶端的数据,但不删除该数据;public intpublic int search(Object data);search(Object data);获取数据在堆栈中的位置,最顶端的位置是1,向下依次增加,如果堆栈不包含此数据,则返回-1。例7-16用堆栈输出该递归序列的若干项。42例子7-16效果图返回4344