学习笔记之JavaSE(32)--JavaAPI详解7

来源:互联网 发布:java物联网待遇 编辑:程序博客网 时间:2024/06/02 18:17

今天学习的内容是集合类之HashSet和LinkedHashSet


与List接口不同,Set接口与Collection接口的方法完全一致。常用的集有HashSet、LinkedHashSet和TreeSet,今天先学习HashSet和LinkedHashSet。


HashSet的底层数据结构是哈希表,是不同步的。HashSet在存储元素时是以该元素的哈希值确定存储位置,在随机访问集中的元素时,不需要从头开始查找,根据哈希值就可以快速找到元素,所以HashSet提供了最快的查询速度注意HashSet可以存储null


那么HashSet是如何判断元素是否重复呢?在存储元素时,HashSet会先调用该元素的HashCode()方法得到该元素的哈希值,与集中元素的哈希值比较,判断该元素是否与集中的元素重复,如果不重复就直接存储该元素。但是由于算法的原因,不同对象的哈希值有可能相同,所以如果该元素的哈希值与集中某元素相同,HashSet还要使用equals()方法比较这两个元素是否相等。如果返回true,不会存储该元素;如果返回false,此时可以选择顺延或者串联存储。所以,当使用集存储自定义类的对象时,必须要覆盖HashCode()方法与equals()方法


由于HashSet是根据哈希值确定元素的存储位置,所以HashSet是无序的。针对这个问题,JavaAPI提供了一个HashSet的子类:LinkedHashSet,它的底层数据结构是链表和哈希表,所以LinkedHashSet是有序的,元素的顺序就是添加的顺序


HashSet和LinkedHashSet的示例程序如下:

public class Test55 {public static void main(String[] args) {// HashSet的方法都是Collection的方法HashSet<String> set = new HashSet<>();set.add("a");set.add("a");set.add("b");set.add("c");System.out.println(set);// [b, c, a] 元素不允许重复,且元素是无序的Iterator<String> it = set.iterator();while (it.hasNext()) {// 由于Set接口没有定义get()方法,所以只能用这种方式获取元素System.out.print(it.next());// bca}// LinkedHashSet是有序的LinkedHashSet<String> l_set = new LinkedHashSet<>();l_set.add("a");l_set.add("a");l_set.add("b");l_set.add("c");System.out.println(l_set);// [a, b, c] 元素不允许重复,且元素是有序的// 使用HashSet存储自定义对象HashSet<Person> hs = new HashSet<>();hs.add(new Person("张三", 21));hs.add(new Person("张三", 21));hs.add(new Person("李四", 21));hs.add(new Person("王五", 21));System.out.println(hs);// [Person [name=王五, age=21], Person [name=张三,// age=21], Person [name=李四, age=21]]Iterator<Person> it_p = hs.iterator();while (it_p.hasNext()) {Person p = it_p.next();System.out.println(p);// 具有相同name和age的Person对象会被视作同一个对象,不会重复存储}}}// 要覆盖Person的hashCode()与equals()方法class Person {private String name;private int age;public Person() {super();}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;}@Overridepublic String toString() {return "Person [name=" + name + ", age=" + age + "]";}@Overridepublic int hashCode() { // 覆盖Object的hashCode()方法final int prime = 31;int result = 1;result = prime * result + age;result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {// 覆盖Object的equals()方法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;}}

补充一点,列表判断元素是否相等(比如调用contains()方法时)只判断equals()方法,如下示例程序:

public class Test56 {public static void main(String[] args) {// 定义一个临时列表存储不重复的元素ArrayList<Person> al = new ArrayList<>();al.add(new Person("张三", 21));al.add(new Person("张三", 21));al.add(new Person("李四", 21));al.add(new Person("王五", 21));System.out.println(al);// 会存储相同name与age的Person对象al = getSingleElement(al);//调用了四次equals()方法System.out.println(al);// 不存储相同name与age的Person对象}public static ArrayList<Person> getSingleElement(ArrayList<Person> al) {// 定义一个临时列表ArrayList<Person> temp = new ArrayList<>();// 迭代alIterator<Person> it = al.iterator();while (it.hasNext()) {Person p = it.next();// 判断该元素是否存在于临时列表中,如不存在,添加进临时列表if (!temp.contains(p)) {// 列表判断元素相同的依据:只判断equals()方法temp.add(p);}}return temp;}}class Person {private String name;private int age;public Person() {super();}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;}@Overridepublic String toString() {return "Person [name=" + name + ", age=" + age + "]";}@Overridepublic int hashCode() { // 覆盖Object的hashCode()方法System.out.println("hashCode()");return age;}@Overridepublic boolean equals(Object obj) {// 覆盖Object的equals()方法System.out.println("equals()");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;}}


0 0
原创粉丝点击