Java HashMap需要注意的两个问题:迭代与键的选择

HashMap迭代方式的选择

HashMap迭代可以有两种方式:entrySet迭代和keySet迭代

示例

entrySet迭代

Map map = new HashMap();
Iterator it = map.entrySet().iterator();
while(it.hasNext()) {
  Map.Entry entry = (Map.Entry) it.next();
  Object key = entry.getKey();
  Object val = entry.getValue();
}

keySet迭代

Map map = new HashMap();
Iterator it = map.keySet().iterator();
while(it.hasNext()) {
  Object key = it.next();
  Object val = map.get(key);
}

这两种都可以实现迭代map,获取map里元素的键和值。它们两种主要差别在于迭代的效率上。

entrySet使用迭代器只做了一次遍历。而keySet实际做了两次,一次是使用迭代器迭代,另外一次是使用map.get(key)获取值是需要使用hashCode比较。所以效率上entrySet迭代相对keySet迭代要高。

总结:迭代HashMap推荐使用效率高的entrySet方式迭代。

HashMap键的选择

HashMap的键可以是任何对象类型。HashMap会对键对象计算hashCode,然后根据对象的hashCode做散列存储。

如下例子:

class User {
    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public int hashCode() {
        int result = name.hashCode();
        result = 31 * result + age;
        return result;
    }

    public static void main(String[] args) {
      User jack = new User("Jack",18);
      Map<User,Integer> map = new HashMap<>();
      map.put(jack,100);
      jack.setAge(19);
      User user = map.get(jack);
      System.out.println(user);
    }

}

例子里的User重写了hashCode()方法,使用name和age计算对象的hashCode。HashMap使用User作为键。因为map存储User对象后,对对象的age做了修改,这样也会导致User对象的hashCode发生变化。但我们在使用map.get()方法获取数据时,得到的结果为null。

所以在选HashMap的键时需要选择键的hashCode固定的。这里推荐基本类型的类,如Integer和String,原因:

  1. Java已对这些类的hashCode重写,有比较好的散列效果
  2. 这些类的为final,不允许在对hashCode()方法重写,让hashCode的值固定
  3. 这些类为常用类型,在很多对象里会存在,如id,name等等。

版权声明:著作权归作者所有。

相关推荐

你需要知道的6个Ruby数组方法

数组是编程的基本结构之一,这里介绍6个Ruby操作数组的方法。Map/Each这两种方法非常相似。 它们让我们对数组的每一项执行操作。示例:array = [1, 2, 3] effects = array.each{|x| # 根据x求值 } added = array.map

JavaScript判断两个数组是否相等

首先判断两个数组是否相等时不能直接使用==var array1 = []; var array2 = []; console.log(array1 == array2); //输出false 对于对象来说,==比较的是两个对象是否为同一个对象。数组属于对象类型,尽管数组元素是相同的,但这两个数组属于不同的对象

JavaScript:Map根据值查找对应的键

Map根据值查找键,可以使用for..of迭代Map的Entry,再判断Entry的值:键值一对一function getByValue(map, searchValue) {   for (let [key, value] of map.entries()) {   

解决iPhone X上下黑边的问题

在iPhone X上直接运行已有的App,App的上下出现黑边:解决方法iPhone X的显示屏为1125px × 2436px (375pt × 812pt @3x),相比于4.7寸的iPhone6,iPhone7以及iPhone8,iPhone X的宽度和4.7寸的屏幕一样,而高度则比4.7寸屏幕多出14

Java 数值相等判断详解(特别注意包装类型之间的比较)

Java数值类型分为基本类型,包装类型。基本类型:byte、short、 int、long、float和double包装类型:Byte、Short、Integer、Long、Float和Double数值比较可分为基本类型之间比较,基本类型与包装类类型比较,包装类型之间的比较。基本类型比较基本类型之间只能使用“==”做相等比较。比较结果就是数值是否相等。int a=1,