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。