五、集合——6-Map集合

6-Map集合

1.概述

(1)Map集合用于保存具有映射关系的数据,所以,Map集合中保存有两组值,一组值用于保存Map里的key,另一组值用于保存Map中的value。key和value可以是任何引用类型的数据,但Map中的key不允许重复。

(2)Map中的key和value具有单向的一对一关系,通过指定的key总能找到与其对应的value。

(3)Map中的key组成的集合可以当做是一个Set集合,并且具有Set集合的特性,即无序并且不可重复。而value所组成的集合类似于一个List集合,可以通过索引来访问到value,但这个List的索引不是int类型,而是key的引用类型。

(4)Map的元素是Entry,Entry是Map的一个内部类,使用Entry来封装key-value对;

(5)Map接口中的常用方法:

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

public class MapTest {
    public static void main(String[] args) {
        //创建一个Map集合
        Map map = new HashMap();
        //向Map集合中添加元素
        map.put(1, "A");
        map.put(2, "B");
        map.put(3, "C");
        map.put(4, "D");
        map.put(5, "A");
        System.out.println(map);
        //查询Map中是否包含指定的key
        System.out.println("是否包含key为1的key:"+map.containsKey(1));
        //查询Map中是否包含指定的value
        System.out.println("是否包含value为A的value"+map.containsValue("A"));
        //返回指定key对应的value
        System.out.println(map.get(1));
        //查询Map是否为空
        System.out.println("该Map是否为空:"+map.isEmpty());
        //获取该Map的key所组成的Set集合
        Set keySet = map.keySet();
        System.out.println(keySet);
        //添加一个新的key-value对,如果该key存在,则新的key-value对会覆盖原key-value对
        map.put(1, "a");
        System.out.println(map);
        //将指定的Map中的key-value对复制到该Map中来
        Map newMap = new HashMap();
        newMap.putAll(map);
        System.out.println(newMap);
        //删除指定key对应的key-value对
        map.remove(1);
        System.out.println(map);
        //获取该Map中key-value对的个数
        System.out.println(map.size());
        //获取Map中value组成的Collection
        Collection c = map.values();
        System.out.println(c);
    }
}

 

 

 

(6)Map接口的内部类Entry,的相关方法:

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

public class MapEntryTest {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put(1, "A");
        map.put(2, "B");
        map.put(3, "C");
        map.put(4, "D");
        map.put(5, "A");
        System.out.println(map);
        //获取Map中的Entry对象组成的Set
        Set set = map.entrySet();
        System.out.println(set);
        //遍历该集合
        Iterator it = set.iterator();
        while(it.hasNext()){
            Entry e = (Entry) it.next();
            //返回该Entry中包含的key
            System.out.println(e.getKey());
            //返回该Entry中包含的value
            System.out.println(e.getValue());
            System.out.println("==============");
        }
    }
}

 

 

 

2.HashMap和Hashtable实现类

(1)HashMap和Hashtable实现类的关系类似于ArrayList和Vector的关系;

(2)HashMap和Hashtable的区别:

  1)Hashtable是一个线程安全的Map实现,但是HashMap不是线程安全的;(虽然如此,但是当多个线程访问同一个Map集合时还是应该选用HashMap然后用Collections工具类把HashMap变成一个线程安全的集合,这样的方式比较好);

  2)Hashtable不允许使用null作为key或者value,但是HashMap则可以使用null作为key或者value;

(3)HashMap使用null作为key和value的例子:

import java.util.HashMap;

public class HashMapTest {
    public static void main(String[] args) {
        HashMap hm = new HashMap();
        hm.put(null, null);
        hm.put(1, null);
        System.out.println(hm);
    }
}

 

(4)与HashSet集合类似,HashMap和Hashtable也不能保证key-value对的顺序是按照输入顺序排列;

(5)HashMap和Hashtable中判断key相等的规则是:通过equals()方法判断两个key时返回值为treu,同时两个key的hashCode()方法返回值相等;判断两个value相等的方式是两个value通过equals()方法返回true;  

(6)类似于HashSet,尽量不要在HashMap或者Hashtable中使用可变对象作为key,或者当可变对象作为key时不要修改该可变对象。

3.LinkedHashMap实现类

(1)LinkedHashMap是HashMap的子类,通过链表维护该集合的顺序,使其顺序与添加元素顺序相同;

(2)LinkedHashMap由于使用链表维护元素插入循序,性能要略低于HashMap,但是在迭代遍历中具有较好的性能;

(3)比较:

import java.util.HashMap;
import java.util.LinkedHashMap;

public class LinkedHashMapTest {
    public static void main(String[] args) {
        //创建一个HashMap集合
        HashMap hm = new HashMap();
        //添加元素
        hm.put("diyige", "A");
        hm.put("dierge", "B");
        hm.put("disange", "C");
        hm.put("disige", "D");
        hm.put("diwuge", "E");
        hm.put("diliuge", "F");
        //遍历元素
        for(Object obj : hm.keySet()){
            String i = (String)obj;
            System.out.println(hm.get(i));
        }
        System.out.println("===================");
        //LinkedHashMap
        LinkedHashMap lhm = new LinkedHashMap();
        lhm.put("diyige", "A");
        lhm.put("dierge", "B");
        lhm.put("disange", "C");
        lhm.put("disige", "D");
        lhm.put("diwuge", "E");
        lhm.put("diliuge", "F");
        for(Object obj:lhm.keySet()){
            String i = (String)obj;
            System.out.println(lhm.get(i));
        }
    }
}

 

4.Properties

(1)Properties类是Hashtable的子类,它主要用于处理属性配置文件;

(2)因为属性配置文件中的“key=value”是字符串类型,所以Properties集合的key和value的类型都是String类型的;

(3)Properties的使用:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

public class PropertiesTest {
    public static void main(String[] args) throws Exception{
        Properties props = new Properties();
        //向Properties中添加属性
        props.setProperty("name", "abc");
        props.setProperty("age", "18");
        props.setProperty("sex", "男");
        //保存到配置文件中
        props.store(new FileOutputStream("test.ini"),"test");    //并生成配置文件
        
        //创建新的Properties
        Properties props2 = new Properties();
        //加载配置文件
        props2.load(new FileInputStream("test.ini"));
        System.out.println(props2);
        //根据指定的key获取属性value
        System.out.println(props2.getProperty("name"));
        System.out.println(props2.getProperty("age"));
        System.out.println(props2.getProperty("sex"));
    }
}

 

 

 

5.SortedMap接口和TreeMap实现类

(1)SortedMap接口和TreeMap实现类也同样类似于SortedSet接口和TreeSet实现类;

(2)TreeMap也可以使得所有在此集合中的key-value对保持有序的状态;

(3)同TreeSet一样,TreeMap也同样有两种排序方式:

  1)自然排序:key元素对应的类必须实现Comparable接口;

  2)定制排序:创建TreeMap时,为其关联实现一个Comparator接口;

(4)TreeMap的自然排序:

  Teacher:

//使用自然排序,必须实现Comparable接口
public class Teacher implements Comparable{
    private String name;
    private int age;
    public Teacher(){
        
    }
    public Teacher(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 int compareTo(Object o) {
        // TODO Auto-generated method stub
        Teacher t = (Teacher)o;
        return this.age-t.age;
    }
    //应该实现equals()方法,其结果应该与compareTo()方法一致
}

 

  TreeMapComparableTest:

import java.util.TreeMap;

public class TreeMapComparableTest {
    public static void main(String[] args) {
        Teacher t1 = new Teacher("A",18);
        Teacher t2 = new Teacher("B",25);
        Teacher t3 = new Teacher("C",24);
        //创建TreeMap集合
        TreeMap map = new TreeMap();
        map.put(t1, "t1");
        map.put(t2, "t2");
        map.put(t3, "t3");
        //遍历map集合
        for(Object obj:map.keySet()){
            Teacher t = (Teacher)obj;
            System.out.println(map.get(t));
        }
        //结果按照年龄升序排列
    }
}

 

(5)TreeMap的定制排序:

import java.util.Comparator;
import java.util.TreeMap;

class Student{
    String name;
    int age;
    public Student(){
        
    }
    public Student(String name,int age){
        this.name = name;
        this.age = age;
    }
}
public class TreeMapComparatorTest {
    public static void main(String[] args) {
        Student s1 = new Student("s1",18);
        Student s2 = new Student("s2",17);
        Student s3 = new Student("s3",19);
        Student s4 = new Student("s4",16);
        //创建一个TreeMap并且与其关联一个Comparator对象
        TreeMap t = new TreeMap(new Comparator(){

            @Override
            public int compare(Object o1, Object o2) {
                // TODO Auto-generated method stub
                Student s1 = (Student)o1;
                Student s2 = (Student)o2;
                return s1.age-s2.age;
            }});
        //添加元素
        t.put(s1, "s1");
        t.put(s2, "s2");
        t.put(s3, "s3");
        t.put(s4, "s4");
        //遍历
        for(Object obj:t.keySet()){
            Student s = (Student)obj;
            System.out.println(t.get(s));
        }
        System.out.println("==============");
        //也可以使用Lambda表达式
        TreeMap t2 = new TreeMap((o1,o2)->(((Student)o1).age-((Student)o2).age));
        //添加元素
        t2.put(s1, "s1");
        t2.put(s2, "s2");
        t2.put(s3, "s3");
        t2.put(s4, "s4");
        //遍历集合
        for(Object obj:t2.keySet()){
            Student s = (Student)obj;
            System.out.println(t2.get(obj));
        }
    }
}

 

 

 

6.WeakHashMap实现类

(1)WeakHashMap的用法类似于HashMap,区别在于HashMap的key保留了对实际对象的强引用,只要该HashMap对象不被销毁,则该HashMap中key所引用的对象就不会被垃圾回收,HashMap也不会自动删除这些key-value对;但WeakHashMap的key只保留了对实际对象的弱引用,如果WeakHashMap对象的key所引用的对象没有被其他强引用变量所引用,这些key所引用的对象可能被垃圾回收,WeakHashMap也能自动删除这些key所对应的key-value对;

(2)WeakHashMap的使用:

import java.util.WeakHashMap;

public class WeakHashMapTest {
    public static void main(String[] args) {
        WeakHashMap wmap = new WeakHashMap();
        //添加元素
        wmap.put(new String("a"), "a");
        wmap.put(new String("b"), "b");
        wmap.put(new String("c"), "c");
        wmap.put(new String("d"), "d");
        wmap.put("e", "e");
        wmap.put("f", "f");
        wmap.put("g", "g");
        System.out.println(wmap);
        //通知系统进行垃圾回收
        System.gc();
        System.out.println(wmap);
        //输出{e=e, g=g, f=f}
    }
}

 

7.IdentityHashMap实现类

(1)IdentityHashMap实现类与HashMap实现类相似,不同的是IdentityHashMap在比较两个key相等时不同,在IdentityHashMap中,当两个key严格相等(key1==key2)时,才认为两个key相等;而在HashMap中,两个key通过equals返回true,并且两个key的hashcode值相同,则两个key相同;

(2)IdentityHashMap和HashMap一样允许使用null作为key和value,并且也不能保证顺序。

8.EnumMap

(1)EnumMap是一个与枚举类一起使用的Map,EnumMap中的key必须是单个枚举类中的枚举值。创建EnumMap时,必须显式指定或隐式指定它对应的枚举类;

(2)EnumMap特性:

  1)在内部以数组形式保存,这种实现形式非常高效和紧凑;

  2)根据key的自然顺序(枚举中的定义顺序)排列来维护key-value对的排列顺序;

  3)不许使用null作为key,但可以使用null作为value;

(3)EnumMap的使用:

import java.util.EnumMap;

enum Season{
    SPRING,SUMMER,FALL,WINTER
}
public class EnumMapTest {
    public static void main(String[] args) {
        //以Season枚举类创建一个EnumMap
        EnumMap em = new EnumMap(Season.class);
        em.put(Season.FALL, "fall");
        em.put(Season.WINTER, "winter");
        em.put(Season.SPRING, "spring");
        em.put(Season.SUMMER, "summer");
        System.out.println(em);
    }
}

 

 

posted @ 2017-08-02 20:07  丶theDawn  阅读(186)  评论(0编辑  收藏  举报