Java集合框架(三)

   Map

   Map集合:该集合存储键值对,一对一对的往里存,而且要保证键的唯一性。

   Map

  |------HashTable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。JDK1.0,效率低。

  |------HashMap:底层是哈希表数据结构,允许使用 null值和 null键,该集合是不同步的。JDK1.2,效率高。

  |------TreeMap:底层是二叉树数据结构,线程不同步,可以给map集合中的键进行排序。

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

   方法总结:

  1、添加

    put(K key, V value)

    putAll(Map<? extends K,? extends V> m)

  2、删除

    clear()

    remove(Object key) 

  3、判断

    containsKey(Object key) 

    containsValue(Object value)

    isEmpty()

  4、获取

    get(Object key) 

    size()

    values()  

    entrySet() 

    keySet() 

   示例代码如下:

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class MapDemo {

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        
        //添加元素
        //添加元素,如果出现添加时,相同的键,那么后添加的值会覆盖原有的键对应的值,并put()方法返回被覆盖的值。
        System.out.println("put:" + map.put("01", "zhangsan01"));//输出null
        System.out.println("put:" + map.put("01", "wangwu"));
        map.put("02", "zhangsan02");
        map.put("03", "zhangsan03");
        
        //System.out.println("containsKey:" + map.containsKey("022"));
        //System.out.println("remove:" + map.remove("02")) ;
        
        //可以通过get()方法的返回值来判断一个键是否存在,通过返回null来判断
        System.out.println("get:" + map.get("023"));
        
        map.put(null, "haha");//HashMap允许使用 null值和 null键
        map.put("04", null);
        
        System.out.println("get:" + map.get("04"));
        System.out.println("get:" + map.get(null));
        
        
        //获取集合中所有的值
        Collection<String> coll = map.values();
        System.out.println(coll);
        System.out.println(map);
        
     }

}

   Map集合的两种取出方式

   Map集合的两种取出方式:

  1、Set<K> keySet():将map所有的键存入到Set集合,因为Set集合具备迭代器,所以可以迭代方式取出所有的键,在根据get()方法,获取每一个键对应的值。

  Map集合的取出原理:将map集合转成set集合,在通过迭代器取出。

  2、Set<Map.Entry<K,V>> entrySet():将map集合中的映射关系存入到了set集合中,而这个关系的数据类型就是:Map.Entry。

  Map.Entry,其实Entry也是一个接口,它是Map接口中的一个内部接口。代码如下:

interface Map {
    public static interface Entry {
        public abstract Object getKey();
        public abstract Object getValue();
    }
}

class HashMap implements Map {
    
    class Haha implements Map.Entry {
        public Object getKey() {
            
        }
        public Object getValue() {
            
        }
    }
    
}

   示例代码:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class MapDemo1 {

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        
        map.put("01", "zhangsan01");
        map.put("02", "zhangsan02");
        map.put("03", "zhangsan03");
        map.put("04", "zhangsan04");
        
        
        //将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 + ":" + value);
        }
        /*
        //先获取map集合的所有的键的Set集合,keySet()
        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);
        }
        */
        
    }

}

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

   分析:

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

   代码如下所示:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

class Student implements Comparable<Student> {
    private String name;
    private int age;
    
    public Student(String name, int age) {
        this.name = name;
        this.age = 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;
    }
    
    @Override
    public boolean equals(Object obj) {
        if(!(obj instanceof Student)) 
            throw new ClassCastException("类型不匹配");
        Student student = (Student) obj;
        return this.name.equals(student.name) &&
                this.age == student.age;
    }

    @Override
    public int hashCode() {
        return name.hashCode() + age * 34;
    }

    public String toString() {
        return name + ":" + age;
    }

    @Override
    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 class MapTest {

    public static void main(String[] args) {
        HashMap<Student, String> map = new HashMap<Student, String>();
        
        map.put(new Student("lisi1", 21), "beijing");
        map.put(new Student("lisi1", 21), "tianjin");
        map.put(new Student("lisi2", 22), "shanghai");
        map.put(new Student("lisi3", 23), "wuhan");
        map.put(new Student("lisi4", 24), "nanjing");
        
        //第一种取出方式  keySet()
        Set<Student> keySet = map.keySet();
        
        Iterator<Student> it = keySet.iterator();
        while(it.hasNext()) {
            Student s = it.next();
            String address = map.get(s);
            System.out.println(s + "..." + address);
        }
        
        //第二种取出方式 entrySet()
        Set<Map.Entry<Student, String>> entrySet = map.entrySet();
        Iterator<Map.Entry<Student, String>> it1 = entrySet.iterator();
        while(it1.hasNext()) {
            Map.Entry<Student, String> me = it1.next();
            Student stu = me.getKey();
            String address = me.getValue();
            System.out.println(stu + "..." + address);
        }
        
    }

}

   练习2:需求:对学生对象的姓名进行升序排序。

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

   代码:

import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

class Student1 implements Comparable<Student1> {
    private String name;
    private int age;
    
    public Student1(String name, int age) {
        this.name = name;
        this.age = 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;
    }
    
    @Override
    public boolean equals(Object obj) {
        if(!(obj instanceof Student1)) 
            throw new ClassCastException("类型不匹配");
        Student1 stu = (Student1) obj;
        return this.name.equals(stu.name) &&
                this.age == stu.age;
    }

    @Override
    public int hashCode() {
        return name.hashCode() + age * 34;
    }

    public String toString() {
        return name + ":" + age;
    }

    @Override
    public int compareTo(Student1 s) {
        int num = new Integer(this.age).compareTo(new Integer(s.age));
        
        if(num == 0) 
            return this.name.compareTo(s.name);
        
        return num;
    }    
}

class StuNameComparator implements Comparator<Student1> {

    @Override
    public int compare(Student1 s1, Student1 s2) {
        int num = s1.getName().compareTo(s2.getName());
        
        if(num == 0) 
            return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
        
        return num;
    }
    
}
public class MapTest1 {

    public static void main(String[] args) {
        Map<Student1, String> tm = new TreeMap<Student1, String>(new StuNameComparator());
        
        tm.put(new Student1("blisi3", 23), "wuhan");
        tm.put(new Student1("lisi1", 21), "beijing");
        tm.put(new Student1("alisi4", 24), "nanjing");
        tm.put(new Student1("lisi1", 21), "tianjin");
        tm.put(new Student1("lisi2", 22), "shanghai");
        
        //System.out.println(tm);
        
        Set<Map.Entry<Student1, String>> entrySet = tm.entrySet();
        
        Iterator<Map.Entry<Student1, String>> it = entrySet.iterator();
        while(it.hasNext()) {
            Map.Entry<Student1, String> me = it.next();
            Student1 stu = me.getKey();
            String addr = me.getValue();
            System.out.println(stu + ":::" + addr);
        }
        
    }

}

   练习3:"sdfgzxcvasdfxcvdf"获取该字符串中的字母出现的次数。希望打印结果:a(1)c(2)...

   分析:

   通过结果发现,每一个字母都有对应的次数。说明字母和次数之间都有映射关系。注意:当发现有映射关系时,可以选择map集合。因为map集合中存放的就是映射关系。

   问:什么时候使用map集合呢?

   答:当数据之间存在着映射关系时,就要先想到map集合。

   本题思路:

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

   代码:

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class MapTest2 {

    public static void main(String[] args) {
        String s = charCount("sdf+gz-x,cvasdf1xcvdfkk");
        System.out.println(s);
    }
    
    public static String charCount(String str) {
        char[] chs = str.toCharArray();
        
        TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();
        
        int count = 0;
        for(int i = 0; i < chs.length; i++) {
            if(!(chs[i] >= 'a' && chs[i] <= 'z' || chs[i] >= 'A' && chs[i] <= 'Z')) 
                continue;//不是字母继续循环
            
            Integer value = tm.get(chs[i]);
            if(value != null) {
                count = value;
            }
            count++;
            tm.put(chs[i], count);
            
            count = 0;
            
            /*
            if(value == null) {
                tm.put(chs[i], 1);
            } else {
                value = value + 1;
                tm.put(chs[i], value);
            }
            */
            
        }
        
        //System.out.println(tm);
        
        StringBuilder sb = new StringBuilder();
        
        Set<Map.Entry<Character, Integer>> entrySet = tm.entrySet();
        
        Iterator<Map.Entry<Character, Integer>> it = entrySet.iterator();
        while(it.hasNext()) {
            Map.Entry<Character, Integer> me = it.next();
            Character ch = me.getKey();
            Integer value = me.getValue();
            sb.append(ch + "(" + value + ")");
        }
        
        return sb.toString();
        
    }

}

   map集合扩展知识——一对多关系

   一对多的关系:一个学校有多个教室,每一个教室都有名称。一个教室有多个学生。

   示例代码:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

/*
map集合扩展知识。

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

"yureban" StudentM("01" "zhangsan")
"yureban" StudentM("02" "lisi")

"jiuyeban" "01" "wangwu"
"jiuyeban" "02" "zhaoliu"

一对多的关系
一个学校有多个教室,每一个教室都有名称。
一个教室有多个学生。

*/
class StudentM {
    private String id;
    private String name;
    
    public StudentM(String id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return id + ":::" + name;
    }
    
    
}
public class MapDemo2 {
    
    public static void demo() {
        HashMap<String, List<StudentM>> czbk = new HashMap<String, List<StudentM>>();
        
        List<StudentM> yure = new ArrayList<StudentM>();
        List<StudentM> jiuye = new ArrayList<StudentM>();
        
        czbk.put("yureban", yure);
        czbk.put("jiuyeban", jiuye);
        
        yure.add(new StudentM("01", "zhangsan"));
        yure.add(new StudentM("04", "wangwu"));
        jiuye.add(new StudentM("01", "zhouqi"));
        jiuye.add(new StudentM("02", "zhaoliu"));
        
        Iterator<String> it = czbk.keySet().iterator();
        
        while(it.hasNext()) {
            String roomName = it.next();
            List<StudentM> room = czbk.get(roomName);
            System.out.println(roomName);
            getInfos(room);
        }
    }
    
    public static void getInfos(List<StudentM> list) {
        Iterator<StudentM> it = list.iterator();
        while(it.hasNext()) {
            StudentM s = it.next();
            System.out.println(s);
        }
    }

    public static void main(String[] args) {
        demo();
        
        /*
        HashMap<String, HashMap<String, String>> czbk = new HashMap<String, HashMap<String, String>>();
        
        HashMap<String, String> yure = new HashMap<String, String>();
        
        HashMap<String, String> jiuye = new HashMap<String, String>();
        
        czbk.put("yureban", yure);
        czbk.put("jiuyeban", jiuye);
        
        yure.put("01", "zhangsan");
        yure.put("02", "lisi");
        
        jiuye.put("01", "zhaoliu");
        jiuye.put("02", "wangwu");
        
        //遍历czbk集合,获取所有的教室
        Iterator<String> it = czbk.keySet().iterator();
        
        while(it.hasNext()) {
            String roomName = it.next();
            HashMap<String, String> room = czbk.get(roomName);
            System.out.println(roomName);
            getStudentMInfo(room);
        }
        
        //getStudentInfo(jiuye);
        */
    }
    public static void getStudentInfo(HashMap<String, String> roomMap) {
        Iterator<String> it = roomMap.keySet().iterator();
        while(it.hasNext()) {
            String id = it.next();
            String name = roomMap.get(id);
            System.out.println(id + ":" + name);
        }
    }
}
View Code
原文地址:https://www.cnblogs.com/yerenyuan/p/5259349.html