• 1. 第7章 常用实用类1.Date类 2.Calendar类 3.Math类与Biglnteger类 4.LinkedList泛型类 5.HashSet泛型类 6.HashMap泛型类 7.TreeSet泛型类 8.TreeMap泛型类 9.Stack泛型类
  • 2. 7.1 Date类 1.Date对象 Date类在java.util包中。使用Date类的无参数构造方 法创建的对象可以获取本地当前时间。 用Date的构造方法Date(long time)创建的Date对象表 示相对1970年1月1日0点(GMT格林威治时间,核北京早晨8点)的时间,例如参数 time取值60*60*1000秒表示Thu Jan 01 01:00:00 GMT 1970。 可以用System类的静态方法 public long currentTimeMillis()获 取系统当前时间,这个时间是从1970.年1月1日0点(GMT)到目前时刻所走过的毫秒数(这是一个不小的数)
  • 3. 。可以根据currentTimeMillis()方法得到的数字,用Date的构造方法Date(long time)来创建一个本地日期的Date对象。 2.格式化时间 Date对象表示时间的默认顺序是:星期、月、日、小时、分、秒、年。例如: Sat Apr 28 21:59:38 CST 2001。 我们可能希望按着某种习惯来输出时间,比如时间的序 :年 月 星期 日或年 月 星期 日 小时 分 秒。
  • 4. 这时可以使用DateFormat的子类SimpleDateFormat来实现日期的格式化。SimpleDateFormat有一个常用构造方法: public SimpleDateFormat(String pattern)。 该构造方法可以用参数pattern指定的格式创建一个对 象,该对象调用: format(Date date) 方法格式化时间对象date。
  • 5. 需要注意的是,pattern中应当含有一些有效的字符序列。例如: ly或yy 表示用2位数字输出年份;yyyy表示用4位数字输出年份。 lM 或MM 表示用2为数字或文本输出月份,如果想用汉字输出月份,pattern中应连续包含至少3个M,如:MMM。
  • 6. ld 或dd 表示用2位数字输出日。 lH或HH 表示用两位数字输出小时。 lm或mm 表示用两位数字输出分。 ls或ss 表示用两位数字输出秒。 l E 或EE 表示用字符串输出星期。 在下面的例子7_1中,我们用三种格式输出时间。 返回
  • 7. import java.util.Date; import java.text.SimpleDateFormat; public class Example7_1{ public static void main(String args[ ]){ Date nowTime=new Date(); System.out.println("现在的时间:"+nowTime); SimpleDateFormat matter1=new SimpleDateFormat(" 'BeijingTime':yyyy-MM-dd"); System.out.println("现在的时间:"+matter1.format(nowTime)); SimpleDateFormat matter2= new SimpleDateFormat("北京时间yyyy-MM-dd HH:mm:ss(a)(EE)");
  • 8. System.out.println("现在的时间:"+matter2.format(nowTime)); long time=-1000L; Date date=new Date(time); System.out.println(time+"秒表示的日期时间是:"+matter2.format(date)); time=1000L; date=new Date(time); System.out.println(time+"秒表示的日期时间是:"+matter2.format(date)); } }
  • 9. 上述程序的输出结果: 现在的时间:Thu Sep 02 09:33:55 CST 2004 现在的时间: time:2004-09-02 goodTime:2004年-09月-星期四02日-09:时33:分55:秒 北京时间 现在的时间:北京时间02日09时九月 55秒33分星期四- 3600秒表示的日期时间是:Thu Jan 01 07:59:56 CST 1970 - 1800秒表示的日期时间是:Thu Jan 01 07:59:58 CST 1970
  • 10. 7.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 hour,int minute) public final void set(int year,int month, int date, int hour, int minute,int second)
  • 11. 将日历翻到任何一个时间,当参数year取负数时表示公元前。 calendar对象调用方法: public int get(int field) 可以获取有关年份、月份、小时、星期等信息,参数field的有效值由Calendar的静态常量指定,例如: calendar.get(Calendar.MONTH); 返回一个整数,如果该整数是0表示当前日历是在一月,该整数是1表示当前日历是在二月等。
  • 12. 日历对象调用 public long getTimeInMillis() 可以将时间表示为毫秒。 下面的例子2使用Calendar来表示时间。并计算了1931年和1945年之间相隔的天数。 返回
  • 13. import java.util.*; public class Example7_2{ public static void main(String args[ ]){ Calendar calendar=Calendar.getInstance(); //创建一个日历对象 calendar.setTime(new Date()); //用当前时间初始化日历时间 String 年=String.valueOf(calendar.get(Calendar.YEAR)), 月=String.valueOf(calendar.get(Calendar.MONTH)+1), 日=String.valueOf(calendar.get(Calendar.DAY_OF_MONTH)), 星期=String.valueOf(calendar.get(Calendar.DAY_OF_WEEK)-1); int hour=calendar.get(Calendar.HOUR_OF_DAY), minute=calendar.get(Calendar.MINUTE), second=calendar.get(Calendar.SECOND);
  • 14. System.out.println("现在的时间是:"); System.out.print(""+年+"年"+月+"月"+日+"日 "+ "星期"+星期); System.out.println(" "+hour+"时"+minute+"分"+second+"秒"); calendar.set(1931,8,18); //将日历翻到1931年九月十八日,8表示九月 long timeOne=calendar.getTimeInMillis(); calendar.set(1945,7,15); //将日历翻到1945年八月十五日,7表示八月 long timeTwo=calendar.getTimeInMillis(); long 相隔天数=(timeTwo-timeOne)/(1000*60*60*24); System.out.println("1945年8月15日和1931年9月18日相隔"+相隔天数+"天"); } } 上述程序的输出结果: 现在的时间是: 2008年8月30日 星期6 16时42分26秒 1945年8月15日和1931年9月18日相隔5080天
  • 15. 下面的例子3输出1931年9月的日历页。
  • 16. import java.util.*; public class Example7_3{ public static void main(String args[ ]){ Calendar 日历=Calendar.getInstance(); 日历.set(1931,8,1); //8代表九月 int 星期几=日历.get(Calendar.DAY_OF_WEEK)-1; String a[]=new String[星期几+30]; //存放号码的一维数组 for(int i=0;i<星期几;i++){ a[i]=""; } for(int i=星期几,n=1;i<星期几+30;i++){ a[i]=String.valueOf(n) ; n++;
  • 17. } int year=日历.get(Calendar.YEAR), month=日历.get(Calendar.MONTH)+1; System.out.println(" "+year+"年"+month+"月"+"18日,日本发动侵华战争"); System.out.printf("%4c%4c%4c%4c%4c%4c%4c\n",'日','一','二', '三','四','五','六'); for(int i=0;i
  • 18. 7.3 Math类与BigInteger类 1.Math类 在编写程序时,可能需要计算一个数的平方根、绝对值、获取一个随机数等等。java.lang包中的Math类中包含许多用来进行科学计算的类方法,这些方法可以直接通过类名调用。另外,Math类还有两个静态常量,E和PI,它们的值分别是: 2.7182828284590452354 和 3.14159265358979323846。
  • 19. 以下是Math类常用方法: l  public static long abs(double a) 返回a的绝对值。 l  public static double max(double a,double b) 返回a、 b的最大值。 l  public static double min(double a,double b) 返回a、b的最小值。 l  public static double random() 产生一个0到1之间的随机数(不包括0和1)。 l  public static double pow(double a,double b) 返回a的b次幂。      
  • 20. l public static double sqrt(double a) 返回a的平方根。 l   public static double log(double a) 返回a的对数。 l   public static double sin(double a) 返回正弦值。 l public static double asin(double a) 返回反正弦值。 有时我们可能需要对输出的数字结果进行必要的格式 化,例如,对于3.14356789,我们希望保留小数位为3位、整数部分至少要显示3位,即将3.14356789格式化为003.144。 可以使用java.text包中的NumberFormat类,该类调用类方法: public static final NumberFormat getInstance()
  • 21. l 实例化一个NumberFormat对象,该对象调用 l public final String format(double number) l方法可以格式化数字number。 l NumberFormat类有如下常用方法: l public void setMaximumFractionDigits(int newValue) l public void setMinimumFractionDigits(int newValue) l public void setMaximumIntegerDigits(int newValue) l public void setMinimumIntegerDigits(int newValue)
  • 22. 在下面的例子4中我们用一定的格式输出5的平方根,通过一个20次的循环,每次获取1到8之间的一个随机数。
  • 23. import java.text.NumberFormat; public class Example7_4{ public static void main(String args[ ]){ double a=Math.sqrt(10); System.out.println("格式化前:"+a); NumberFormat f=NumberFormat.getInstance(); f.setMaximumFractionDigits(5); f.setMinimumIntegerDigits(3); String s=f.format(a); System.out.println("格式化后:"+s);
  • 24. System.out.println("得到的随机数:"); int number=8; for(int i=1;i<=20;i++){ int randomNumber=(int)(Math.random()*number)+1; //产生1~8之间的随机数 System.out.print(" "+randomNumber); if(i%10==0) System.out.println(""); } } } 例子5使用自己编写的MyNumberFormat类中的方法格式化10的平方根
  • 25. public class Example7_5{ public static void main(String args[]){ double a=Math.sqrt(10); System.out.println("格式化前:"+a); MyNumberFormat myFormat=new MyNumberFormat(); System.out.println("格式化后:"+myFormat.format(a,5));//保留5位小数 } } class MyNumberFormat{ public String format(double a,int n){
  • 26. String str=String.valueOf(a); //用数字a得到一个串对象 int index=str.indexOf("."); //获取小数点的位置 String temp=str.substring(index+1); //截取小数部分 int fractionLeng=temp.length(); //首先知道小数点后面有几个数字 n=Math.min(fractionLeng,n); //取n和fractionLeng中的最小值 str=str.substring(0,index+n+1); //得到保留 n位小数后的字符串 return str; } }
  • 27. 2.BigInteger类 程序有时需要处理大整数,java.math包中的BigInteger类提供任意精度的整数运算。可以使用构造方法: public BigInteger(String val) 构造一个十进制的BigInteger对象。该构造方法可以发生NumberFormatException异常,也就是说,字符串参数val中如果含有非数字字母就会发生NumberFormatException异常。 以下是BigInteger类的常用方法:
  • 28. public BigInteger add(BigInteger val) 返回当前大整数对象与参数指定的大整数对象的和。 public BigInteger subtract(BigInteger val) 返回当前大整数对象与参数指定的大整数对象的差。 public BigInteger multiply(BigInteger val) 返回当前大整数对象与参数指定的大整数对象的积。 public BigInteger divide(BigInteger val) 返回当前大整数对象与参数指定的大整数对象的商。
  • 29. public BigInteger remainder(BigInteger val) 返回当前大整数对象与参数指定的大整数对象的余。 public int compareTo(BigInteger val) 返回当前大整数对象与参数指定的大整数的比较结果,返回值是1、-1或0,分别表示当前大整数对象大于、小于或等于参数指定的大整数。 public BigInteger abs() 返回当前大整数对象的绝对值。 public BigInteger pow(int exponent) 返回当前大整数对象的exponent次幂。
  • 30. public String toString() 返回当前大整数对象 十进制的字符串表示。 public String toString(int p) 返回当前大整数对象p进制的字符串表示。 在下面的例子6中,计算了2个大整数的和、差、积和商,并计算出了一个大整数的因子个数(因子中不包括1和大整数本身)。 返回
  • 31. import java.math.*; public class Example7_6{ public static void main(String args[]){ BigInteger n1=new BigInteger("987654321987654321987654321"), n2=new BigInteger("123456789123456789123456789"), result=null; result=n1.add(n2); System.out.println(n1+"+"+n2+"="); System.out.println(result); result=n1.subtract(n2); System.out.println(n1+"-"+n2+"="); System.out.println(result); result=n1.multiply(n2); System.out.println(n1+"*"+n2+"="); System.out.println(result); result=n1.divide(n2);
  • 32. System.out.println(n1+"/"+n2+"="); System.out.println(result); BigInteger m=new BigInteger("77889988"), COUNT=new BigInteger("0"), ONE=new BigInteger("1"), TWO=new BigInteger("2"); for(BigInteger i=TWO;i.compareTo(m)<0;i=i.add(ONE)){ if((n1.remainder(i).compareTo(BigInteger.ZERO))==0){ COUNT=COUNT.add(ONE); System.out.println(m+"的因子:"+i); } } System.out.println(m+"一共有"+COUNT+"个因子"); } }
  • 33. 7.4 LinkedList泛型类 使用LinkedList泛型类可以创建链表结构的数据对 象。链表是由若干个节点组成的一种数据结构,每个节点含有一个数据和下一个节点的引用(单链表),或含有一个数据并含有上一个节点的引用和下一个节点的引用(双链表),节点的索引从0开始。链表适合动态地改变它存储的数据,如,增加、删除节点等。
  • 34. 1.LinkedList对象 java.util 包中的LinkedList泛型类创建的对象以链表结构存储数据,习惯上称LinkedList类创建的对象为链表对象。例如, LinkedList mylist=new LinkedList(); 创建一个空双链表。然后mylist可以使用add(String obj)方法向链表依次增加节点,节点中的数据是参数obj指定对象的引用。
  • 35. 例如: mylist.add(“How”); mylist.add(“Are”); mylist.add(“You”); mylist.add(“Java”); 这时,双链表mylist就有了有4个节点,节点是自动连 接在一起的,不需要我们去做连接,也就是说,不需 要我们去操作安排节点中所存放的下一个或上一个节点的引用。
  • 36. 2.常用方法 以下是LinkedList泛型类的一些常用方法。 public boolean add(E element) 向链表末尾添加一个新的节点,该节点中的数据是参数elememt指定的对象。 public void add(int index ,E element) 向链表的指定位置添加一个新的节点,该节点中的数据是参数elememt指定的对象。 public void addFirst(E element) 向链表的头添加新节点,该节点中的数据是参数elememt指定的对象。
  • 37. public E removeFirst() 删除第一个节点,并返回这个节点中的对象E。 public E removeLast() 删除最后一个节点对象,并返回这个节点中的对象E。 public E get(int index) 得到链表中指定位置处节点中的对象。 public E getFirst() 得到链表中第一个节点中的对象。 public E getLast() 得到链表中最后一个节点中的对象。 public int indexOf(E element) 返回含有数据element的节点在链表中首次出现的位置,如果链表中无此节点则返回-1。
  • 38. public int lastIndexOf(E element) 返回含有数据element的节点在链表中最后出现的位置,如果链表中无此节点则返回-1。 public E set(int index ,E element) 将当前链表index位置节点中的对象element替换为参数element指定的对象。并返回被替换的对象。 public int size() 返回链表的长度,即节点的个数。 public boolean contains(Object element) 判断链表节点中是否有节点含有对象element。
  • 39. public Object clone() 得到当前链表的一个克隆链表, 该克隆链表中节点数据的改变不会影响到当前链表中节点的数据,反之亦然。 下述例子7_7使用了上述一些方法。
  • 40. import java.util.*; class Student{ String name; int score; Student(String name,int score){ this.name=name; this.score=score; } } public class Example7_7{ public static void main(String args[]){
  • 41. LinkedList mylist=new LinkedList(); Student stu1=new Student("张小一",78), stu2=new Student("王小二",98), stu3=new Student("李大山",67); mylist.add(stu1); mylist.add(stu2); mylist.add(stu3); int number=mylist.size(); System.out.println("现在链表中有"+number+"个节点: "); for(int i=0;i
  • 42. System.out.printf("第"+i+"节点中的数据,学生:%s,分数:%d\n",temp.name,temp.score); } Student removeSTU=mylist.remove(1); System.out.printf("被删除的节点中的数据是:%s,%d\n",removeSTU.name,removeSTU.score); Student replaceSTU=mylist.set(1,new Student("赵钩林",68)); System.out.printf("被替换的节点中的数据是:%s,%d\n",replaceSTU.name,replaceSTU.score); number=mylist.size(); System.out.println("现在链表中有"+number+"个节点: "); for(int i=0;i
  • 43. } if(mylist.contains(stu1)){ System.out.println("链表包含"+stu1+":"); System.out.println(stu1.name+","+stu1.score); } else{ System.out.println("链表没有节点含有"+stu1); } } }
  • 44. 3.遍历链表 例子7借助get方法实现了遍历链表。我们可以借助泛型 类Iterator实现遍历链表,一个链表对象可以使用iterator()方法返回一个Iterator类型的对象,如果链表是“Student类型”的链表,即链表节点中的数据是Student类创建的对象,那么该链表使用iterator()方法返回一个Iterator类型的对象,该对象使用next()方法遍历链表。在下面的例子7_8中,我们把学生的成绩存放在一个链表中,并实现了遍历链表。
  • 45. import java.util.*; class Student{ String name ; int number; float score; Student(String name,int number,float score){ this.name=name; this.number=number; this.score=score; } } public class Example7_8{ public static void main(String args[]){ LinkedList mylist=new LinkedList(); Student stu_1=new Student("赵民" ,9012,80.0f),
  • 46. stu_2=new Student("钱青" ,9013,90.0f), stu_3=new Student("孙枚" ,9014,78.0f), stu_4=new Student("周右" ,9015,55.0f); mylist.add(stu_1); mylist.add(stu_2); mylist.add(stu_3); mylist.add(stu_4); Iterator iter=mylist.iterator(); while(iter.hasNext()){ Student te=iter.next(); System.out.println(te.name+" "+te.number+" "+te.score); } } }
  • 47. 4.LinkedList泛型类实现的接口: LinkedList泛型类实现了泛型接口List,而List接口由是Collection接口的子接口。LinkedList类中的绝大部分方法都是接口方法的实现。编程时,可以使用接口回调技术,即把LinkedList对象的引用赋值给Collection接口变量或List接口变量,那么接口变量就可以调用类实现的接口方法。
  • 48. 5.SDK1.5之前的LinkedList类 JDK1.5之前没有泛型的LinkedList类,可以用普通的 LinkedList创建一个链表对象,例如: LinkedList mylist=new LinkedList(); 创建了一个空双链表。然后mylist链表可以使用add(Object obj)方法向这个链表依次添加节点。由于任何类都是Object类的子类,因此可以把任何一个对象作为链表节点中的对象。
  • 49. 需要注意的是当使用get()获取一个节点中的对象,要用类型转换运算符转换回原来的类型。Java泛型的主要目的是可以建立具有类型安全的集合框架,如链表、散列表等数据结构,最重要的一个优点就是:在使用这些泛型类建立的数据结构时,不必进行强制类型转换,即不要求进行运行时类型检查。SDK1.5是支持泛型的编译器,它将运行时类型检查提前到编译时执行,使代码更安全。如果你使用旧版本的LinkedList类,1.5编译器会给出警告信息,但程序仍能正确运行。下面是使用旧版本.例子9 返回
  • 50. 7.5 HashSet泛型类 HashSet泛型类在数据组织上类似数学上的集合,可以进行“交”、“并”、“差”等运算。 1.HashSet对象 HashSet泛型类创建的对象称作集合,例如 HashSet set= HashSet(); 那么,set就是一个可以存储String类型数据的集合, set可以调用add(String s)方法将String类型的数据添加 到集合中,添加到集合中的数据称做集合的元素。
  • 51. 集合不允许有相同的元素,也就是说,如果b已经是集 合中的元素,那么再执行set.add(b)操作是无效的。集 合对象的初始容量是16个字节,装载因子是0.75,也 就是说,如果集合添加的元素超过总容量的75%时,集合的容量将增加一倍。 2.常用方法 public boolean add(E o) 向集合添加参数指定的元素。 public void clear() 清空集合,使集合不含有任何元素。 public boolean contains(Object o) 判断参数指定的数据是否属于集合。 public boolean isEmpty() 判断集合是否为空。
  • 52. public boolean remove(Object o) 集合删除参数指定的元素。 public int size() 返回集合中元素的个数。 Object[] toArray() 将集合元素存放到数组中,并返回这个数组。 boolean containsAll(HanshSet set) 判断当前集合是否包含参数指定的集合。 public Object clone() 得到当前集合的一个克隆对象,该对象中元素的改变不会影响到当前集合中元素,反之亦然。 下面例子10,把学生成绩存放到一个集合中,并实现遍历集合。
  • 53. import java.util.*; class Student{ String name; int score; Student(String name,int score){ this.name=name; this.score=score; } } public class Example7_10{
  • 54. public static void main(String args[]){ Student zh=new Student("张红铭",77), wa=new Student("王家家",68), li=new Student("李佳佳",67); HashSet set=new HashSet(); HashSet subset=new HashSet(); set.add(zh); set.add(wa); set.add(li); subset.add(wa); subset.add(li);
  • 55. if(set.contains(wa)){ System.out.println("集合set中含有:"+wa.name); } if(set.containsAll(subset)){ System.out.println("集合set包含集合subset"); } int number=subset.size(); System.out.println("集合subset中有"+number+"个元素:"); Object s[]=subset.toArray(); for(int i=0;i
  • 56. } number=set.size(); System.out.println("集合set中有"+number+"个元素:"); Iterator iter=set.iterator(); while(iter.hasNext()){ Student te=iter.next(); System.out.printf("姓名:%s,分数:%d\n",te.name,te.score); } } }
  • 57. 3.集合的交、并与差 集合对象调用boolean addAll(HashSet set)方法可以和参数指定的集合求并运算,使得当前集合成为两个集合的并。 集合对象调用boolean boolean retainAll (HashSet set)方法可以和参数指定的集合求交运算,使得当前集合成为两个集合的交。 集合对象调用boolean boolean boolean removeAll (HashSet set)方法可以和参数指定的集合求差运算,使得当前集合成为两个集合的差 参数指定的集合必须和当前集合是同种类型的集合,否则上述方法返回false。
  • 58. 下面的例子11例子11求2个集合A、B的对称差集合, 即求(A-B)U(B-A)。 上述程序的运行结果: A和B的对称差集合有4个元素:编译时出现了警告: 4,6,3,5, 返回
  • 59. import java.util.*; public class Example7_11{ public static void main(String args[]){ Integer one=new Integer(1), two=new Integer(2), three=new Integer(3), four=new Integer(4), five=new Integer(5), six=new Integer(6); HashSet A=new HashSet(), B=new HashSet(), tempSet=new HashSet(); A.add(one); A.add(two); A.add(three); A.add(four); B.add(one);
  • 60. B.add(two); B.add(five); B.add(six); tempSet=(HashSet)A.clone(); A.removeAll(B); //A变成调用该方法之前的A集合与B集合的差集 B.removeAll(tempSet); //B变成调用该方法之前的B集合与tempSet集合的差集 B.addAll(A); //B就是最初的A与B的对称差 int number=B.size(); System.out.println("A和B的对称差集合有"+number+"个元素:"); Iterator iter=B.iterator(); while(iter.hasNext()){ Integer te=iter.next(); System.out.printf("%d,",te.intValue()); } } }
  • 61. 4.HashSet泛型类实现的接口 HashSet泛型类实现了泛型接口Set,而 Set接口由是Collection接口的子接口。 HashSet类中的绝大部分方法都是接口方法的实现。编程时,可以使用接口回调技术,即把HashSet对象的引用赋值给Collection接口变量或Set接口变量,那么接口就可以调用类实现的接口方法。 返回
  • 62. 7.6 HashMap泛型类 HashMap也是一个很实用的泛型类, HashMap对象采用散列表这种数据结构存储数据,习惯上称HashMap对象为散列映射对象。散列映射用于存储键/值数据对,允许把任何数量的键/值数据对存储在一起。键不可以发生逻辑冲突,即不要两个数据项使用相同的键,如果出现两个数据项对应相同的键,那么,先前散列映射中的键/值对将被替换。散列映射在它需要更多的存储空间时会自动增大容量。
  • 63. 例如,如果散列映射的装载因子是0.75,那么当散列映射的容量被使用了75%时,它就把容量增加到原始容量的2倍。对于数组和链表这两种数据结构,如果要查找它们存储的某个特定的元素却不知道它的位置,就需要从头开始访问元素直到找到匹配的为止;如果数据结构中包含很多的元素,就会浪费时间。这时最好使用散列映射来存储要查找的数据,使用散列映射可以减少检索的开销。
  • 64. 1.HashMap对象 HashMap泛型类创建的对象称作散列映射,例如: HashMap hashtable= new HashSet(); 那么,hashtable就可以存储“键/值”对数据,其中的键必须是一个String对象,键对应的值必须是Student对象。hashtable可以调用 public V put(K key,V value)将键/值对数据存放到散列映射中,该方法同时返回键所对应的值。
  • 65. 2.常用方法 public void clear() 清空散列映射。 public Object clone() 返回当前散列映射的一个克隆。 public boolean containsKey(Object key) 如果散列映射有键/值对使用了参数指定的键,方法返回true,否则返回false。 public boolean containsValue(Object value) 如果散列映射有键/值对的值是参数指定的值,方法返回true,否则返回false。
  • 66. public V get(Object key) 返回散列映射中使用key做键的键/值对中的值。 public boolean isEmpty() 如果散列映射不含任何键/值对,方法返回true,否则返回false。 public V remove(Object key) 删除散列映射中键为参数指定的键/值对,并返回键对应的值。 public int size() 返回散列映射的大小,即散列映射中键/值对的数目。
  • 67. 3.遍历散列映射 如果想获得散列映射中所有键/值对中的值,首先使用 public Collection values() 方法返回一个实现Collection接口类创建的对象的引用,并要求将该对象的引用返回到Collection接口变量中。values()方法返回的对象中存储了散列映射中所有“键/值”对中的“值”,这样接口变量就可以调用类实现的方法,比如获取Iterator对象,然后输出所有的值。
  • 68. 下面的例子12使用了散列映射的常用方法,并遍历了散列映射。 import java.util.*; class Book{ String ISBN,name; Book(String ISBN,String name){
  • 69. this.name=name; this.ISBN=ISBN; } } public class Example7_12{ public static void main(String args[]){ Book book1=new Book("7302033218","C++基础教程"), book2=new Book("7808315162","Java编程语言"), book3=new Book("7302054991","J2ME无线设备编程"); String key="7808315162";
  • 70. HashMap table=new HashMap(); table.put(book1.ISBN,book1); table.put(book2.ISBN,book2); table.put(book3.ISBN,book3); if(table.containsKey(key)){ System.out.println(table.get(key).name+"有货"); } Book b=table.get("7302054991"); System.out.println("书名: "+b.name+",ISBN: "+b.ISBN); int number=table.size();
  • 71. System.out.println("散列映射中有"+number+"个元素: "); Collection collection=table.values(); Iterator iter=collection.iterator(); while(iter.hasNext()){ Book te=iter.next(); System.out.printf("书名:%s,ISBN:%s\n",te.name,te.ISBN); } } }
  • 72. 4.HashMap泛型类实现的接口 HashMap泛型类实现了泛型接口Map,HashMap>类中的绝大部分方法都是Map接口方法的实现。编程时,可以使用接口回调技术,即把HashMap对象的引用赋值给Map接口变量,那么接口就可以调用类实现的接口方法。 返回
  • 73. 7.7 TreeSet泛型类 TreeSet 泛型类是实现Set接口的类,它的大部分方法都是接口方法的实现。TreeSet 泛型类创建的对象称作树集,例如 TreeSet tree= new TreeSet (); 那么,tree就是一个可以存储Student类型数据的集合,tree可以调用add(String s)方法将Student类型的数据添加到树集中,存放到树集中的对象按对象的串表示升序排列。以下是TreeSet 类的常用方法:
  • 74. public boolean add(E o) 向树集添加加对象,添加成功返回true,否则返回false。 public void clear() 删除树集中的所有对象。 public void contains(Object o) 如果包含对象o方法返回true,否则返回false 。 public E first() 返回树集中的第一个对象(最小的对象)。 public E last() 返回最后一个对象(最大的对象)。
  • 75. public isEmpty() 判断是否是空树集,如果树集不含对象返回true 。 public boolean remove(Object o) 删除树集中的对象o。 public int size() 返回树集中对象的数目。 但很多对象不适合按着字符串排列大小。对象调用toString()方法就可以获得自己的字符串表示,比如一个文本框(TextField)的字符串表示是: java.awt.TextField[textfield0,0,0,0x0,invalid,text=,editable,selection=0-0] 如果让文本框按着字符串来比较大小似乎无任何意义。
  • 76. 我们在创建树集时可自己规定树集中的对象按着什么样的“大小”顺序排列。假如我们有四个学生对象,他们有姓名和成绩,我们想把这四个对象添加到树集中,并按着成绩的高低排列,而不是按着姓名的字典序排列节点。 首先创建学生的Student类可以实现接口:Comparable。Comparable接口中有一个方法: public int compareTo(Object b); Student类通过实现这个接口来规定它创建的对象的大小关系,如下所示:
  • 77. class Student implements Comparable { int english=0; String name; Student(int e,String n) { english=e;name=n;
  • 78. } public int compareTo(Object b) { Student st=(Student)b; return (this.english-st.english); } }
  • 79. Comparator是java.util包中的一个接口,compare是接口中的方法,因此匿名类的方法体必须实现接口中的方法(有关匿名类可参见第5章,13节)。当mytree每次添加对象时,都会再调用接口中的方法实现对象大小的互相比较,mytree调用接口方法的过程对编程人员是不可见的,Sun公司在编写开发TreeSet类时已经实现了这一机制。 下面的例子13把Student对象添加到树集中,并按着成绩的高低排列。
  • 80. import java.util.*; class Student implements Comparable{ int english=0; String name; Student(int e,String n){ english=e;name=n; }
  • 81. public int compareTo(Object b){ Student st=(Student)b; return (this.english-st.english); } } public class Example7_13{ public static void main(String args[]){ TreeSet mytree=new TreeSet();
  • 82. Student st1,st2,st3; st1=new Student(90,"zhan ying"); st2=new Student(66,"wang heng"); st3=new Student(86,"Liuh qing"); mytree.add(st1); mytree.add(st2); mytree.add(st3);
  • 83. Iterator te=mytree.iterator(); while(te.hasNext()){ Student stu=te.next(); System.out.println(" "+stu.name+" "+stu.english); } } }
  • 84. 注:树集中不容许出现大小相等的两个节点,例如,在上述例子中如果再添加语句 s t5=new Student(76,"keng wenyi"); mytree.add(st5); 是无效的。如果允许成绩相同,可把上述例子中Student类中的compareTo方法更改为: 返回
  • 85. 7.8 TreeMap泛型类 TreeMap类实现了Map接口。TreeMap提供了按排序顺序存储“关键字/值”对的有效手段。应该注意的是,不像散列映射(HashMap),树映射(TreeMap)保证它的元素按照关键字升序排列。下面是TreeMap构造函数: TreeMap() TreeMap(comparator comp)
  • 86. 第一种形式构造的树映射,按关键字的大小顺序来排序树映射中的“关键字/值”对,关键字的大小顺序是按其字符串表示的字典顺序。第二种形式构造的树映射,关键字的大小顺序按comp接口规定的大小顺序,树映射按关键字的大小顺序来排序树映射中的“关键字/值”对。TreeMap类的常用方法与HashMap类相似。 下面的例子14使用了TreeMap,分别按着学生的身高和体重排序对象。 import java.util.*; class MyKey implements Comparable{ int number=0; MyKey(int number){ this.number=number;返回
  • 87. } public int compareTo(Object b){ MyKey st=(MyKey)b; if((this.number-st.number)==0){ return -1; } else{ return (this.number-st.number); } } } 返回
  • 88. class Student{ String name=null; int height,weight; Student(int w,int h,String name){ weight=w; height=h; this.name=name; } } public class Example7_14{返回
  • 89. public static void main(String args[ ]){ Student s1=new Student(65,177,"张三"), s2=new Student(85,168,"李四"); TreeMap treemap=new TreeMap(); treemap.put(new MyKey(s1.weight),s1); treemap.put(new MyKey(s2.weight),s2); int number=treemap.size();返回
  • 90. System.out.println("树映射中有"+number+"个对象:"); Collection collection=treemap.values(); Iterator iter=collection.iterator(); while(iter.hasNext()){ Student te=iter.next(); System.out.printf("%s,%d(公斤)\n",te.name,te.weight); }返回
  • 91. treemap.clear(); treemap.put(new MyKey(s1.height),s1); treemap.put(new MyKey(s2.height),s2); number=treemap.size(); System.out.println("树映射中有"+number+"个对象:"); collection=treemap.values(); iter=collection.iterator(); while(iter.hasNext()){ Student te=iter.next(); System.out.printf("%s,%d(厘米)\n",te.name,te.height); } } } 返回
  • 92. 7.9 Stack泛型类 堆栈是一种“后进先出”的数据结构,只能在一端进行输入或输出数据的操作。堆栈把第一个放入该堆栈的数据放在最底下,而把后续放入的数据放在已有数据的顶上,如图7.6所示。 数据 数据 数据 数据 新数据输出数据压栈弹栈图7.6 堆栈结构示意图
  • 93. 向堆栈中输入数据的操作称为“压栈”,从栈中输出数据的操作称为“弹栈”。由于堆栈总是在顶端进行数据的输入输出操作,所以弹栈总是输出(删除)最后压入堆栈中的数据,这就是“后进先出”的来历。 使用java.util包中的Stack类创建一个堆栈对象,堆栈对象可以使用 public E push(E item); 输入数据,实现压栈操作。使用 public E pop();
  • 94. 输出数据,实现弹栈操作。使用 public boolean empty(); 判断堆栈是否还有数据,有数据返回false ,否则返回true。使用 public E peek(); 获取堆栈顶端的数据,但不删除该数据。使用 public int search(Object data); 获取数据在堆栈中的位置,最顶端的位置是1,向下依次增加,如果堆栈不含此数据,则返回-1。
  • 95. 堆栈是很灵活的数据结构,使用堆栈可以节省内存的开销。比如,递归是一种很消耗内存的算法,我们可以借助堆栈消除大部分递归,达到和递归算法同样的目的。Fibonacci整数序列是我们熟悉的一个递归序列,它的第n项是前两项的和,第一项和第二项是1。下面的例子15用堆栈输出该递归序列的若干项。 import java.util.*; public class Example7_15{ public static void main(String args[]){ Stack stack=new Stack(); stack.push(new Integer(1)); 返回
  • 96. stack.push(new Integer(1)); int k=1; while(k<=10){ for(int i=1;i<=2;i++){ Integer F1=stack.pop(); int f1=F1.intValue(); Integer F2=stack.pop(); int f2=F2.intValue(); 返回
  • 97. Integer temp=new Integer(f1+f2); System.out.println(""+temp.toString()); stack.push(temp); stack.push(F2); } k++; } } } 返回
  • 98. 第七章 问答题1.怎样实例化一个Calendar对象? 答:Calendar类在java.util包中。使用Calendar类的static方法getInstance()可以初始化一个日历对象,如: Calendar calendar= Calendar.getInstance();
  • 99. 第七章 问答题2.Calendar对象调用set(1949, 9,1)设置的年月日分别是多少?答:1949年10月1日
  • 100. 第七章 问答题3.怎样得到一个1--100之间的随机数?答:int randomNumber=(int)(Math.random()*100)+1
  • 101. 第七章 问答题4.BigInteger类的常用构造方法是什么?答:可以使用构造方法: public BigInteger(String val)
  • 102. 第七章 问答题5.两个BigInteger类对象怎样进行加法运算?答:BigInteger n1=new BigInteger ("大整数字符串"), n2=new BigInteger("大整数字符串"), result=null; result=n1.add(n2);
  • 103. 第七章 问答题6.LinkedList泛型类是一种什么数据结构?答:是一种链表类数据结构。
  • 104. 第七章 问答题7.对于需要经常查找的数据,应选用LinkedList还是选用HashMap? 答:选用HashMap