发布者:caijw 阅读量:61946 发布时间:2013-09-10 03:58:39
void print(Q q) { System.out.println("print:"+q); } } class GenericDemo4 { public static void main(String[] args) { Demo d = new Demo(); d.show("haha"); d.show(new Integer(4)); d.print("heihei");//实现了传什么就接受什么,摆脱类一确定类中方法参数类型就确定的局限 } } ``` ## 泛型类和泛型方法的注意事项 泛型类和方法可以同时定义,但要注意泛型的作用范围,如果使用了泛型类的泛型作为参数类型的函数,参数类型在定义类时已经定义,不能改变 如需定义泛型方法,需注意方法中的类型和类中的类型不能一样,需要定义一个其他类型 ```java class Demo { public void show(T t) { System.out.println("show:"+t); } public void print(Q q)//泛型方法的参数和泛型类不能一样 { System.out.println("print:"+q); } public static void method(W t)//静态方法不能调用泛型类的参数,只能自己定义泛型方法 { System.out.println("method:"+t); } } class GenericDemo4 { public static void main(String[] args) { Demo d = new Demo(); d.show("haha"); //d.show(4); d.print(5); d.print("hehe"); Demo.method("hahahahha"); } } ``` ## 泛型接口的介绍和使用 自定义接口用到泛型的不多,只会用到JAVA提供的泛型接口,只要了解原理就可以,泛型定义在接口上。 接口定义泛型,类在实现的时候有两种实现方法 ```java interface Inter { void show(T t); } class InterImpl_1 implements Inter//实现时候可以确定传入类型 { public void show(String t) { System.out.println("show :"+t); } } class InterImpl_2 implements Inter//实现时候不能确定传入类型,此时和泛型类一样 { public void show(T t) { System.out.println("show :"+t); } } class GenericDemo5 { public static void main(String[] args) { InterImpl_1 i = new InterImpl_1();//已经定义好,只能传字符串 i.show("haha"); InterImpl_2 i = new InterImpl_2();//和泛型类一样 i.show(4); } } ``` ## 通配符与泛型限定 1、当传入的类型不确定时,可以使用通配符?。也可以理解为占位符。使用通配符的好处是可以不用明确传入的类型,这样在使用泛型类或者泛型方法时,提高了扩展性。 2、泛型的限定: 上限:? extends E: 可以接收E类型或者E的子类型。 下限:? super E: 可以接收E类型或者E的父类型。 # 集合框架顶层之Map Map是一个接口,和Collection接口一样同属于集合框架的顶层,该体系存储的是一对数据,键值对,而且要确保键的唯一性 所属关系: Map |--Hashtable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。JDK1.0,效率低。 |--HashMap:底层是哈希表数据结构。允许使用null键null值,该集合是不同步的。JDK1.2,效率高。 |--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给Map集合中的键进行排序。 注:Map和Set看上去很像,其实Set在底层就是调用了Map集合的方法 ## Map集合中的共性方法 1、增加 V put(K key,V value):添加元素,如果添加时,存在该键值,那么新键值对会覆盖老键值对,并返回被覆盖的值。 void putAll(Map extends K,? extends V> m):添加一个集合 2、删除 void clear():清空集合中的所有键值对 V remove(Object key):删除键为key的映射关系(如果存在,返回key对应的值),如果不存在返回null 3、判断 boolean containsKey(Object key):判断该键是否存在 boolean containsValue(Object value):判断该值是否存在 boolean isEmpty():判断集合是否为空 4、获取 V get(Object key):通过键获取值,如果不存在返回null int size():获取该集合的长度 Collectionvalues():获取Map集合中所以得值,返回一个Collection集合 还有两个取出方法,是map集合的重点 Set keySet():将集合的所有键存储到一个Set集合中,返回该集合 Set> entrySet():将集合的所有映射关系存储到一个Set集合中,返回该集合 注:HashMap集合可以通过get()方法的返回值来判断一个键是否存在,通过返回null来判断。(虽然在hashMap中可以存入null键,会影响正常的判断,但由于大部分开发null键无意义,故而可以使用这种方法进行判断) 上述方法的代码演示: ```java import java.util.*; class MapDemo { public static void main(String[] args) { Map map = new HashMap(); //添加元素,添加元素,如果出现添加时,相同的键。那么后添加的值会覆盖原有键对应值。 //并put方法会返回被覆盖的值。 System.out.println("put:"+map.put("01","zhangsan1")); System.out.println("put:"+map.put("01","wnagwu")); map.put("02","zhangsan2"); map.put("03","zhangsan3"); System.out.println("containsKey:"+map.containsKey("022")); //System.out.println("remove:"+map.remove("02")); System.out.println("get:"+map.get("023")); map.put("04",null); System.out.println("get:"+map.get("04")); //可以通过get方法的返回值来判断一个键是否存在。通过返回null来判断。 //获取map集合中所有的值。 Collection coll = map.values(); System.out.println(coll); System.out.println(map); } } ``` ## Map集合的两种取出方式 Map集合的取出原理:将Map集合转成Set集合。再通过迭代器取出。 1、Set keySet():将集合的所有键存储到一个Set集合中,返回该集合,在通过集合的迭代器获取Set集合中存放的Map集合的键,在用Map集合的get方法获取该键对应的值,从而得到Map集合的所有元素并对其操作 代码示例: ```java import java.util.*; class MapDemo2 { public static void main(String[] args) { Map map = new HashMap(); map.put("02","zhangsan2"); map.put("03","zhangsan3"); map.put("01","zhangsan1"); map.put("04","zhangsan4"); //先获取map集合的所有键的Set集合,keySet(); Set keySet = map.keySet(); //有了Set集合。就可以获取其迭代器。 Iterator it = keySet.iterator(); while(it.hasNext()) { String key = it.next(); //有了键可以通过map集合的get方法获取其对应的值。 String value = map.get(key); System.out.println("key:"+key+",value:"+value); } } } ``` ![](https://statics.caijw.com/uploads/2014/09/El2rxBCcQ30pgpZewJA5uvSF0nLBTLT7h7oJUsCQ.jpeg) 1、Set> entrySet():将集合的所有映射关系存储到一个Set集合中,返回该集合,而这个映射关系的类型就是Map.Entry Entry也是一个接口,它是Map接口中的一个内部接口,之所以定义在内部是因为只有有了Map集合,有了键值对,才会有键值的映射关系。关系属于Map集合中的一个内部事物。而且该事物在直接访问Map集合中的元素。 类似于迭代器,这个接口中定义了获取键和获取值的抽象方法,该接口只能通过entrySet方法创建一个存储着该接口子类类型的Set集合,而Set集合迭代器迭代到的就是Map.Entry的子类对象 代码示例: ```java import java.util.*; class MapDemo2 { public static void main(String[] args) { Map map = new HashMap(); map.put("02","zhangsan2"); map.put("03","zhangsan3"); map.put("01","zhangsan1"); map.put("04","zhangsan4"); //将Map集合中的映射关系取出。存入到Set集合中。 Set> entrySet = map.entrySet(); Iterator> it = entrySet.iterator(); while(it.hasNext()) { Map.Entry me = it.next(); String key = me.getKey(); String value = me.getValue(); System.out.println(key+":"+value); } } } ``` ![](https://statics.caijw.com/uploads/2014/09/gZpxiz2xoHMgwxZsOAkvvFIuKIY2IWHvS9p2aTFt.jpeg) ## Map集合及其子类集合的练习 什么时候使用map集合呢? 当数据之间存在这映射关系时,就要先想map集合。 练习1: 每一个学生都有对应的归属地。学生Student,地址String。 学生类属性:姓名,年龄。 注意:姓名和年龄相同的视为同一个学生,保证学生的唯一性。 ```java /* 思路: 1,描述学生。 2,定义map容器。将学生作为键,地址作为值。存入。 3,获取map集合中的元素。 */ import java.util.*; class Student implements Comparable { private String name; private int age; Student(String name,int age) { this.name = name; this.age = age; } public int compareTo(Student s) { int num = new Integer(this.age).compareTo(new Integer(s.age)); if(num==0) return this.name.compareTo(s.name); return num; } public int hashCode() { return name.hashCode()+age*34; } public boolean equals(Object obj) { if(!(obj instanceof Student)) throw new ClassCastException("类型不匹配"); Student s = (Student)obj; return this.name.equals(s.name) && this.age==s.age; } public String getName() { return name; } public int getAge() { return age; } public String toString() { return name+":"+age; } } class MapTest { public static void main(String[] args) { HashMap hm = new HashMap(); hm.put(new Student("lisi1",21),"beijing"); hm.put(new Student("lisi1",21),"tianjin"); hm.put(new Student("lisi2",22),"shanghai"); hm.put(new Student("lisi3",23),"nanjing"); hm.put(new Student("lisi4",24),"wuhan"); //第一种取出方式 keySet Set keySet = hm.keySet(); Iterator it = keySet.iterator(); while(it.hasNext()) { Student stu = it.next(); String addr = hm.get(stu); System.out.println(stu+".."+addr); } //第二种取出方式 entrySet Set> entrySet = hm.entrySet(); Iterator> iter = entrySet.iterator(); while(iter.hasNext()) { Map.Entry me = iter.next(); Student stu = me.getKey(); String addr = me.getValue(); System.out.println(stu+"........."+addr); } } } ``` 练习2: "sdfgzxcvasdfxcvdf"获取该字符串中的字母出现的次数。希望打印结果:a(1)c(2)..... 通过结果发现,每一个字母都有对应的次数,说明字母和次数之间都有映射关系,当发现有映射关系时,可以选择map集合,因为map集合中存放就是映射关系。 ```java /* 思路: 1,将字符串转换成字符数组。因为要对每一个字母进行操作。 2,定义一个map集合,因为打印结果的字母有顺序,所以使用treemap集合。 3,遍历字符数组。 将每一个字母作为键去查map集合。 如果返回null,将该字母和1存入到map集合中。 如果返回不是null,说明该字母在map集合已经存在并有对应次数。 那么就获取该次数并进行自增。,然后将该字母和自增后的次数存入到map集合中。覆盖调用原理键所对应的值。 4,将map集合中的数据变成指定的字符串形式返回。 */ import java.util.*; class MapTest3 { public static void main(String[] args) { String s= charCount("ak+abAf1c,dCkaAbc-defa"); System.out.println(s); } public static String charCount(String str) { char[] chs = str.toCharArray(); TreeMap tm = new TreeMap(); int count = 0;//虽然定义在for循环中第一行可以不用最后重置为0,但为节省空间考虑。还是定义在外面好 for(int x=0; x='a' && chs[x]<='z' || chs[x]>='A' && chs[x]<='Z')) continue; Integer value = tm.get(chs[x]); if(value!=null) count = value; count++; tm.put(chs[x],count);//直接往集合中存储字符和数字,为什么可以,因为自动装箱。 count = 0;//每次循环结束都要清为0 } //System.out.println(tm); StringBuilder sb = new StringBuilder(); Set> entrySet = tm.entrySet(); Iterator> it = entrySet.iterator(); while(it.hasNext()) { Map.Entry me = it.next(); Character ch = me.getKey(); Integer value = me.getValue(); sb.append(ch+"("+value+")"); } return sb.toString(); } } ``` ## Map扩展知识 在很多项目中,应用比较多的是一对多的映射关系,这就可以通过嵌套的形式将多个映射定义到一个大的集合中,并将大的集合分级处理,形成一个体系。 代码示例: ```java /* map集合被使用是因为具备映射关系。 以下是班级对应学生,而学生中学号对应着姓名的映射关系: "yureban" Student("01" "zhangsan"); "yureban" Student("02" "lisi"); "jiuyeban" "01" "wangwu"; "jiuyeban" "02" "zhaoliu"; 就如同一个学校有多个教室。每一个教室都有名称。 */ import java.util.*; class MapExpandKnow { public static void main(String[] args) { //预热班集合 HashMap yureban=new HashMap(); //就业班集合 HashMap jiuyeban=new HashMap(); //学校集合 HashMap> czbk=new HashMap>(); //学校中班级集合和名称的映射 czbk.put("yureban",yureban); czbk.put("jiuyueban",jiuyeban); //预热班级中学号与姓名的映射 yureban.put("01","zhangsan"); yureban.put("02","lisi"); //就业班级中学号与姓名的映射 jiuyeban.put("01","wangwu"); jiuyeban.put("02","zhouqi"); //直接显示全部学生信息 getAllStudentInfo(czbk); } //定义一个方法获取全部学生信息,包括在哪个班级,叫什么名字,学号多少 public static void getAllStudentInfo(HashMap> hm) { for (Iterator it=hm.keySet().iterator();it.hasNext() ; )//用keySet取出方式 { String s= it.next();//班级名称 System.out.println(s+":"); HashMap stu=hm.get(s);//班级集合 getStudentInfo(stu); } } //获取班级中学生的信息,包括姓名和学号 public static void getStudentInfo(HashMap hm) { for (Iterator it=hm.keySet().iterator();it.hasNext() ; ) { String key=it.next();//学号 String value=hm.get(key);//姓名 System.out.println(key+"..."+value); } } } ``` -separator-
void print(Q q)//泛型方法的参数和泛型类不能一样 { System.out.println("print:"+q); } public static void method(W t)//静态方法不能调用泛型类的参数,只能自己定义泛型方法 { System.out.println("method:"+t); } } class GenericDemo4 { public static void main(String[] args) { Demo d = new Demo(); d.show("haha"); //d.show(4); d.print(5); d.print("hehe"); Demo.method("hahahahha"); } } ``` ## 泛型接口的介绍和使用 自定义接口用到泛型的不多,只会用到JAVA提供的泛型接口,只要了解原理就可以,泛型定义在接口上。 接口定义泛型,类在实现的时候有两种实现方法 ```java interface Inter { void show(T t); } class InterImpl_1 implements Inter//实现时候可以确定传入类型 { public void show(String t) { System.out.println("show :"+t); } } class InterImpl_2 implements Inter//实现时候不能确定传入类型,此时和泛型类一样 { public void show(T t) { System.out.println("show :"+t); } } class GenericDemo5 { public static void main(String[] args) { InterImpl_1 i = new InterImpl_1();//已经定义好,只能传字符串 i.show("haha"); InterImpl_2 i = new InterImpl_2();//和泛型类一样 i.show(4); } } ``` ## 通配符与泛型限定 1、当传入的类型不确定时,可以使用通配符?。也可以理解为占位符。使用通配符的好处是可以不用明确传入的类型,这样在使用泛型类或者泛型方法时,提高了扩展性。 2、泛型的限定: 上限:? extends E: 可以接收E类型或者E的子类型。 下限:? super E: 可以接收E类型或者E的父类型。 # 集合框架顶层之Map Map是一个接口,和Collection接口一样同属于集合框架的顶层,该体系存储的是一对数据,键值对,而且要确保键的唯一性 所属关系: Map |--Hashtable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。JDK1.0,效率低。 |--HashMap:底层是哈希表数据结构。允许使用null键null值,该集合是不同步的。JDK1.2,效率高。 |--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给Map集合中的键进行排序。 注:Map和Set看上去很像,其实Set在底层就是调用了Map集合的方法 ## Map集合中的共性方法 1、增加 V put(K key,V value):添加元素,如果添加时,存在该键值,那么新键值对会覆盖老键值对,并返回被覆盖的值。 void putAll(Map extends K,? extends V> m):添加一个集合 2、删除 void clear():清空集合中的所有键值对 V remove(Object key):删除键为key的映射关系(如果存在,返回key对应的值),如果不存在返回null 3、判断 boolean containsKey(Object key):判断该键是否存在 boolean containsValue(Object value):判断该值是否存在 boolean isEmpty():判断集合是否为空 4、获取 V get(Object key):通过键获取值,如果不存在返回null int size():获取该集合的长度 Collectionvalues():获取Map集合中所以得值,返回一个Collection集合 还有两个取出方法,是map集合的重点 Set keySet():将集合的所有键存储到一个Set集合中,返回该集合 Set> entrySet():将集合的所有映射关系存储到一个Set集合中,返回该集合 注:HashMap集合可以通过get()方法的返回值来判断一个键是否存在,通过返回null来判断。(虽然在hashMap中可以存入null键,会影响正常的判断,但由于大部分开发null键无意义,故而可以使用这种方法进行判断) 上述方法的代码演示: ```java import java.util.*; class MapDemo { public static void main(String[] args) { Map map = new HashMap(); //添加元素,添加元素,如果出现添加时,相同的键。那么后添加的值会覆盖原有键对应值。 //并put方法会返回被覆盖的值。 System.out.println("put:"+map.put("01","zhangsan1")); System.out.println("put:"+map.put("01","wnagwu")); map.put("02","zhangsan2"); map.put("03","zhangsan3"); System.out.println("containsKey:"+map.containsKey("022")); //System.out.println("remove:"+map.remove("02")); System.out.println("get:"+map.get("023")); map.put("04",null); System.out.println("get:"+map.get("04")); //可以通过get方法的返回值来判断一个键是否存在。通过返回null来判断。 //获取map集合中所有的值。 Collection coll = map.values(); System.out.println(coll); System.out.println(map); } } ``` ## Map集合的两种取出方式 Map集合的取出原理:将Map集合转成Set集合。再通过迭代器取出。 1、Set keySet():将集合的所有键存储到一个Set集合中,返回该集合,在通过集合的迭代器获取Set集合中存放的Map集合的键,在用Map集合的get方法获取该键对应的值,从而得到Map集合的所有元素并对其操作 代码示例: ```java import java.util.*; class MapDemo2 { public static void main(String[] args) { Map map = new HashMap(); map.put("02","zhangsan2"); map.put("03","zhangsan3"); map.put("01","zhangsan1"); map.put("04","zhangsan4"); //先获取map集合的所有键的Set集合,keySet(); Set keySet = map.keySet(); //有了Set集合。就可以获取其迭代器。 Iterator it = keySet.iterator(); while(it.hasNext()) { String key = it.next(); //有了键可以通过map集合的get方法获取其对应的值。 String value = map.get(key); System.out.println("key:"+key+",value:"+value); } } } ``` ![](https://statics.caijw.com/uploads/2014/09/El2rxBCcQ30pgpZewJA5uvSF0nLBTLT7h7oJUsCQ.jpeg) 1、Set> entrySet():将集合的所有映射关系存储到一个Set集合中,返回该集合,而这个映射关系的类型就是Map.Entry Entry也是一个接口,它是Map接口中的一个内部接口,之所以定义在内部是因为只有有了Map集合,有了键值对,才会有键值的映射关系。关系属于Map集合中的一个内部事物。而且该事物在直接访问Map集合中的元素。 类似于迭代器,这个接口中定义了获取键和获取值的抽象方法,该接口只能通过entrySet方法创建一个存储着该接口子类类型的Set集合,而Set集合迭代器迭代到的就是Map.Entry的子类对象 代码示例: ```java import java.util.*; class MapDemo2 { public static void main(String[] args) { Map map = new HashMap(); map.put("02","zhangsan2"); map.put("03","zhangsan3"); map.put("01","zhangsan1"); map.put("04","zhangsan4"); //将Map集合中的映射关系取出。存入到Set集合中。 Set> entrySet = map.entrySet(); Iterator> it = entrySet.iterator(); while(it.hasNext()) { Map.Entry me = it.next(); String key = me.getKey(); String value = me.getValue(); System.out.println(key+":"+value); } } } ``` ![](https://statics.caijw.com/uploads/2014/09/gZpxiz2xoHMgwxZsOAkvvFIuKIY2IWHvS9p2aTFt.jpeg) ## Map集合及其子类集合的练习 什么时候使用map集合呢? 当数据之间存在这映射关系时,就要先想map集合。 练习1: 每一个学生都有对应的归属地。学生Student,地址String。 学生类属性:姓名,年龄。 注意:姓名和年龄相同的视为同一个学生,保证学生的唯一性。 ```java /* 思路: 1,描述学生。 2,定义map容器。将学生作为键,地址作为值。存入。 3,获取map集合中的元素。 */ import java.util.*; class Student implements Comparable { private String name; private int age; Student(String name,int age) { this.name = name; this.age = age; } public int compareTo(Student s) { int num = new Integer(this.age).compareTo(new Integer(s.age)); if(num==0) return this.name.compareTo(s.name); return num; } public int hashCode() { return name.hashCode()+age*34; } public boolean equals(Object obj) { if(!(obj instanceof Student)) throw new ClassCastException("类型不匹配"); Student s = (Student)obj; return this.name.equals(s.name) && this.age==s.age; } public String getName() { return name; } public int getAge() { return age; } public String toString() { return name+":"+age; } } class MapTest { public static void main(String[] args) { HashMap hm = new HashMap(); hm.put(new Student("lisi1",21),"beijing"); hm.put(new Student("lisi1",21),"tianjin"); hm.put(new Student("lisi2",22),"shanghai"); hm.put(new Student("lisi3",23),"nanjing"); hm.put(new Student("lisi4",24),"wuhan"); //第一种取出方式 keySet Set keySet = hm.keySet(); Iterator it = keySet.iterator(); while(it.hasNext()) { Student stu = it.next(); String addr = hm.get(stu); System.out.println(stu+".."+addr); } //第二种取出方式 entrySet Set> entrySet = hm.entrySet(); Iterator> iter = entrySet.iterator(); while(iter.hasNext()) { Map.Entry me = iter.next(); Student stu = me.getKey(); String addr = me.getValue(); System.out.println(stu+"........."+addr); } } } ``` 练习2: "sdfgzxcvasdfxcvdf"获取该字符串中的字母出现的次数。希望打印结果:a(1)c(2)..... 通过结果发现,每一个字母都有对应的次数,说明字母和次数之间都有映射关系,当发现有映射关系时,可以选择map集合,因为map集合中存放就是映射关系。 ```java /* 思路: 1,将字符串转换成字符数组。因为要对每一个字母进行操作。 2,定义一个map集合,因为打印结果的字母有顺序,所以使用treemap集合。 3,遍历字符数组。 将每一个字母作为键去查map集合。 如果返回null,将该字母和1存入到map集合中。 如果返回不是null,说明该字母在map集合已经存在并有对应次数。 那么就获取该次数并进行自增。,然后将该字母和自增后的次数存入到map集合中。覆盖调用原理键所对应的值。 4,将map集合中的数据变成指定的字符串形式返回。 */ import java.util.*; class MapTest3 { public static void main(String[] args) { String s= charCount("ak+abAf1c,dCkaAbc-defa"); System.out.println(s); } public static String charCount(String str) { char[] chs = str.toCharArray(); TreeMap tm = new TreeMap(); int count = 0;//虽然定义在for循环中第一行可以不用最后重置为0,但为节省空间考虑。还是定义在外面好 for(int x=0; x='a' && chs[x]<='z' || chs[x]>='A' && chs[x]<='Z')) continue; Integer value = tm.get(chs[x]); if(value!=null) count = value; count++; tm.put(chs[x],count);//直接往集合中存储字符和数字,为什么可以,因为自动装箱。 count = 0;//每次循环结束都要清为0 } //System.out.println(tm); StringBuilder sb = new StringBuilder(); Set> entrySet = tm.entrySet(); Iterator> it = entrySet.iterator(); while(it.hasNext()) { Map.Entry me = it.next(); Character ch = me.getKey(); Integer value = me.getValue(); sb.append(ch+"("+value+")"); } return sb.toString(); } } ``` ## Map扩展知识 在很多项目中,应用比较多的是一对多的映射关系,这就可以通过嵌套的形式将多个映射定义到一个大的集合中,并将大的集合分级处理,形成一个体系。 代码示例: ```java /* map集合被使用是因为具备映射关系。 以下是班级对应学生,而学生中学号对应着姓名的映射关系: "yureban" Student("01" "zhangsan"); "yureban" Student("02" "lisi"); "jiuyeban" "01" "wangwu"; "jiuyeban" "02" "zhaoliu"; 就如同一个学校有多个教室。每一个教室都有名称。 */ import java.util.*; class MapExpandKnow { public static void main(String[] args) { //预热班集合 HashMap yureban=new HashMap(); //就业班集合 HashMap jiuyeban=new HashMap(); //学校集合 HashMap> czbk=new HashMap>(); //学校中班级集合和名称的映射 czbk.put("yureban",yureban); czbk.put("jiuyueban",jiuyeban); //预热班级中学号与姓名的映射 yureban.put("01","zhangsan"); yureban.put("02","lisi"); //就业班级中学号与姓名的映射 jiuyeban.put("01","wangwu"); jiuyeban.put("02","zhouqi"); //直接显示全部学生信息 getAllStudentInfo(czbk); } //定义一个方法获取全部学生信息,包括在哪个班级,叫什么名字,学号多少 public static void getAllStudentInfo(HashMap> hm) { for (Iterator it=hm.keySet().iterator();it.hasNext() ; )//用keySet取出方式 { String s= it.next();//班级名称 System.out.println(s+":"); HashMap stu=hm.get(s);//班级集合 getStudentInfo(stu); } } //获取班级中学生的信息,包括姓名和学号 public static void getStudentInfo(HashMap hm) { for (Iterator it=hm.keySet().iterator();it.hasNext() ; ) { String key=it.next();//学号 String value=hm.get(key);//姓名 System.out.println(key+"..."+value); } } } ``` -separator-