Set
Set set overview and features
Set set features
- A collection that does not contain duplicate elements
- There is no indexed method, so you can't use a normal for loop to traverse
Set set exercise
- Store string and traverse
import java.util.HashSet; import java.util.Set; /* Set Set characteristics A collection that does not contain duplicate elements There is no indexed method, so you can't use a normal for loop to traverse HashSet: There is no guarantee for the iterative order of the set */ public class SetDemo { public static void main(String[] args) { //Create collection object //HashSet: there is no guarantee for the iterative order of the set Set<String> set = new HashSet<String>(); //Add element set.add("hello"); set.add("world"); set.add("java"); //Does not contain duplicate elements set.add("hello"); //ergodic for (String s : set) { System.out.println(s); } /*Operation results: world java hello */ } }
Operation results:
Hash value
Hash value: it is a value of int type calculated by JDK according to the address, string or number of the object
There is a method in the Object class to get the hash value of the Object
- public int hashCode(): returns the hash code value of the object
Hash value characteristics of object
- The hashCode() method is called multiple times for the same object, and the returned hash value is the same
- By default, different objects have different hash values. Rewriting the hashCode() method can make the hash values of different objects the same
/* Hash value: it is a value of int type calculated by JDK according to the address, string or number of the object Object Class has a method to get the hash value of the object: public int hashCode(): Returns the hash code value of the object */ public class HashDemo { public static void main(String[] args) { //Create student object Student s1 = new Student("Xiaobai", 12); //The hashCode() method is called multiple times for the same object, and the returned hash value is the same System.out.println(s1.hashCode());//1854778591 System.out.println(s1.hashCode());//1854778591 System.out.println("--------"); //Create student object Student s2 = new Student("Xiaobai", 22); //By default, different objects have different hash values //Through method rewriting, the hash values of different objects can be the same System.out.println(s2.hashCode()); System.out.println("--------"); System.out.println("hello".hashCode());//99162322 System.out.println("world".hashCode());//113318802 System.out.println("java".hashCode());//3254818 System.out.println("world".hashCode());//113318802 System.out.println("--------"); System.out.println("Heavily".hashCode());//1179395 System.out.println("conversation".hashCode());//1179395 System.out.println("program".hashCode());//992740 System.out.println("code".hashCode());//656766 } }
Operation results:
HashSet collection overview and features
HashSet set features
- The underlying data structure is a hash table
- There is no guarantee for the iterative order of the set, that is, the order of the storage group and the extracted elements is not guaranteed
- There is no indexed method, so you can't use a normal for loop to traverse
- Because it is a Set set, it is a Set that does not contain duplicate elements
HashSet set exercise
- Store string and traverse
public class HashSetDemo { public static void main(String[] args) { //Create collection object HashSet<String> hs = new HashSet<String>(); //Add element hs.add("hello"); hs.add("world"); hs.add("java"); hs.add("world"); //ergodic for (String s : hs) { System.out.println(s); } } }
Operation results:
Source code analysis of HashSet set to ensure element uniqueness
//Create collection object
HashSet hs = new HashSet();
//Add element
hs.add("hello");
hs.add("world");
hs.add("java");
hs.add("world");
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
//The hash value is related to the element's hashCode() method
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
//If the hash table is not initialized, it is initialized
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
//The storage location of the object is calculated according to the hash value of the object. If there is no element in the location, the element is stored
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else {
Node<K,V> e; K k;
/*
The stored element compares the hash value with the previous element
If the hash values are different, the execution continues down, adding elements to the collection
If the hash values are the same, the object's equals() method is called for comparison
If false is returned, the execution continues down, adding the element to the collection
If true is returned, it indicates that the element is repeated and will not be stored
*/
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
else if (p instanceof TreeNode)
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else {
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
}
++modCount;
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
}
HashSet collection storage elements:
- To ensure element uniqueness, you need to override hashCode() and equals()
Hash table of common data structures
Hashtable
- Before JDK8, the bottom layer was implemented by array + linked list, which can be said to be an array with linked list elements
- After JDK8, when the length is long, the bottom layer is optimized
Case: the HashSet collection stores student objects and traverses them
Requirements: create a collection for storing student objects, store multiple student objects, and use the program to traverse the collection on the console
Requirement: if the member variable values of the student object are the same, we think it is the same object
import java.util.Objects; //Define student classes public class Student { private String name; private int 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; } public Student() { super(); } public Student(String name, int age) { super(); this.name = name; this.age = age; } //Shortcut key overrides hashCode() and equals() @Override public int hashCode() { return Objects.hash(age, name); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Student other = (Student) obj; return age == other.age && Objects.equals(name, other.name); } }
import java.util.HashSet; /* Case: the HashSet collection stores student objects and traverses them Requirements: create a collection for storing student objects, store multiple student objects, and use the program to traverse the collection on the console Requirement: if the member variable values of the student object are the same, we think it is the same object */ public class HashSetDemo2 { public static void main(String[] args) { //Create a HashSet collection object HashSet<Student> hs = new HashSet<Student>(); // Create student object Student s1 = new Student("Xiaobai", 12); Student s2 = new Student("Xiao Hei", 13); Student s3 = new Student("Xiao Hong", 11); Student s4 = new Student("Xiao Hong", 11); // Add students to collection hs.add(s1); hs.add(s2); hs.add(s3); hs.add(s4); //Traversal set for (Student s : hs) { System.out.println(s.getName() + "," + s.getAge()); } } }
Operation results:
LinkedHashSet collection overview and features
LinkedHashSet set features:
- The Set interface implemented by hash table and linked list has predictable iteration order
- There is a linked list to ensure the order of elements, that is, the storage and extraction order of elements are consistent
- There is a hash table to ensure the uniqueness of elements, that is, there are no duplicate elements
LinkedHashSet set exercise
- Store string and traverse
import java.util.LinkedHashSet; /* LinkedHashSet Collection features: - The Set interface implemented by hash table and linked list has predictable iteration order - There is a linked list to ensure the order of elements, that is, the storage and extraction order of elements are consistent - There is a hash table to ensure the uniqueness of elements, that is, there are no duplicate elements LinkedHashSet Set exercise - Store string and traverse */ public class LinkedHashSetDemo { public static void main(String[] args) { //Create collection object LinkedHashSet<String> lhs = new LinkedHashSet<String>(); //Add element lhs.add("hello"); lhs.add("world"); lhs.add("java"); lhs.add("world"); //ergodic for (String s : lhs) { System.out.println(s); } } }
Operation results:
TreeSet collection overview and features
TreeSet set features:
- Elements are ordered. The order here does not refer to the order of storage and retrieval, but is sorted according to certain rules. The specific sorting method depends on the construction method
TreeSet(): sort according to the natural order of its elements
TreeSet (comparator): sort according to the specified comparator - There is no indexed method, so you can't use a normal for loop to traverse
- A collection that does not contain duplicate elements because it is a Set collection
TreeSet set exercise
- Store integers and traverse
import java.util.TreeSet; /* TreeSet Collection features: - Elements are ordered. The order here does not refer to the order of storage and retrieval, but is sorted according to certain rules. The specific sorting method depends on the construction method TreeSet(): Sort according to the natural order of its elements TreeSet(Comparator comparator): Sorts according to the specified comparator - There is no indexed method, so you can't use a normal for loop to traverse - A collection that does not contain duplicate elements because it is a Set collection TreeSet Set exercise - Store integers and traverse */ public class TreeSetDemo { public static void main(String[] args) { //Create collection object TreeSet<Integer> ts = new TreeSet<Integer>();//Since the reference type is used in < >, the wrapper class Integer of int is used //Add element ts.add(55); ts.add(22); ts.add(44); ts.add(33); ts.add(11); ts.add(11);//Does not contain duplicate elements //Traversal set for (int i : ts) { System.out.println(i); } /*Run results: sort from small to large in natural order 11 22 33 44 55 */ } }
Operation results:
Use of natural sorting Comparable
- Store and traverse the student object, create a TreeSet collection, and use the parameterless construction method
- Requirements: sort according to the age from small to large. If the age is the same, sort according to the alphabetical order of the name
//Define student classes public class Student implements Comparable<Student> { private String name; private int 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; } public Student() { super(); } public Student(String name, int age) { super(); this.name = name; this.age = age; } @Override public int compareTo(Student s) { // TODO Auto-generated method stub // return 0;// Same, not stored // return 1;// Positive order of storage // return -1;// Reverse order of storage //Sorted by age int num = this.age - s.age;//Here this represents S2 and s represents s1 // int num=s.age-this.age;// Descending order //When the age is the same, sort alphabetically by name int num2 = num == 0 ? this.name.compareTo(s.name) : num;//Because natural sorting itself can use string type, use s.name directly return num2;//The uniqueness of elements can be guaranteed } }
import java.util.TreeSet; /* Use of natural sorting Comparable - Store and traverse the student object, create a TreeSet collection, and use * * parameterless construction method** - Requirements: sort according to the age from small to large. If the age is the same, sort according to the alphabetical order of the name */ public class TreeSetDemo2 { public static void main(String[] args) { //Create collection object TreeSet<Student> ts = new TreeSet<Student>(); //Create student object Student s1 = new Student("xiaobai", 12); Student s2 = new Student("dabai", 13); Student s3 = new Student("xiaohei", 14); Student s4 = new Student("dahei", 10); Student s5 = new Student("xiaohong", 10); Student s6 = new Student("xiaohong", 10);//Element unique //Add students to collection ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); ts.add(s6); //Traversal set for (Student s : ts) { System.out.println(s.getName() + "," + s.getAge()); } /*Operation results: ClassCastException Because: the student class does not implement the Comparable interface */ /*Operation results: xiaobai,12 Because: at this time, 0 is returned in compareTo() */ /*Change compareTo() to return 1 Operation results: xiaobai,12 dabai,13 xiaohei,14 dahei,10 Output in stored order */ /*Change compareTo() to return -1 Operation results: dahei,10 xiaohei,14 dabai,13 xiaobai,12 Output in reverse order according to the stored order */ } }
Operation results:
Conclusion:
- The TreeSet collection is used to store custom objects. The parameterless construction method uses natural sorting to sort elements
- Natural sorting is to let the class to which the element belongs implement the Comparable interface and override the compareTo (T o) method
- When rewriting a method, be sure to note that the collation must be written according to the required primary and secondary conditions
Use of Comparator sorting Comparator
- Store the student object and traverse it, create a TreeSet collection, and use the construction method with parameters
- Requirements: sort according to the age from small to large. If the age is the same, sort according to the alphabetical order of the name
//Define student classes public class Student { private String name; private int 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; } public Student() { super(); } public Student(String name, int age) { super(); this.name = name; this.age = age; } }
/* *Use of Comparator sorting Comparator** - Store the student object and traverse it, create a TreeSet collection, and use the * * parameter construction method** - Requirements: sort according to the age from small to large. If the age is the same, sort according to the alphabetical order of the name */ import java.util.Comparator; import java.util.TreeSet; public class TreeSetDemo3 { public static void main(String[] args) { //Create collection object TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {//Use anonymous inner classes @Override public int compare(Student s1, Student s2) { // TODO Auto-generated method stub //this.age--s.age //s1--s2 int num = s1.getAge() - s2.getAge(); int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num; return num2; } }); //Create student object Student s1 = new Student("xiaobai", 12); Student s2 = new Student("dabai", 13); Student s3 = new Student("xiaohei", 14); Student s4 = new Student("dahei", 10); Student s5 = new Student("xiaohong", 10); Student s6 = new Student("xiaohong", 10);//Element unique //Add students to collection ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); ts.add(s6); //Traversal set for (Student s : ts) { System.out.println(s.getName() + "," + s.getAge()); } } }
Operation results:
Conclusion:
- The user-defined objects are stored in the TreeSet collection. The construction method with parameters uses comparator sorting to sort the elements
- Comparator sorting is to let the collection construction method receive the implementation class object of comparator and rewrite the compare(T o1, T o2) method
- When rewriting a method, be sure to note that the collation must be written according to the required primary and secondary conditions
Case: ranking of scores
Requirements: use TreeSet set to store multiple student information (name, Chinese score, mathematics score), and traverse the set
Requirements: appear from high to low according to the total score
//Define student classes public class Student { private String name; private int chinese; private int math; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getChinese() { return chinese; } public void setChinese(int chinese) { this.chinese = chinese; } public int getMath() { return math; } public void setMath(int math) { this.math = math; } public Student(String name, int chinese, int math) { super(); this.name = name; this.chinese = chinese; this.math = math; } public Student() { super(); } @Override public String toString() { return "name=" + name + ", chinese=" + chinese + ", math=" + math + ", sum=" + getSum(); } public int getSum() { return this.chinese + this.math; } }
import java.util.Comparator; import java.util.TreeSet; /* Case: ranking of scores Requirements: use TreeSet set to store multiple student information (name, Chinese score, mathematics score), and traverse the set Requirements: appear from high to low according to the total score */ public class TreeSetDemo4 { public static void main(String[] args) { //Create collection object TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { // TODO Auto-generated method stub //Appear from high to low according to the total score //s---this //s2---s1 // int num=(s2.getChinese()+s2.getMath())-(s1.getChinese()+s1.getMath()); //Main conditions int num = s2.getSum() - s1.getSum(); //minor criteria int num2 = num == 0 ? s1.getChinese() - s2.getChinese() : num; int num3 = num2 == 0 ? s1.getName().compareTo(s2.getName()) : num2; return num3; } }); //Create student object Student s1 = new Student("Xiaobai", 55, 66); Student s2 = new Student("Xiao Hei", 54, 76); Student s3 = new Student("Xiao Hong", 67, 44); Student s4 = new Student("Xiao Huang", 23, 64); Student s5 = new Student("Blue ", 95, 78); Student s6 = new Student("Little green", 94, 79);//The total score is the same, but the scores of individual subjects are different Student s7 = new Student("Little purple", 94, 79);//The total score and single subject score are the same //Add students to collection ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); ts.add(s6); ts.add(s7); //Traversal set for (Student s : ts) { System.out.println(s.toString()); } } }
Operation results:
Case: random number without repetition
Requirements: write a program to obtain 10 random numbers between 1 – 20. It is required that the random numbers cannot be repeated and output on the console
import java.util.HashSet; import java.util.Random; import java.util.Set; import java.util.TreeSet; import hello.randomDemo; /* Case: random number without repetition Requirements: write a program to obtain 10 random numbers between 1 and 20. It is required that the random numbers cannot be repeated and output on the console */ public class SetDemo2 { public static void main(String[] args) { //Create Set collection object // Set<Integer> set=new HashSet<Integer>(); Set<Integer> set = new TreeSet<Integer>(); //Create random number object Random r = new Random(); //Judge whether the set length is less than 10 while (set.size() < 10) {//Less than 10, a random number is generated and added to the set int number = r.nextInt(20) + 1; set.add(number); } //Variable set for (Integer i : set) { System.out.println(i); } } }
Operation results: