HashSet-LinkedHashSet àì夳堔傛蜴生んèń 2022-07-12 04:46 217阅读 0赞 HashSet是Set接口的一个实现类,它所存储的元素是不可重复的,并且元素都是无序的,当向HashSet集合中添加一个对象时,首先会调用对象的hashCode()方法来确定元素的存储位置,然后再调用对象的equals()方法来确保该位置没有重复的元素。Set集合与List集合存取元素的方式都一样。 1.HashSet存储字符串并遍历 package com.first; import java.util.HashSet; public class HelloWorld { public static void main(String[] args) { HashSet<String> hs=new HashSet<>(); boolean b1=hs.add("a"); boolean b2=hs.add("b"); boolean b3=hs.add("b"); System.out.println(b1); System.out.println(b2); System.out.println(b3); for (String s : hs) { System.out.println(s); } } 运行结果为 true true false b a 如果添加相同的元素会返回false。 HashSet集合之所以能确保不出现重复的元素,是因为它在存入元素时做了很多工作。当调用HashSet集合的add()方法存入元素时,首先调用当前存入对象的hashCode()方法获得对象的哈希值,然后根据对象的哈希值计算出一个存储位置,如果该位置上没有元素,则直接将元素存入,如果该位置上有元素存在,则会调用equals()方法让当前存入的元素依次和该位置上的元素进行比较,如果返回的结果为true就将元素存入集合,返回的结果为false则说明有重复元素,就将该元素舍弃。 为了保证HashSet正常工作,要求存入对象时,重写该类中的hashCode()和equals()方法。将字符串存入HashSet时,String类已经重写了hashCode()和equals()方法。 2.HashSet存储自定义对象保证元素唯一性。 package com.first; import java.util.HashSet; public class HelloWorld { public static void main(String[] args) { HashSet<Person> hs=new HashSet<>(); boolean b1=hs.add(new Person("张三",22)); boolean b2=hs.add(new Person("李四",23)); boolean b3=hs.add(new Person("张三",22)); for (Person p : hs) { System.out.println(p); } } } class Person{ String name; int age; public Person(String name, int age) { 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) { Person p=(Person)obj; return this.name.equals(p.name)&&this.age==p.age; } @Override public int hashCode() { return 10; } } 运行结果为 Person [name=李四, age=23] Person [name=张三, age=22] 这里重写了Person类中的equals()和hashCode()方法,hashCode随意返回了一个数字10. 当调用add方法存入对象时,因为调用hashCode时返回的都是相同的值10,所以都会调用equals方法来进行比较。如果没有重写hasCode方法的话,会用其父类Object中的hasCode方法,而这个方法每次生成的值都不同,所以不会调用equals方法进行比较。 但自己重写的这两个方法,效率很低,每次都要调用equals方法。其实这两个方法可以自动生成,用快捷键alt+shift+s+h。 @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; 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 true; } # LinkedHashSet # 底层是链表实现的,是set集合中唯一一个能保证怎么存就怎么取的集合对象。 因为是HashSet的子类,所以也是保证元素唯一的
还没有评论,来说两句吧...