Set接口的实现类
HashSet的使用
public class TestSet {
public static void main(String[] args) {
Set<String> set=new HashSet<String>();
set.add("hello");
System.out.println( set.add("world"));//true
set.add("java");
set.add("html");
System.out.println( set.add("world"));//false
System.out.println("集合中元素的个数:"+set.size());
System.out.println(set);//运过运行效果可知,集合中元素无序,而且唯一
set.remove("java");
System.out.println(set);
// set.clear();
// System.out.println(set);
System.out.println("遍历集合");
for(String s:set){
System.out.println(s);
}
System.out.println("迭代器");
for(Iterator<String> item=set.iterator(); item.hasNext();){
System.out.println(item.next());
}
}
}
TreeSet的使用
public class TestSet {
public static void main(String[] args) {
Set<String> set=new TreeSet<String>();
set.add("hello");
System.out.println( set.add("world"));//true
set.add("java");
set.add("html");
System.out.println( set.add("world"));//false
System.out.println("集合中元素的个数:"+set.size());
System.out.println(set);//运过运行效果可知,集合中元素无序,而且唯一
set.remove("java");
System.out.println(set);
// set.clear();
// System.out.println(set);
System.out.println("遍历集合");
for(String s:set){
System.out.println(s);
}
System.out.println("迭代器");
for(Iterator<String> item=set.iterator(); item.hasNext();){
System.out.println(item.next());
}
}
}
HashSet和TreeSet存储自定义对象
public class Person {
private String name;
private int age;
private Gender gender;
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;
}
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
public Person(String name, int age, Gender gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
public Person() {
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", gender=" + gender +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name) &&
gender == person.gender;
}
@Override
public int hashCode() {
return Objects.hash(name, age, gender);
}
}
enum Gender{
男,女;
}
public class TestSetPerson {
public static void main(String[] args) {
HashSet<Person> hs=new HashSet<Person>();//创建集合对象,同时规定集合中只能存储Person类型
//准备四个Person对象
Person p1=new Person("marry",20,Gender.女);
Person p2=new Person("lili",22,Gender.女);
Person p3=new Person("jack",32,Gender.男);
Person p4=new Person("marry",20,Gender.女);
hs.add(p1);
hs.add(p2);
hs.add(p3);
hs.add(p4);
System.out.println("集合中元素的个数:"+hs.size());
System.out.println(hs);
}
}
使用HashSet存储自定义对象时,需要重写hashCode及equals方法
HashSet的底层数据结构有关 (哈希表/散列表)
主结构:顺序表+链表
从JDK1.8开始,节点的个数超过8个,将链表改成红黑树
-
哈希表是如何查找数据的,如何添加数据的
1.计算哈希 码(调用hashCode(),结果是一个int值,整数的哈希码取自身即可)
2.计算在哈希表中的存储位置 y=k(x)=x%11 x:哈希码 k(x) 函数 y:在哈希表中的存储位置
3.存入哈希表
情况1:一次添加成功
情况2:多次添加成功(出现了冲突,调用equals()和对应链表的元素进行比较,
比较到最后,结果都是false,创建新节点,存储数据,并加入链表末尾)
情况3:不添加(出现了冲突,调用equals()和对应链表的元素进行比较,
经过一次或者多次比较后,结果是true,表明重复,不添加)结论1:哈希表添加数据快(3步即可,不考虑冲突) 结论2:唯一 结论2:无序3.哈希表是如何查询数据的 和添加数据的过程是相同的 情况1:一次找到 23 86 76 情况2:多次找到 67 56 78 情况3:找不到 100 200 结论1:哈希表查询数据快
-
hashCode和equals到底有什么神奇的作用
hashCode():计算哈希码,是一个整数,根据哈希码可以计算出数据在哈希表中的存储位置
equals():添加时出现了冲突,需要通过equals进行比较,判断是否相同
查询时也需要使用equals进行比较,判断是否相同 -
并且执行了几次?
hashCode是放入几个元素,就执行几次
equals:在相同位置放入元素的时候才会去比较。