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会导致无法在集合中找到该对象,所以导致无法删除,最终会导致内存泄漏。