Map扩展这一节,学起来挺绕人的,尤其是在加入了泛型之后,视频看了三遍最后还是要记录下来,方便以后复习。
感觉思路比代码重要,自己费了老大劲编出一个坨坨般的程序,编译还会出很多问题,昏天黑地的,但是老师的视频讲解一看,感觉简单的要命,
也不知道问题到底出在哪里,估计是做题太少,练习不够,经验要加强,不能好高骛远。学基础一定要多做练习,下一本习题来做才好。
分析的思路一定要清晰,不分析清晰了,直接写,肯定是坨坨。
需求:遍历一个学校的学生。
分析:班级---学号---学生:映射关系,选择Map
学校:Map school:通过班级的名称检索班级Map classX,所以泛型为<String,Map<String,Student>>
班级:Map classX:通过学号检索学生Student,所以泛型是<String,Student>
第一步存储信息:
Map<String,Map<String,Student>> school=new HashMap<String,Map<String,Student>>();//创建容器
Map<String,Student> class_1=new HashMap<String,Student>();
Map<String,Student> class_2=new HashMap<String,Student>();
Map<String,Student> class_3=new HashMap<String,Student>();
school.put("class_1",class_1);//将检索班级名和班级容器映射存入Map school中
school.put("class_2",class_2);
school.put("class_3",class_3);
class_1.put("id001",new Student("jack","male",15));//将检索学号和学生对象映射存入Map classX中
class_2.put("id002",new Student("queen","female",35));
class_3.put("id003",new Student("king","male",45));
存储完毕。
第二步遍历:
有两层检索:在学校中检索班级名,获取班级;在班级中检索学号,获取学生;最终目的获取所有的学生,即遍历。
首先,小圈或者说内圈先遍历。然后,在大圈中调用小圈即可。
①向方法中传递班级Map作为参数,然后遍历此班级,返回Student对象:
public static Student getStudent(Map<String,Student> class_x)//注意泛型格式
//为了书写方便,这里采用keySet()方法来获取检索Set。
Set<String> ks=class_x.keySet();
//为了书写方便,这里采用while循环格式进行迭代。
Iterator<String> it=ks.iterator();
while(it.hasNext())
String id=it.next();
return Student st=class_x.get(id);//代码中注意合并id,省略st。
②向方法中传递学校Map作为参数,然后遍历学校,可以返回Student并存放在一个List中,这里我直接打印。
public static void getAllStudent(Map<String,Map<String,Student>> school )
Set<String> ks=school.keySet();//获取班级名检索Set
for(Iterator<String> it=ks.iterator();it.hasNext;)
//这时候it.next()取出的是班级名,使用班级名取出班级,然后将班级作为参数传递,调用getStudent()方法。
sop(getStudent(school.get(it.next())));//直接打印Student,下面要在Student中覆写toString()方法。
第三步,补充完善Student类
为了使这个类适应Hash结构集合和Set类集合:在Student中覆写equals(),hashCode()方法,并且实现Comparable<Student>,覆写compareTo();
为了直接打印这个类的对象,覆写toString()方法;
Hash机构中,比如HashSet是先判断hashCode是否重复,重复时才判断元素是否相同equals;
public int hashCode()//覆写的hashCode和equals都来自Object类,不要改变返回值类型,也不要使用泛型。
return name.hashCode()+sex.hashCode()*34+age;//这里希望按照哪个因素排列,可以扩大其权重。
public boolean equals(Object obj)
if(!(obj instanceof Student))
throw new ClassCastException("无效的类型");
Student s=(Student)obj;
return this.name.equals(s.name)&&this.sex.equals(s.sex)&&this.age==s.age;
public int compareTo(Student s)
int m=this.age-s.age;
if(m==0)
m=this.sex.compareTo(s.sex);
if(m==0)
m=this.name.compareTo(s.name);
return m;
public String toString()
return name+"------"+sex+"------"+age;
泛型的使用需要重新深入复习。
思路分析完毕,形成代码:
import java.util.*;
public class MapPlus2
{
public static void main(String[]args)
{
Map<String,Map<String,Student>> school=new HashMap<String,Map<String,Student>>();//创建容器
Map<String,Student> class_1=new HashMap<String,Student>();
Map<String,Student> class_2=new HashMap<String,Student>();
Map<String,Student> class_3=new HashMap<String,Student>();
school.put("class_1",class_1);//将检索班级名和班级容器映射存入Map school中
school.put("class_2",class_2);
school.put("class_3",class_3);
class_1.put("id001",new Student("jack","male",15));//将检索学号和学生对象映射存入Map classX中
class_2.put("id002",new Student("queen","female",35));
class_3.put("id003",new Student("king","male",45));
getAllStudent(school);
}
public static void getAllStudent(Map<String,Map<String,Student>> school)
{
Set<String> ks=school.keySet();//获取班级名检索Set
for(Iterator<String> it=ks.iterator();it.hasNext();)
sop(getStudent(school.get(it.next())));//直接打印Student,下面要在Student中覆写toString()方法。
}
public static Student getStudent(Map<String,Student> class_x)//注意泛型方法的格式
{
Set<String> ks=class_x.keySet();
Iterator<String> it=ks.iterator();
while(it.hasNext())
{
return class_x.get(it.next());
}
return null;
}
public static<T> void sop(T t)
{
System.out.println(t);
}
}
class Student implements Comparable<Student>
{
private String name;
private String sex;
private int age;
Student(String name,String sex,int age)
{
this.name=name;
this.sex=sex;
this.age=age;
}
public String getName()
{
return name;
}
public String getSex()
{
return sex;
}
public int getAge()
{
return age;
}
public boolean equals(Object obj)
{
if(!(obj instanceof Student))
throw new ClassCastException("类型不匹配");
Student s=(Student)obj;
return this.name.equals(s.name)&&this.sex.equals(s.sex)&&this.age==s.age;
}
public int hashCode()
{
return name.hashCode()+sex.hashCode()*34+age;
}
public String toString()
{
return name+"------"+sex+"------"+age;
}
public int compareTo(Student s)
{
int num=this.age-s.age;
if(num==0)
{
num=this.sex.compareTo(s.sex);
if(num==0)
num=this.name.compareTo(s.name);
}
return num;
}
}
打印结果:
jack------male------15
queen------female------35
king------male------45
这篇文章算是一个阶段性的总结整合,收获颇多,思路清晰了代码就是直接将思路复制进格式里罢了,错误很少,整体把握也容易。
记录如上。