Set collection: a collection that does not contain repeated elements. To be more precise, the set does not satisfy the element pair e1 and e2 of e1.equals(e2) and contains a null element. As the name implies, this interface mimics the mathematical set abstraction.
java.util.Set interface extends Collection interface
Features:
1. It is not allowed to store duplicate elements
2. There is no index, no method with index, and ordinary for loop traversal cannot be used.
一.HashSet
This class implements the Set interface and is supported by a hash table (actually a HashMap instance). It does not guarantee the iteration order of the set; in particular, it does not guarantee that the order will remain the same forever. This class allows the use of null elements.
This implementation is also not synchronous .
public static void main(String[] args) { // polymorphic writing Set<Integer> set = new HashSet<>(); set.add(1); set.add(3); // disorder, access The order is inconsistent set.add(2); set.add(1); // There can be no repeated elements // You can not use ordinary for loops, you can iterate, you can also foreach loop Iterator<Integer> iterator = set.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); // 1 2 3 } for (Integer i: set) { System.out.println(i); // 1 2 3 } }
The structure of the hash set to store the data (hash table)
What is a hash table?
Let’s first look at the hash value (hash value)
Definition: It is a decimal integer, randomly given by the system (that is, the address value of the object, a logical address, the simulated address, not the physical address where the data is actually stored)
There is a method in the Object class to get the hash value of the object.
public native int hashCode(): Returns the hash value of the object .
native: It means that the method calls the method of the local operating system.
public static void main(String[] args) { Person person = new Person(); // The Person class inherits the Object class, so you can use the hashCode method of the Object class int hash = person.hashCode(); Person person1 = new Person (); int hash1 = person1.hashCode(); /*The toString method in the Object source code: public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode());} The second half of the output is the hexadecimal representation of the hash address value */ // Compare System.out.println(person); // demo08.Person@1b6d3586 System.out.println(hash); // 460141958 }
Note that in the toString method of Object source code, the second half of @ printed is the hexadecimal number of the hash address value.
But the same is just a logical address, not a physical address.
The same logical address does not mean the same physical address! The object is different, the hash address may also be the same.
For example:
System.out.println(person == person1); // false String str = new String("aaa"); String str1 = new String("aaa"); System.out.println(str.hashCode()); // 96321 System.out.println(str1.hashCode()); // 96321// The logical address is not the same as the physical address System.out.println(str == str1); // false // The object is different, and the hash address may be the same System.out.println("重地".hashCode( )); // 1179395 System.out.println("Call".hashCode()); // 1179395
Before JDK1.8, the bottom layer of the hash table was implemented by array + linked list, that is, the linked list is used to handle conflicts, and the linked lists of the same hash value are stored in a linked list. But when there are many elements in a bucket, that is, when there are many elements with equal hash values, the efficiency of searching through the key value at one time is low. In JDK1.8, the hash table storage is realized by array + linked list + red-black tree. When the length of the linked list exceeds the threshold (8), the linked list is converted to a red-black tree, which greatly reduces the search time.
Simply put, the hash table is implemented by an array + linked list + red-black tree (JDK1.8 adds the red-black tree part).
As shown in the explanation:
Let's learn the principle that HashSet does not allow elements to be repeated:
// Create a HashSet collection HashSet<String> hashSet = new HashSet<>(); // Store elements String str1 = new String("aaa"); String str2 = new String("aaa"); hashSet.add(str1) ; hashSet.add(str2); hashSet.add("heavy ground"); hashSet.add("call"); hashSet.add("aaa"); System.out.println(hashSet); // [aaa, heavy ground , Call]
HashSet stores custom type elements
Store data of Integer and String types in HashSet. These data types are already defined types, and the hashCode method and equals method are overridden, so how to store custom type elements?
Also rewrite the hashCode method and equals method!
When storing custom type elements for HashSet, you need to rewrite the hashCode method and equals method in the object and establish your own comparison method to ensure that the objects in the HashSet collection are unique.
When there is no rewrite method:
public static void main(String[] args) { // Create a HashSet collection to store Person HashSet<Person> hashSet = new HashSet<>(); Person p1 = new Person("易烊千玺"); Person p2 = new Person ("王俊凯"); Person p3 = new Person("易 烊千玺"); hashSet.add(p1); hashSet.add(p2); hashSet.add(p3); System.out.println(p1.hashCode ()); // 460141958 System.out.println(p3.hashCode()); // 1956725890 System.out.println(p1.equals(p3)); // false // When the equals and hashCode methods are not overridden // Print [Person{name='Yiyang Qianxi'}, Person{name='王俊凯'}, Person{name='Yiyang Qianxi'}] // Unable to identify the same celebrity System.out.println(hashSet ); }
After rewriting the method:
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return Objects.equals(name, person.name); } @Override public int hashCode() { return Objects.hash(name); }
System.out.println(p1.hashCode()); // 806906957 System.out.println(p3.hashCode()); // 806906957 System.out.println(p1.equals(p3)); // true System.out.println(hashSet); // [Person{name='王俊凯'}, Person{name='易烊千玺'}]