Q: When to use the List? ======================== To store elements in ordered and also allowed the duplication more over the elements must index supported, then: we can prefer "List" ArrayList a = new ArrayList<>(); a.add(10); a.add(20); a.add(10); a.add(20); Sop(a); //[10,20,10,20] Q: When to use the Set? ======================= To Store elements not in ordered and not allowed the duplication more over the index is not supported to access the elements, we can prefer "Set". -> Set is an interface which is consisting of different classes. HashSet Class: ============== -> HashSet is a class which implements from Set interface. Syntax: public class HashSet implements Set<>{ } -> HashSet Class internally uses "HashMap" Class. That means, at the time of creation of an object for the HashSet class, the object for HashMap class can be created internally. -> The HashMap object can be created by calling the default HashMap() constructor by the HashSet class internally. -> The HashMap Object can create a Hash Table with the default capacity of '16' at the time of HashSet object creation. That means we can store the elements (key-value pairs) up to 16 into this Hash Table. -> The HashMap object follows the Hash Table data structure and this table can store elements in key-value pair format. -> If a new element can add to the HashSet object, then internally that element will be stored in the Hash Table as a key with the value of "PRESENT". Here, "PRESENT" is an Object for Object class. Syntax: private static final Object PRESENT = new Object(); -> There is no order can be preserved for the set. What happens at the time of an adding elements into HashSet Object? =================================================================== -> While adding elements to HashSet, first the Hash code of that elements is calculated internally. -> Based on that hash code of the element, bucket index is calculated. bucketIndex = hashCode(element) X n - 1 here: n ==> Capacity of that structure. Ex: Internal capacity of Hash Table ==> 16 Bucket Index ==> 0 to 15 Rehashing: ========== Hash Table capacity can be get doubled: when the adding of element is reach with this "capacity * load Factor" -> if the Hash table capacity can be get doubled, again the buffer index of an element can calculate and arrange those elements according to the buffer index. How to create HashSet object: ============================= Syntax_1: HashSet ObjectName = new HashSet<>(); Here: The HashMap table can be created through the HashSet Object with: internal capacity = 16 load factor = 0.75 Syntax_2: HashSet ObjectName = new HashSet<>(10,0.6); here: the HashMap can create through "HashSet" object with: internal Capacity = 10 load factor = 0.6 Syntax_3: HashSet ObjectName = new HashSet<>(10); Here: HashMap Table can create through the object of HashSet with: internal Capacity = 10 load factor = 0.75 n = 10 * 0.75 Q: How we can say that the set is not support the duplication? =============================================================== add() can return Boolean values. If it can return "true", then we can say that element added successfully. Otherwise, that element not added. When we can try to add the duplicate element into the HashSet, add() can return "false" for that duplicate element. Q: If the specified element is not in the HashSet, then what happened with remove()? ==================================================================================== remove() can return Boolean value at the time of removing of an elements from collection. true ==> element removed successfully false ==> that element is not present package p1; import java.util.HashSet; public class MainClass { public static void main(String[] args) { // creating the HashSet Object HashSet hs = new HashSet<>(); // adding elements into HashSet Object hs.add(121); hs.add(101); hs.add(97); hs.add(100); hs.add(99); hs.add(79); System.out.println("The HashSet Object hs = "+hs); boolean b = hs.add(101); boolean b1 = hs.add(211); System.out.println("The HashSet Object hs = "+hs); System.out.println(b); System.out.println("The HashSet Object hs = "+hs); System.out.println(b1); boolean b2 = hs.remove(99); System.out.println(b2); System.out.println(hs); boolean a = hs.remove(1); System.out.println(a); } } =================================== package p1; import java.util.HashSet; public class MainClass { public static void main(String[] args) { HashSet stringSet = new HashSet<>(); stringSet.add("abksdjhdjhka"); stringSet.add("ahshSHLSJLsjl"); stringSet.add("lahaKJSGAGHG"); for(String s:stringSet) { System.out.println(s); } } } ======================================================== package p1; import java.util.HashSet; import java.util.Objects; class Employee{ private int empNo; private String ename; private double salary; private String gender; private double experience; // creating the constructor for initializing class data members public Employee(int empNo, String ename, double salary, String gender, double experience) { super(); this.empNo = empNo; this.ename = ename; this.salary = salary; this.gender = gender; this.experience = experience; } // defining setters and getters public int getEmpNo() { return empNo; } public void setEmpNo(int empNo) { this.empNo = empNo; } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public double getExperience() { return experience; } public void setExperience(double experience) { this.experience = experience; } // generate toString() @Override public String toString() { return "Employee [empNo=" + empNo + ", ename=" + ename + ", salary=" + salary + ", gender=" + gender + ", experience=" + experience + "]"; } @Override public int hashCode() { return Objects.hash(empNo, ename, experience, gender, salary); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Employee other = (Employee) obj; return empNo == other.empNo && Objects.equals(ename, other.ename) && Double.doubleToLongBits(experience) == Double.doubleToLongBits(other.experience) && Objects.equals(gender, other.gender) && Double.doubleToLongBits(salary) == Double.doubleToLongBits(other.salary); } } public class Solution { private static HashSet getEmployeeSet(){ HashSet empSet = new HashSet<>(); empSet.add(new Employee(7298,"John",45000.0,"Male",3.5)); empSet.add(new Employee(7288,"Rupa",78000.0,"Female",7.5)); empSet.add(new Employee(7289,"Jhanshi",48000.0,"Female",3.7)); empSet.add(new Employee(7290,"Dinesh",54000.0,"Male",4.1)); empSet.add(new Employee(7278,"Darshana",34000.0,"Female",3.0)); empSet.add(new Employee(7391,"Jotshna",66000.0,"Female",5.1)); empSet.add(new Employee(7291,"Karthik",49000.0,"Male",3.5)); empSet.add(new Employee(7272,"Bhuvi",56000.0,"Male",3.9)); empSet.add(new Employee(7288,"Rupa",78000.0,"Female",7.5)); return empSet; } public static void main(String[] args) { HashSet setEmp = getEmployeeSet(); System.out.println("The Employee are:"); for(Employee emp:setEmp) { System.out.println(emp); } } } ================================================ Q-1: Is HashSet object thread safe? =================================== Ans: No Q-2: Can we make HashSet Object as thread safe? ================================================ Yes using "synchronizedSet()" from Collections class. Ex: Set newSetEmp = Collections.synchronizedSet(setEmp); Q-3: Is HashSet mutable? ========================= Yes Q-4: Can we make HashSet as Immutable? ====================================== Ans: Yes using unmodifiableSet() from Collections class.