您的位置:首页 > 职场人生

黑马程序员----------java基础加强之hashSet总结

2014-05-19 00:16 495 查看
----------------------android培训java培训、期待与您交流!
----------------------

关于Set接口下的hashSet总结。

HashSet的使用一直是令人纠结的问题,所以今天翻了笔记把它总结一下,希望能够给看到的人们提供帮助。

他是java.util包下的,使用他们时一般要重新覆盖hashCode()和equals()方法。

而hashCode()方法覆盖有这么三大原则:

1.一定要让那些我们认为相同的对象返回相同的hashCode值。

2.尽量让那些我们认为不相同的值返回不同的hashCode值。

3.尽量让对象的hashCode值三裂开。

当我们试图把某个类的对象当成 HashMap 的 key,或试图将这个类的对象放入 HashSet 中保存时,重写该类的 equals(Object obj) 方法和 hashCode() 方法很重要,而且这两个方法的返回值必须保持一致:当该类的两个的 hashCode() 返回值相同时,它们通过 equals() 方法比较也应该返回 true。通常来说,所有参与计算 hashCode() 返回值的关键属性,都应该用于作为 equals() 比较的标准。

如下程序就正确重写了 Name 类的 hashCode() 和 equals() 方法,程序如下:

Java代码

class Name

{

private String first;

private String last;

public Name(String first, String last)

{

this.first = first;

this.last = last;

}

// 根据 first 判断两个 Name 是否相等

public boolean equals(Object o)

{

if (this == o)

{

return true;

}

if (o.getClass() == Name.class)

{

Name n = (Name)o;

return n.first.equals(first);

}

return false;

}

// 根据 first 计算 Name 对象的 hashCode() 返回值

public int hashCode()

{

return first.hashCode();

}

public String toString()

{

return "Name[first=" + first + ", last=" + last + "]";

}

}

public class HashSetTest2

{

public static void main(String[] args)

{

HashSet<Name> set = new HashSet<Name>();

set.add(new Name("abc" , "123"));

set.add(new Name("abc" , "456"));

System.out.println(set);

}

}

上面程序中提供了一个 Name 类,该 Name 类重写了 equals() 和 toString() 两个方法,这两个方法都是根据 Name 类的 first 实例变量来判断的,当两个 Name 对象的 first 实例变量相等时,这两个 Name 对象的 hashCode() 返回值也相同,通过 equals() 比较也会返回 true。

程序主方法先将第一个 Name 对象添加到 HashSet 中,该 Name 对象的 first 实例变量值为"abc",接着程序再次试图将一个 first 为"abc"的 Name 对象添加到 HashSet 中,很明显,此时没法将新的 Name 对象添加到该 HashSet 中,因为此处试图添加的 Name 对象的 first 也是" abc",HashSet 会判断此处新增的 Name 对象与原有的 Name 对象相同,因此无法添加进入,程序在①号代码处输出
set 集合时将看到该集合里只包含一个 Name 对象,就是第一个、last 为"123"的 Name 对象。

下面是用eclipse自动生成的代码:

package TestMath;

public class Student {
private String name;
private int age;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}

}


很明显,eclspse想的要比我们想的周全,它的做法是在保证相同对象返回相同哈希值的同时,也尽可能的做到了不同对象返回不同的哈希值。

----------------------android培训java培训、期待与您交流!
----------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐