使用Set集合都是要去掉重复元素的,如果在存储的时候逐个equals()比较,效率低,哈希算法提高了去重复的效率,降低了使用equals()方法的次数。
当HashSet调用add()方法存储对象的时候,先调用对象的hasCode()方法得到一个哈希值,然后再集合中查找是否有哈希值相同的对象。
1、如果没有哈希值相同的对象就直接存入集合。
2、如果有哈希值相同的对象,就和哈希值相同的对象逐个进行equals()比较,比较结果为false就存入,true则不存。
(1)类中必须重写hashCode()和equals()方法。
(2)hashCode():属性相同的对象返回值必须相同,属性不同的返回值尽量不同(提高效率)。
(3)equals():属性相同返回true,属性不同返回false,返回false的时候存储。
代码演示如下:
package set;
import java.util.HashSet;
public class Demo2_HashSet {
public static void main(String[] args) {
HashSet hs = new HashSet<>();
hs.add(new Person("张三",23));
hs.add(new Person("张三",23));
hs.add(new Person("李四",24));
hs.add(new Person("李四",24));
hs.add(new Person("李四",24));
hs.add(new Person("李四",24));
System.out.println(hs.size());
System.out.println(hs);
}
}
package set;
public class Person {
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
@Override
public boolean equals(Object obj) {
//System.out.println("equals方法执行了");
Person p = (Person)obj;
return this.name.equals(p.name) && this.age == p.age;
}
/*@Override
public int hashCode() {
//System.out.println("hashCode方法执行了");
System.out.println(name.hashCode());
System.out.println(name.hashCode());
System.out.println("==========================================");
return name.hashCode() + age;
}*/
/*
* 1, 31是一个质数,质数是能被1和自己本身整除的数
* 2,31这个数既不太大也不小
* 3,31这个数好算,2的五次方-1,2向左移动5位
public int hashcode(){
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
public boolean equals(Object obj) {
if(this == obj) {//调用对象和传入对象是同一个对象
return ture;
}
if(obj == null) {
return false;
}
if(getClass() != obj.getClass()){//判断两个对象对应的字节码文件是否是同一个字节码。
return false;
}
Person other = (Person)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 false;
}
*/
}
分析:
1,创建Scanner对象。
2,创建HshSet对象,将字符存储,去掉重复。
3,将字符串转换为字符数组,获取每一个字符存储在HashSet集合中,自动去除重复。
4,遍历HashSet,打印每一个字符。
代码演示如下:
package set;
import java.util.HashSet;
import java.util.Scanner;
public class Test2 {
public static void main(String[] args) {
String line = sc.nextLine();
char[] arr = line.toCharArray();
for(char c : arr) {
hs.add(c);
}
//4,遍历HashSet,打印每一个字符
for(char ch : hs) {
System.out.print(ch + " ");
}
}
}
分析:
1,创建List集合存储若干个重复元素。
2,单独定义方法去除重复。
3,打印一下List集合。
代码演示如下:
package set;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
public class Test3 {
public static void main(String[] args) {
ArrayList list = new ArrayList<>();
list.add("a");
list.add("a");
list.add("a");
list.add("b");
list.add("b");
list.add("b");
list.add("b");
list.add("c");
list.add("c");
list.add("c");
list.add("c");
//2,单独定义方法去除重复
getSingle(list);
//3,打印一下List集合
System.out.println(list);
}
/**
* 分析
* 去除List集合中的重复元素
* 1,创建一个LinkedHashSet集合
* 2,将List集合中的所有的元素添加到LinkedHashSet集合
* 3,将List集合中的元素清除
* 4,将LinkedHashSet集合中的元素添加回List集合中
*/
public static void getSingle(List list){
//1,创建一个LinkedHashSet集合
LinkedHashSet lhs = new LinkedHashSet<>();
//LinkedHashSet l = new LinkedHashSet<>();
//l.add(new Person("张三",23));
//2,将List集合中的所有的元素添加到LinkedHashSet集合中
lhs.addAll(list);
//3,将list集合中的元素清除
list.clear();
//4,将LinkedHashSet集合中的元素添加回List集合中
list.addAll(lhs);
//list.addAll(l);
}
}