34.Map

Map集合:该集合存储键值对。一对一对往里存,而且要保证键的唯一性。每个键最多只能映射到一个值。
1.添加
  put(K key,V value)
  putAll(Map<? extends K,? extends V> m)
2.删除
  clear()
  remove(Object key)
3.判断
  containsValue(Object value)
  containsKey(Object key)
  isEmpty
4.获取
  get(Object key)
  size()
  values()

  entrySet()
  keySet()

Map
  --HashTable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。效率低
  --HashMap:底层是哈希表数据结构,允许使用null键null值。该集合是不同步的。效率高
  --TreeMap:底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。

和Set很像,Set底层就是使用了Map集合。

public class Map_01 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Map<String,String> map=new HashMap<String,String>();
        
        //添加元素,如果出现相同的键,那么后添加的值会覆盖原有键的对应值。打印时put方法返回原有键的值。
        System.out.println("put:"+map.put("01", "zhangsan1"));
        System.out.println("put:"+map.put("01", "zhangsan11"));
        map.put("02", "zhangsan2");
        map.put("03", "zhangsan3");
        map.put("04","lisi");
        
        System.out.println("containsKey:"+map.containsKey("01"));
        System.out.println("remove:"+map.remove("022")); //键不存在返回null,存在返回键对应的值
        
        System.out.println("get:"+map.get("022"));////键不存在返回null,存在返回键对应的值
        
        map.put(null,"zhangsan4");
        System.out.println("getnull:"+map.get(null));//可以通过get方法的返回值来判断一个键是否存在,通过返回Null来判断
        
        map.put("05", null);
        System.out.println("get04:"+map.get("05"));
        
        
        System.out.println(map); //键值对
        
        //获取Map集合中所有的值
        Collection<String> coll=map.values(); //
         System.out.println("mapvalue:"+coll);
    }

}

 

Map集合的两种取出方式:
1.Set<key> keySet:将Map中所有键存入到Set集合。因为Set集合具备迭代器,所以可以通过迭代方式取出所有的键,根据get方法,获取每一个键对应的值。
Map集合的取出原理:将map集合转成set集合,再通过迭代器取出。
2.Set<Map.Entry<k,v>> entrySet:将Map集合中的映射关系存入早set集合中,而这个关系的数据类型就是:Map.Entry

 

entrySet

Map.Entry 其实Entry也是一个接口,它是Map接口 中的一个内部接口

public class Map_entrySet_02 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Map<String,String> map=new HashMap<String,String>();
        
        map.put("02", "zhangsan2");
        map.put("03", "zhangsan3");
        map.put("01", "zhangsan1");
        map.put("04", "zhangsan4");
        
        //将Map集合中的映射关系取出。存入到Set集合中    
        Set<Map.Entry<String,String>> entrySet =map.entrySet();
        
        Iterator<Map.Entry<String,String>> it=entrySet.iterator();
        
        while(it.hasNext()){
            Map.Entry<String,String> me=it.next();
            String key=me.getKey();
            String value=me.getValue();
            System.out.println("key:"+key+",value:"+value);
        }
    }
}

 

keySet

public class Map_keySet_03 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Map<String,String> map=new HashMap<String,String>();
        
        map.put("02", "zhangsan2");
        map.put("03", "zhangsan3");
        map.put("01", "zhangsan1");
        map.put("04", "zhangsan4");
        
        //先获取Map集合中所有键的Set集合
        Set<String> keySet=map.keySet();
        
        //有了Set集合,就可以获取迭代器
        Iterator<String> it=keySet.iterator();
        
        while(it.hasNext()){
            String key=it.next();
            
            //有了键,就可以通过Map集合的get方法获取其对应的值
            String value=map.get(key);
            System.out.println("key:"+key+",value="+value);
        }
    }
}

 

练习:
每个学生都有对应的归属地。学生Student,地址String。学生属性:姓名,年龄。
注意:姓名和年龄相同的视为同一学生,保证学生的唯一性。

1.描述学生
2.定义Map容器,将学生作为键,地址作为值,存入。
3.获取map集合中的元素

public class HashMap_04 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        HashMap<Student,String> hm=new HashMap<Student,String>();
        
        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<Student> keySet=hm.keySet();
        
        Iterator<Student> it=keySet.iterator();
        while(it.hasNext()){
            Student s=it.next();
            String addr=hm.get(s);
            System.out.println(s+","+addr);
        }
        
        //第二种取出方式:entrySet()
        Set<Entry<Student, String>> entrySet=hm.entrySet();
        
        Iterator<Entry<Student,String>> it1=entrySet.iterator();
        while(it1.hasNext()){
            Entry<Student,String> e=it1.next();
            Student s=e.getKey();
            String str=e.getValue();
            System.out.println(s+"---"+str);
        }
    }

}
class  Student implements Comparable<Student>{
    private String name;
    private int age;
    
    
    public String getName() {
        return name;
    }


    public void setName(String name) {
        this.name = name;
    }


    public int getAge() {
        return age;
    }


    public void setAge(int age) {
        this.age = age;
    }


    Student(String name,int age){
        this.name=name;
        this.age=age;
    }

    public String toString(){
        return name+":"+age;
    }
    
    public int hashCode(){
        return name.hashCode()+age*34;
    }
    
    public boolean equals(Object obj){
        if(!(obj instanceof Student)){
            throw new ClassCastException("传入的不是Student类");
        }
        
        Student s=(Student) obj;
        
        return this.name.equals(s.name) && (this.age==s.age);
    }

    //学生对象可能存到二叉树里,按年龄排序
    public int compareTo(Student o) {
        System.out.println("compareTo~~~~~~~~~~~~");
        int num=new Integer(this.age).compareTo(new Integer(o.age));
        if(num ==0){
            return this.name.compareTo(o.name);
        }
        return num;
    }
}

 

需求:对工人对象的年龄进行升序排列

因为数据是以键值对的形式存在的。所以要使用可以排序的Map集合。TreeMap

之后要求按姓名排序。工人类不能随意更改,指定一个比较器

public class TreeMap_05 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //TreeMap<Worker,String> hm=new TreeMap<Worker,String>();
        
        //自定义排序
        TreeMap<Worker,String> hm=new TreeMap<Worker,String>(new Com());
        
        hm.put(new Worker("lisi1",27),"beijing");
        hm.put(new Worker("lisi1",21),"tianjin"); //被视为同一个人
        hm.put(new Worker("lisi2",25),"shanghai");
        hm.put(new Worker("lisi3",23),"nanjing");
        hm.put(new Worker("lisi4",24),"wuhan");
        
        Set<Entry<Worker,String>> entrySet=hm.entrySet();
        
        Iterator<Entry<Worker,String>> it=entrySet.iterator();
        while(it.hasNext()){
            Entry<Worker,String> e=it.next();
            Worker w=e.getKey();
            String s=e.getValue();
            System.out.println(w+":"+s);
        }
    }

}
class  Worker implements Comparable<Worker>{
    private String name;
    private int age;
    
    
    public String getName() {
        return name;
    }


    public void setName(String name) {
        this.name = name;
    }


    public int getAge() {
        return age;
    }


    public void setAge(int age) {
        this.age = age;
    }


    Worker(String name,int age){
        this.name=name;
        this.age=age;
    }

    public String toString(){
        return name+":"+age;
    }
    
    public int hashCode(){
        return name.hashCode()+age*34;
    }
    
    public boolean equals(Object obj){
        if(!(obj instanceof Student)){
            throw new ClassCastException("传入的不是Worker类");
        }
        
        Worker s=(Worker) obj;
        
        return this.name.equals(s.name) && (this.age==s.age);
    }


    public int compareTo(Worker o) {
        int num=new Integer(this.age).compareTo(new Integer(o.age));
        if(num ==0){
            return this.name.compareTo(o.name);
        }
        return num;
    }
}

class Com implements Comparator{

    @Override
    public int compare(Object o1, Object o2) {
        // TODO Auto-generated method stub
        
        Worker w1=(Worker) o1;
        Worker w2=(Worker) o2;
        
        int num=w1.getName().compareTo(w2.getName());
        if(num==0){
            return new Integer(w1.getAge()).compareTo(w2.getAge());
        }
        
        return num;
    }
    
}

 

练习:
"sdfgzxcvasdfxcvdf"获取该字符串中字母出现的次数。

希望打印结果a(1)c(2)

通过结果发现每个字母都有对应的次数。说明字母和次数之间有映射关系

注意:
当发现有映射关系时,可以选择map集合。因为map集合中存放的就是映射关系。

什么时候使用map集合呢?
当数据之间存在着映射关系时,就要先想到map集合

思路:
  1.将字符串转换成字符数组,因为要对每一个字母进行操作。
  2.定义一个map集合,因为打印结果的字母有顺序,所以使用treemap集合
  3.遍历字符数组
    将每一个字母作为键去查map集合。如果返回null,将该字母和1存入到map集合中
    如果返回不是null,说明该字母在map集合内已经存在,并有对应的次数,那么就获取该次数并进行自增。
    然后将该字母和自增后的次数存入到map集合中,覆盖调用原来键所对应的值
  4.将map集合中的数据变成指定的字符串形式返回。

public class TreeMap_06 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String s="sdf,gzxcv-asdfxc?vdf";
        System.out.println(charCount(s));
    }
    
    public static String charCount(String str){
        
        //得到字符数组
        char [] chs=str.toCharArray();
        
        TreeMap<Character,Integer> tm=new TreeMap<Character,Integer>();//泛型中接收的都是引用数据类型,int char为基本数据类型
        
        for(int x=0;x<chs.length;x++){
            
            //不是字母
            if(!(chs[x]>='a' && chs[x]<='z' || chs[x]>='A' && chs[x]<='Z')){
                continue;
            }
            
            //集合中元素出现的次数
            Integer value=tm.get(chs[x]);
            
            if(value == null){
                tm.put(chs[x], 1);
            }else{
                value=value+1;
                tm.put(chs[x],value);
            }
        }
        
        System.out.println(tm); //得到集合
        
        StringBuffer bf=new StringBuffer();
        
        Set<Entry<Character,Integer>> set=tm.entrySet();
        
        Iterator<Entry<Character,Integer>> it=set.iterator();
        while(it.hasNext()){
            Entry<Character,Integer> e=it.next();
            Character c=e.getKey();
            Integer i=e.getValue();
            //System.out.println(c+"("+i+")"); 
            
            bf.append(c+"("+i+")");
        }
        
        return bf.toString();
    }
}

 

map扩展知识

map集合被使用是因为具备映射关系。

"数学班" "01" "zhangsan"
"数学班" "02" "lisi"

"化学班" "01" "wangwu"
"化学班" "02" "zhaoliu"

一个学校有多个教室,每个教室多个学生

获取每个班的班级名称、学生Id及姓名

public class Map_07 {

    public static void main(String[] args) {
        
        /*HashMap<String,HashMap<String,String>> school=new HashMap<String,HashMap<String,String>>();
        
        HashMap<String,String> math=new HashMap<String,String>();
        
        HashMap<String,String> chemical=new HashMap<String,String>();
        
        school.put("数学班", math);
        school.put("化学班", chemical);
        
        math.put("01", "zhangsan");
        math.put("02", "lisi");
        
        chemical.put("01", "wangwu");
        chemical.put("02", "zhaoliu");*/
        
        HashMap<String,HashMap<String,String>> school=new HashMap();
        HashMap<String,String> math=new HashMap();
        HashMap<String,String> chemical=new HashMap();
        
        school.put("数学班", math);
        school.put("化学班",chemical);
        
        math.put("01", "张三");
        math.put("02","李四");
        
        chemical.put("01","王五");
        chemical.put("02", "赵六");
        
        //获取学校所有班的键
        Set<String> cl=school.keySet();
        
        Iterator<String> it=cl.iterator();
        while(it.hasNext()){
            String clKey=it.next(); //获取每个班级键
            System.out.println(clKey+"--");
            HashMap<String,String> room=school.get(clKey);  //获取每个班级名称
            //System.out.println(room);
            getStuInfo(room);
        }
    }
    
    //获取每个班学生及编号
    public static void getStuInfo(HashMap<String,String> roomMap){ // HashMap hm,String room 告诉学校,教室
        
        Set<String> room=roomMap.keySet();
        
        Iterator<String> it=room.iterator();
        while(it.hasNext()){
            String id=it.next();
            String name=roomMap.get(id);
            System.out.println("id:"+id+",name:"+name);
        }
    }
}

 

转载于:https://www.cnblogs.com/syj1993/p/8336385.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值