-
import
java.util.HashSet;
-
-
class
Dog{
-
String color;
-
-
public
Dog(String s){
-
color = s;
-
}
-
}
-
-
public
class
SetAndHashCode {
-
public
static
void
main(String[] args) {
-
HashSet<Dog> dogSet =
new
HashSet<Dog>();
-
dogSet.add(
new
Dog(
"white"
));
-
dogSet.add(
new
Dog(
"white"
));
-
-
System.out.println(
"We have "
+ dogSet.size() +
" white dogs!"
);
-
-
if
(dogSet.contains(
new
Dog(
"white"
))){
-
System.out.println(
"We have a white dog!"
);
-
}
else
{
-
System.out.println(
"No white dog!"
);
-
}
-
}
-
}
上述代码的输出为:
Set的contains(Object o) 方法详解
Java的API文档指出: 当且仅当 本set包含一个元素 e,并且满足(o==null ? e==null : o.equals(e))条件时,contains()方法才返回true. 因此 contains()方法 必定使用equals方法来检查是否相等.
需要注意的是: set 中是可以包含 null值的(常见的集合类都可以包含null值). 所以如果添加了null,然后判断是否包含null,将会返回true,代码如下所示:
-
HashSet<Dog> a =
new
HashSet<Dog>();
-
a.add(
null
);
-
if
(a.contains(
null
)){
-
System.out.println(
"true"
);
-
}
Java的根类Object定义了 public boolean equals(Object obj) 方法.因此所有的对象,包括数组(array,[]),都实现了此方法。
在自定义类里,如果没有明确地重写(override)此方法,那么就会使用Object类的默认实现.即只有两个对象(引用)指向同一块内存地址(即同一个实际对象, x==y为true)时,才会返回true。
如果把Dog类修改为如下代码,能实现我们的目标吗?
-
class
Dog{
-
String color;
-
-
public
Dog(String s){
-
color = s;
-
}
-
-
-
public
boolean
equals(Object obj) {
-
if
(!(obj
instanceof
Dog))
-
return
false
;
-
if
(obj ==
this
)
-
return
true
;
-
return
this
.color == ((Dog) obj).color;
-
}
-
-
}
英文答案是: no.
问题的关键在于
Java中hashCode与equals方法的紧密联系
. hashCode() 是Object类定义的另一个基础方法.
equals()与hashCode()方法之间的设计实现原则为:
如果两个对象相等(使用equals()方法),那么必须拥有相同的哈希码(使用hashCode()方法).
即使两个对象有相同的哈希值(hash code),他们不一定相等.意思就是: 多个不同的对象,可以返回同一个hash值.
hashCode()的默认实现是为不同的对象返回不同的整数.有一个设计原则是,hashCode对于同一个对象,不管内部怎么改变,应该都返回相同的整数值.
在上面的例子中,因为未定义自己的hashCode()实现,因此默认实现对两个对象返回两个不同的整数,这种情况破坏了约定原则。
-
class
Dog{
-
String color;
-
-
public
Dog(String s){
-
color = s;
-
}
-
-
-
public
boolean
equals(Object obj) {
-
if
(!(obj
instanceof
Dog))
-
return
false
;
-
if
(obj ==
this
)
-
return
true
;
-
return
this
.color == ((Dog) obj).color;
-
}
-
-
public
int
hashCode(){
-
return
color.length();
-
}
-
}
但是上面的hashCode实现,要求Dog的color是不变的.否则会出现如下的这种困惑:
-
import
java.util.HashSet;
-
import
java.util.Set;
-
-
-
public
class
TestContains {
-
-
-
public
static
final
class
Person{
-
private
String name =
""
;
-
public
Person(String n) {
-
setName(n);
-
}
-
public
String getName() {
-
return
name;
-
}
-
public
void
setName(String name) {
-
this
.name = (name==
null
)?
""
: name;
-
}
-
@Override
-
public
int
hashCode() {
-
-
return
name.length();
-
-
}
-
@Override
-
public
boolean
equals(Object obj) {
-
if
(!(obj
instanceof
Person)){
-
return
false
;
-
}
-
if
(obj ==
this
){
-
return
true
;
-
}
-
return
this
.name.equals(((Person)obj).name);
-
}
-
};
-
-
public
static
void
main(String[] args) {
-
Set<Person> persons =
new
HashSet<Person>();
-
-
Person person =
new
Person(
"tiemao"
);
-
persons.add(person);
-
-
person.setName(
"ren"
);
-
-
boolean
has = persons.contains(person);
-
int
size = persons.size();
-
System.out.println(
"has="
+has);
-
System.out.println(
"size="
+size);
-
}
-
}
新手对Set中contains()方法的疑惑[java] view plain copyimport java.util.HashSet; class Dog{ String color; public Dog(String s){ color = s; }
test_
set
.add('b');
console.log(test_
set
);//
Set
(2){"a", "b"}
console.log(test_
set
.has('a'));//true
console.log(test_
set
.has('c'));//fal.
list.
contains
(o) :遍历集合所有元素,用每个元素和传入的元素进行 equals 比较,如果集合元素有 n 个,则会比较 n 次,所以时间复杂度为 O(n) 。
方法
源码如下:
// ArrayList
中
的
方法
public boolean
contains
(Object o) {
return indexOf(o) >= 0;
public int indexOf(Object o) {
if (o == null) {
for .
关了再重新开一下。
您好,我修改模板的时候提示
contains
aninvalidpa?
打开360安全卫士-软件管家,搜索“c ”和“.net”然后点击一键安装,可以尝试多版本安装,如果遇到不能安装的话,系统会有对应的提示。
java
conta...
s=“pwwkew”
public static void lengthOfLongestSubstring(String s) {
char[] ss=s.toCharArray();
Set
<String>
set
=new Hash
Set
<>();
for(char c:ss){
if(
set
.
contains
(c)){
System...
本文主要对两者共有的
方法
contains
()做一个简单的讨论,主要是性能上的对比,并用JMH(ava Microbenchmark Harness)进行测试比较。
2 先看JMH测试结果
我们使用一个由O...
然后,创建一个Node的
Set
集合,并add一个Node对象nd1,同时new一个xy值与nd1相同的nd2:
Node nd1 = new Node(1,2);
Node nd2 = new Node(1,2);
Set
<Node> st=new Hash
Set
<>