Java中的Map接口

Map对象和Set类似,都包含类似的子接口和实现类HashMapLinkedHashMapSortedMap(接口),TreeMapEnumMap

Map的key可以看做是一个Set,其存放是无序的,而且也不能包含重复。实际上Map包含一个keySet()方法,返回Map里所有key组成的Set集合。

Map的value可以看做是一个List,元素与元素之间可以重复,而且可以按照索引来查找。

关于HashMap与HashTable

HashTable是一个比较古老的Map实现类,少用为妙。

还有两点不同

  1. HashTable是一个线程安全的Map实现,而HashMap是线程不安全的,所有具体场景具体选择。
  2. HashTable不允许用null当做key或value,否则报错,而HashMap可以。

它们是怎么判断对象相等呢?

通过equalshashCode方法,都返回为true则表示两者相等。故,添加对象时,可以重写这两个方法来判别同一对象。

比较重要的一点

可变对象作为HashMap或者HashTable的key的时候,且程序修改了作为key的可变对象,则可能出现再也无法访问到Map中被修改过的key。如下示例

private static void testMap() {
    Hashtable ht = new Hashtable();
    ht.put(new A(1000), "hello world");
    ht.put(new A(2000), "hello world2");
    Iterator iterator = ht.keySet().iterator();
    A first = (A) iterator.next();
    first.count = 5000;
    System.out.println(ht);
    ht.remove(new A(5000));
    System.out.println(ht);
    System.out.println(ht.get(new A(5000)));
    System.out.println(ht.get(new A(2000)));
}

A的代码

class A {
    int count;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        A a = (A) o;
        return count == a.count;
    }

    @Override
    public int hashCode() {
        return count;
    }

    public A(int count) {

        this.count = count;
    }

    @Override
    public String toString() {
        return "A{" +
                "count=" + count +
                '}';
    }
}

输出结果

{A{count=5000}=hello world, A{count=2000}=hello world2}
{A{count=5000}=hello world, A{count=2000}=hello world2}
null
hello world2

可见new A(5000)对应的值找不到了,所以,在Map中键的值最好不要修改,否则就会出现这种问题。

LinkedHashMap

它会维护插入顺序,所以性能略低于HashMap,但是在迭代全部元素有较好的性能。

Properties

HashTable的子类,一般用来读取配置文件,有load(加载)和store(写入)方法。

如果您觉得本文对您有用,欢迎捐赠或留言~
微信支付
支付宝

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注