Java 集合知识总结(四)

Map集合主要用于保存有映射关系的数据,Map集合中存在两组数据,一组用于保存key,一组用于保存value,key和value可以是任何引用类型的数据,Map得key不允许重复,key和value直接存在单向的一对一关系。

Map集合主要接口图如下:

1)HashMap和Hashtable

Hashtable是线程安全的,HashMap是线程不安全的,所以性能比Hashtable要高;Hashtable不允许null为key,HashMap允许null为key,但是有且只有一个key为null得键值对。

public class HashMapTest {
    public static void main(String[] args) {
        HashMap maps = new HashMap();
        maps.put(null, null);
        maps.put("", 222);
        System.out.println("HashMap:" + maps.get(null));
        System.out.println("HashMap2:" + maps.get(""));
        System.out.println("------------------------------");
        Hashtable ms = new Hashtable();
        ms.put("", 111);
        ms.put(null, 1222);
        System.out.println("Hashtable:" + ms.get(null));
        System.out.println("Hashtable:" + ms.get(""));
    }
}

结果是:

Exception in thread "main" java.lang.NullPointerException
    at java.util.Hashtable.hash(Unknown Source)
    at java.util.Hashtable.put(Unknown Source)
    at com.zzl.demo.HashMapTest.main(HashMapTest.java:17)
HashMap:null
HashMap2:222
------------------------------

与hashset类似,尽量不要使用可变对象作为key,如若必须使用,则尽量不要修改作为key得对象

/**
 * 重写equals和hashcode方法
 * @author Administrator
 *
 */
public class Test1 {
    private int count;
    public Test1(int count) {
        this.count = count;
    }
    @Override
    public boolean equals(Object obj) {
        if (obj == this){
            return true;
        }
        if (null !=  obj && obj.getClass() == this.getClass()){
            Test1 ts1 = (Test1)obj;
            return this.count == ts1.count;
        }
        return false;
    }
    @Override
    public int hashCode() {
        return this.count;
    }
    public int getCount() {
        return count;
    }
    public void setCount(int count) {
        this.count = count;
    }
}
public class MapDemo {
    public static void main(String[] args) {
        HashMap maps = new HashMap();
        // 插入数据
        maps.put(new Test1(1000), "111");
        maps.put(new Test1(2000), "222");

        Iterator it = maps.keySet().iterator();
        Test1 ts1 = (Test1)it.next();
        ts1.setCount(2000);
        // 修改后的map集合
        System.out.println(maps);
        // 只能删除没有被修改的对象key
        maps.remove(new Test1(2000));
        System.out.println(maps);
        // key对象被修改,无法获取对应的value
        System.out.println(maps.get(new Test1(2000)));
    }
}

结果是

{com.zzl.demo.Test1@7d0=111, com.zzl.demo.Test1@7d0=222}
{com.zzl.demo.Test1@7d0=111}
null

判断key值是否相等,需要判断两个对象的equals方法返回相等,hashcode方法返回值也必须相等

判断value是否相等,只需要通过equals方法返回是否为true。

2)Map集合示例:使用properties读取属性文件

public class PropertiesDemo {
    public static void main(String[] args) {
        Properties pro = new Properties();
        // 添加属性
        pro.setProperty("账号", "admin");
        pro.setProperty("密码", "123");
        
        // 写入属性文件
        try {
            pro.store(new FileOutputStream("d:\test.properties"),"Test data");
        } catch (IOException e) {
            System.out.println(e);
        }
    }
}

结果是:

#Test data
#Sun Jul 16 23:09:13 CST 2017
u8D26u53F7=admin
u5BC6u7801=123

3)TreeMap实现类

TreeMap就是一个红黑树数据结构,每一个key-value作为红黑树的一个节点;TreeMap保证所有key-value为有序状态,通过key对节点进行排序,有两种排序自然排序和自定义排序。

TreeMap和TreeSet类似,判断两个key是否相等通过compareTo()返回是否为0。

public class TreeMapTest {
    public static void main(String[] args) {
        TreeMap tmap = new TreeMap();
        //插入数据
        tmap.put(3, "test1");
        tmap.put(-1, "test2");
        tmap.put(20, "test2");
        
        // 自然排序
        System.out.println(tmap);
        // 获取最小key
        System.out.println(tmap.firstKey());
        // 获取最大key
        System.out.println(tmap.lastKey());
    }
}

结果是:

{-1=test2, 3=test1, 20=test2}
-1
20

总结:

HashMap和Hashtable实现机制一样,但是由于Hashtable比较古老同时是线程安全的,所有速度要比HashMap慢;TreeMap使用的红黑树管理,速度要比HashMap和Hashtable更慢,除非需要使用有序的map,否则建议多使用HashMap。

原文地址:https://www.cnblogs.com/quina520/p/7192461.html