Java易错点4

这是我参与更文挑战的第12天,活动详情查看: 更文挑战

Java易错点3

如有理解错误的话,恳请大家指正!!!

异常处理

异常处理三大关键字try、catch、finally。try模块里的return是先于finally执行,还是finally执行完了再return呢?

示例代码

package com.wangscaler;

public class TestException {
    public static int a = 1;

    public static void main(String[] args) {
        int b = test();
        System.out.println(b);
        System.out.println(a);
    }

    public static int test() {
        try {
            return a;
        } catch (Exception e) {
            System.out.println(e);
        } finally {
            ++a;
        }
        return 999999;
    }
}
复制代码

执行结果

1
2
复制代码

总结

return a;执行之前,会将a的值存放在局部变量里,然后执行finally,虽然finally执行完a的值已经是2,但是return是返回的却是在finally执行之前保存的变量的值,如果你在finally中使用return,就会覆盖之前的值,所以在finally中避免使用return。除了return,break、continue等也不应该被使用。

Hash

  • HashMap:

    • 实现了Map接口

    • 存储键值对

    • 根据键值对计算出hashCode值存储数据。

    • 访问速度快。

    • 允许一条记录的键为null,允许多条记录的值为null。

    • 非线程安全的,即任一时刻有多个线程同时写 HashMap ,可能会导致数据不一致。如果要满足线程安全,可以使用 Collections 的 SynchronizedMap 方法 或者使用 ConcurrentHashMap。

    • key相同的value会被替换。

    • 不能保留排列次序

  • HashSet

    • 实现了Set接口
    • 存储对象
    • 根据对象的成员计算hashCode值,两个对象的hashCode值可能相同。
    • 比HashMap访问效率慢
    • 不允许集合中有重复的值
  • HashTable

    • HashTable 是遗留类,与 HashMap 类似,不同的是它继承 Dictionary。
    • 线程安全的,任一时刻只能有一个线程写 HashTable。
    • 不可以接受null键和值。
  • LinkedHashMap

    • HashMap 的一个子类,保存了记录的插入顺序
  • TreeMap

    • 实现了 SortedMap 接口,根据键(key)排序,默认是按照键值的升序排序,也可以指定排序的比较器。

​ HashMap的Key调用hashCode()方法,使用hashCode作为哈希表的索引,如果当前内容不为空,则根据equals方法,找到key相同的Entry数组,将Value替换成新的;如果未找到Key相同的,则将当前位置的链表后移,将新的Entry数组放入链表头;如果当前内容为空,则将Key和Value封装成Entry数组,放入。

​ HashSet添加元素,先调用元素的hashCode方法得到元素的哈希值,通过该哈希值获取元素在哈希表的位置,如果该位置没有元素直接写入;如果已经有了,则通过equals方法比较元素值,如果相同,则不允许添加;如果不相同则允许添加。

推荐文章–>HashMap源码

示例代码

people对象

package com.wangscaler;

import java.util.Objects;

public class People {
    private int age;

    private String name;

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

    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String word = "people";

    @Override
    public String toString() {
        return "People{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

    public static void eat() {
        System.out.println("吃饭");
    }


    public void sleep() {
        System.out.println("睡觉");
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof People) {
            People people = (People) obj;
            return Objects.equals(this.age, people.age) && Objects.equals(this.name, people.name);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(age, name);
    }

}
复制代码

main函数

package com.wangscaler;

import java.util.HashSet;

public class TestHash {
    public static void main(String[] args) {
        HashSet<People> peoples = new HashSet<>();
        People people = new People(18, "wang");
        peoples.add(people);
        System.out.println("当前的hashcode值为:" + people.hashCode());
        people.setName("wangscaler");
        System.out.println("修改之后的hashcode值为:" + people.hashCode());
        System.out.println(peoples.contains(people));
        peoples.remove(people);
        System.out.println(people.getName());
        System.out.println(people.getAge());
        for (People p : peoples
        ) {
            System.out.println(p.hashCode());
            System.out.println(p.getAge());
            System.out.println(p.getName());
        }

    }
}

复制代码

执行结果

当前的hashcode值为:3643378
修改之后的hashcode值为:1901259290
false
wangscaler
18
1901259290
18
wangscaler
复制代码

总结

当对象存入Hash之后,如果修改了hashcode会导致无法在集合中找到该对象,所以导致无法删除,最终会导致内存泄漏。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享