package setdemos; import java.util.HashSet; import java.util.Set; /** * Created by gao on 15-12-17. */ public class HashSetDemo01 { public static void main(String[] args) { //建立集合對象 Set<String> set = new HashSet<String>(); //建立並添加元素 set.add("hello"); set.add("java"); set.add("world"); set.add("java"); set.add("android"); set.add("hello"); //加強for for(String s : set){ System.out.println(s); } } }
package setdemos; /** * @author Administrator * */ public class Student { private String name; private int age; public Student() { super(); } public Student(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 boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Student)) return false; Student student = (Student) o; if (age != student.age) return false; if (!name.equals(student.name)) return false; return true; } @Override public int hashCode() { int result = name.hashCode(); result = 31 * result + age; return result; } }
測試類:java
package setdemos; import java.util.HashSet; /** * Created by gao on 15-12-17. */ /* * 需求:存儲自定義對象,並保證元素的惟一性 * 要求:若是兩個對象的成員變量值都相同,則爲同一個元素。 * * 目前是不符合個人要求的:由於咱們知道HashSet底層依賴的是hashCode()和equals()方法。 * 而這兩個方法咱們在學生類中沒有重寫,因此,默認使用的是Object類。 * 這個時候,他們的哈希值是不會同樣的,根本就不會繼續判斷,執行了添加操做。 */ public class HashSetDemo02 { public static void main(String[] args) { // 建立集合對象 HashSet<Student> hs = new HashSet<Student>(); // 建立學生對象 Student s1 = new Student("林青霞", 27); Student s2 = new Student("柳巖", 22); Student s3 = new Student("王祖賢", 30); Student s4 = new Student("林青霞", 27); Student s5 = new Student("林青霞", 20); Student s6 = new Student("范冰冰", 22); // 添加元素 hs.add(s1); hs.add(s2); hs.add(s3); hs.add(s4); hs.add(s5); hs.add(s6); // 遍歷集合 for (Student s : hs) { System.out.println(s.getName() + "---" + s.getAge()); } } }
interface Collection { ... } interface Set extends Collection { ... } class HashSet implements Set { private static final Object PRESENT = new Object(); private transient HashMap<E,Object> map; public HashSet() { map = new HashMap<>(); } public boolean add(E e) { //e=hello,world return map.put(e, PRESENT)==null; } } class HashMap implements Map { public V put(K key, V value) { //key=e=hello,world //看哈希表是否爲空,若是空,就開闢空間 if (table == EMPTY_TABLE) { inflateTable(threshold); } //判斷對象是否爲null if (key == null) return putForNullKey(value); int hash = hash(key); //和對象的hashCode()方法相關 //在哈希表中查找hash值 int i = indexFor(hash, table.length); for (Entry<K,V> e = table[i]; e != null; e = e.next) { //此次的e實際上是第一次的world Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; //走這裏實際上是沒有添加元素 } } modCount++; addEntry(hash, key, value, i); //把元素添加 return null; } transient int hashSeed = 0; final int hash(Object k) { //k=key=e=hello, int h = hashSeed; if (0 != h && k instanceof String) { return sun.misc.Hashing.stringHash32((String) k); } h ^= k.hashCode(); //這裏調用的是對象的hashCode()方法 // This function ensures that hashCodes that differ only by // constant multiples at each bit position have a bounded // number of collisions (approximately 8 at default load factor). h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); } } hs.add("hello"); hs.add("world"); hs.add("java"); hs.add("world");
4)HashSet存儲元素保證惟一性的代碼及圖解android
package hashsetdemos; /** * Created by gao on 15-12-17. */ public class Dog { private String name; private int age; private String color; private char sex; public Dog() { } public Dog(String name, int age, String color, char sex) { this.name = name; this.age = age; this.color = color; this.sex = sex; } 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 String getColor() { return color; } public void setColor(String color) { this.color = color; } public char getSex() { return sex; } public void setSex(char sex) { this.sex = sex; } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", age=" + age + ", color='" + color + '\'' + ", sex=" + sex + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Dog)) return false; Dog dog = (Dog) o; if (age != dog.age) return false; if (sex != dog.sex) return false; if (!color.equals(dog.color)) return false; if (!name.equals(dog.name)) return false; return true; } @Override public int hashCode() { int result = name.hashCode(); result = 31 * result + age; result = 31 * result + color.hashCode(); result = 31 * result + (int) sex; return result; } }
測試類:數組
package hashsetdemos; import java.util.HashSet; /** * Created by gao on 15-12-17. */ /* * HashSet集合存儲自定義對象並遍歷。若是對象的成員變量值相同即爲同一個對象 * * 注意了: * 你使用的是HashSet集合,這個集合的底層是哈希表結構。 * 而哈希表結構底層依賴:hashCode()和equals()方法。 * 若是你認爲對象的成員變量值相同即爲同一個對象的話,你就應該重寫這兩個方法。 * 如何重寫呢?不一樣擔憂,自動生成便可。 */ public class Exercise01 { public static void main(String[] args) { // 建立集合對象 HashSet<Dog> hs = new HashSet<Dog>(); // 建立狗對象 Dog d1 = new Dog("秦檜", 25, "紅色", '男'); Dog d2 = new Dog("高俅", 22, "黑色", '女'); Dog d3 = new Dog("秦檜", 25, "紅色", '男'); Dog d4 = new Dog("秦檜", 20, "紅色", '女'); Dog d5 = new Dog("魏忠賢", 28, "白色", '男'); Dog d6 = new Dog("李蓮英", 23, "黃色", '女'); Dog d7 = new Dog("李蓮英", 23, "黃色", '女'); Dog d8 = new Dog("李蓮英", 23, "黃色", '男'); //添加元素 hs.add(d1); hs.add(d2); hs.add(d3); hs.add(d4); hs.add(d5); hs.add(d6); hs.add(d7); hs.add(d8); //遍歷 for (Dog d : hs) { System.out.println(d.getName() + "---" + d.getAge() + "---" + d.getColor() + "---" + d.getSex()); } } }
package linkedhashset; import java.util.LinkedHashSet; /** * Created by gao on 15-12-17. */ public class LinkedHashSetDemo { public static void main(String[] args) { // 建立集合對象 LinkedHashSet<String> hs = new LinkedHashSet<String>(); // 建立並添加元素 hs.add("hello"); hs.add("world"); hs.add("java"); hs.add("world"); hs.add("java"); // 遍歷 for (String s : hs) { System.out.println(s); } } }