Java -- Set 2-3 (Set)

Posted by Ryanmcgrim on Fri, 31 Dec 2021 11:15:54 +0100

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:

Topics: Java set hash comparator