public class Main{
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
HashSet<String> set = new HashSet<>();
while(scanner.hasNext()) {
String string = scanner.nextLine();
String [] strings = string.split(" ");
for(int i=0;i<strings.length;i++) {
set.add(strings[i]);
}
}
System.out.println(set.size());
}
}
HashSet的去重问题:
HashSet在存放对象的时候会判断对象时候是同一对象。
默认引用类型比较的是地址值,如果地址值相同,那么这是一模一样的对象,那么判断肯定是同一对象,就不再重复的往里放。
如果对象重写了hashcode和equals方法,就比较这二者是否相等。
如果hashcode相等,那么比较equals方法,如果equals再相等,那么证明这是同一个对象;如果equals不相等,那么及时hashcode相等,也是两个对象。
所以得证:
如果equals不相等,那么hashcode可能相等;
如果equals相等,那么hashcode一定相等。
如果hashcode相等,那么equals可能相等;
如果hashcode不相等,那么equals一定不相等。
因此举个例子:
再举例子之前先看一个代码:
String s =”hello”;
String s1 = new String(“hello”);
System.out.println(s==s1);
结果我们知道肯定是不相等的。
Set set1 = new HashSet();
String s = “hello”;
set1.add(s);
set1.add(s);
String s1 = new String(“hello”);
set1.add(s1);
System.out.println(set1.size());
结果是多少?
结果是1,
为什么?因为我们说了 引用类型如果没有重写hashcode和equals方法,那么默认比较的是Object类的hashcode和equals方法。
Object类中的hashcode返回的是是通过将该对象的内部地址转换成一个整数来实现的。
如:
Hashcode也能确保对象的唯一性。
而equals默认比较的是对象的地址值。
因此,默认情况下比较不同的引用类型结果肯定是不同的对象。
就是因为String重写了hashCode和equals方法造成了HashSet判断是同一元素的缘故。