1.Map用于保存具有映射关系的数据,由key-value键-值的方式进行保存,且为一一对应的关系(key唯一)。
2.HashMap和Hashtable类
二者都是Map接口的实现类,Hashtable是一个古老的实现类,且是一个线程安全的实现,不可以使用null值作为其中的key和value。HashMap可以使用null作为key和value。
二者判断key是否相等的标准:equals()方法返回true并且key的hashCode()值也相等。
判断value是否相等的标准:只需equals()比较返回0,则相等。如:
import java.util.*;
class A
{
int count;
public A(int count)
{
this.count=count;
}
public boolean equals(Object obj)
{
if(obj==this)
{
return true;//同一对象,则直接返回true
}
else if(obj!=null&&obj.getClass()==A.class)
{//父子关系
A a=(A)obj;
return this.count==a.count;
}
return false;
}
public int hashCode()
{
return this.count;
}
}
class B
{
public boolean equals(Object obj)
{
return true;
}
}
class NullInHashMap
{
public static void main(String[] args)
{
HashMap hm=new HashMap();
hm.put(null,null);//插入null
hm.put("a",null);
System.out.println(hm);
Hashtable ht=new Hashtable();
ht.put(new A(100),"zhang");
ht.put(new A(200),"zhang2");
ht.put(new A(300),new B());//添加一个值为B对象的元素
System.out.println(ht);
//由于ht中有一个值为B对象的元素,则与"123"比较调用equals时,均相等,则下面返回true
System.out.println(ht.containsValue("123"));
//关键字比较,返回true。
System.out.println(ht.containsKey(new A(100)));
ht.remove(new A(100));
for(Object key:ht.keySet())
{//输出key及对应的value
System.out.println(key+":"+ht.get(key));
}
Hashtable ht2=new Hashtable();
ht2.put(new A(60000),"123");
ht2.put(new A(87563),"abc");
Iterator it=ht2.keySet().iterator();
A a=(A)it.next();//取出第一个new A(60000)
System.out.println(a.count);
a.count=87563;//将第一个A(60000)中的count改为87563
System.out.println(ht2);
ht2.remove(new A(87563));//只能删除A(87563),即未被修改的key
System.out.println(ht2);
System.out.println(ht2.get(new A(87563)));//无法获取已修改的key
}
}
3.LinkedHashMap类
该类为HashMap的子类,该类在添加元素时,不需对key-value进行排序,只要插入的键值对时保持顺序即可(输出时按插入顺序)。
4.SortedMap接口和TreeMap实现类
类似于TreeSet中判断两个元素是否相等,TreeMap按照两个key的compareTo()方法返回0,则相等。重写equals方法时和compareTo()方法时应保持一致的返回结果。
import java.util.*;
class B implements Comparable
{
int count;
public B(int count)
{
this.count=count;
}
public String toString()
{
return "B[count:"+count+"]";
}
public boolean equals(Object obj)
{
if(this==obj)
return true;
else if(obj!=null&&obj.getClass()==B.class)
{
B b=(B)obj;
return this.count==b.count;
}
return false;
}
public int compareTo(Object obj)
{
B b=(B)obj;
return count>b.count?1:count<b.count?-1:0;//按count递增
}
}
class TreeMapTest
{
public static void main(String[] args)
{
TreeMap tm=new TreeMap();
tm.put(new B(3),"123");
tm.put(new B(-4),"abc");
System.out.println(tm);
//返回最小的key对应的元素
System.out.println(tm.firstEntry());
//返回最后一个Key值
System.out.println(tm.lastKey());
//返回比new B(1)大的最小key值
System.out.println(tm.higherKey(new B(1)));
//返回tm的子集,即从new B(-1)到new B(5)中的元素
System.out.println(tm.subMap(new B(-1),new B(5)));
}
}
5.WeekHashMap实现类
与HashMap的区别在于,HashMap的key保留了key对实际对象的强引用。只要HashMap对象不销毁,其key所引用的对象就不会被回收。
而WeekHashMap仅保留了弱引用,当key所引用的对象没有被其它强引用变量引用时。则这些key所引用的对象很可能被垃圾回收。如:
import java.util.*;
class WeakHashMapTest
{
public static void main(String[] args)
{
WeakHashMap whm=new WeakHashMap();
whm.put(new String("zhang1"),new String("123"));
whm.put(new String("zhang2"),new String("234"));
whm.put("java",new String("345"));
System.out.println(whm);
//通知系统进行垃圾回收
System.gc();
System.runFinalization();
//此时一般输出{java=345}
System.out.println(whm);
}
}
6.IdentityHashMap实现类
其比较key相等的比较是通过==判断。
import java.util.*;
class IndetityHashMapTest
{
public static void main(String[] args)
{
IdentityHashMap ihm=new IdentityHashMap();
//下面两个能添加成功
ihm.put(new String("zhang1"),123);
ihm.put(new String("zhang1"),234);
System.out.println(ihm);
//下面两个只可能会添加一个
ihm.put("java",123);
ihm.put("java",234);
System.out.println(ihm);
}
}
7.EnumMap实现类
其key只能是单个枚举类的枚举值,内部以数组进行保存。
import java.util.*;
enum Season
{
SPRING,SUMMER,FALL,WINTER
}
class EnumMapTest
{
public static void main(String[] args)
{
EnumMap enummap=new EnumMap(Season.class);
enummap.put(Season.SPRING,"123");
enummap.put(Season.FALL,"234");
enummap.put(Season.WINTER,"345");
System.out.println(enummap);
}
}
8.各Map实现类的性能比较
HashMap通常比Hashtable快点。TreeMap通常比HashMap、Hashtable慢,但其中的key-value总处于有序状态。LinkedHashMap比HashMap慢。
即:EnumMap>HashMap>(Hashtable、LinkedHashMap、TreeMap)
程序中应多使用HashMap