LinkedHashSet in Java

LinkedHashSet implements Set interface.In LinkedHashSet  data is storing as key – value pairs.

HashSet & LinkedHashSet

  LinkedHashSet is the doubly linked list version of HashSet. In case of HashSet , if we are iterating the items , the order of insertion cannot be guaranteed.That means , HashSet is unordered  and unsorted Set . The order is  random. But  LinkedHashSet is ordered Set. In LinkedHashSet the order of insertion is preserving.So objects are storing the same order by which it is inserted. That is the difference between HashSet and LinkedHashSet.

Now let us see an example. In our example , if just change the LinkedHashSet  to HashSet , and you can understand the difference between Hashset and LinkedHashset.

import java.util.LinkedHashSet;
import java.util.Set;
public class LinkedHashSetSample {
Set set = null;
public LinkedHashSetSample(){
set = new LinkedHashSet();
}
public void addItemsToSet() {
String[] listItems = {"dog", "cat", "cow", "elephant", "sheep"};
for (int i = 0; i < listItems.length; i++) { set.add(listItems[i]); } } public void displaySet() { System.out.println("Displaying contents of set"); for (Object item : set) { System.out.println("Item = " + item.toString()); } } public void removeItems() { System.out.println("Removing contents of set"); set.remove("dog"); set.remove("cat"); set.remove("cow"); set.remove("elephant"); set.remove("sheep"); System.out.println("Contents removed ,now size of set = " + set.size()); } public static void main(String[] args) { LinkedHashSetSample sample = new LinkedHashSetSample(); sample.addItemsToSet(); sample.displaySet(); sample.removeItems(); } }

Output

Displaying contents of set

Item = dog

Item = cat

Item = cow

Item = elephant

Item = sheep

Removing contents of set

Contents removed  ,now size of set = 0

Note:

LinkedHashSet is the LinkedList version of HashSet.So LinkedHashSet also  relying on hash code implementation of objects storing.So for effective insertion and search  we should override the hashCode() and equals() methods in our class whose objects needs to be stored in LinkedHashSet.

case 1)Without overriding hashCode() and  equals()

In this case , we are planning to put four Employee objects in a LinkedHashSet object.After putting those objects , we are initializing a new object with same attributes of an object which is already stored in set.

Let us see our Employee.java first:

public class Employee {
private int id;
private String name;
public Employee(int empId, String name) {
this.id = empId;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return "Id = " + getId() + " Name = " + getName();
}
}

Now let us see the Main.java.It adds four Employee objects (emp1 ,emp2,emp3 and emp4)and later trying to check for an object which is meaningfully equal to emp1(attributes are same  for  both the objects).

import java.util.LinkedHashSet;
import java.util.Set;
public class Main {
private Set set = null;
public Main() {
set = new LinkedHashSet();
}
public void addItems() {
Employee emp1 = new Employee(1,"Bijoy");
Employee emp2 = new Employee(2,"Karthik");
Employee emp3 = new Employee(3,"JayaKrishnan");
Employee emp4 = new Employee(4,"Dexter");
set.add(emp1);
set.add(emp2);
set.add(emp3);
set.add(emp4);
}
public void getItems() {
Employee emp = new Employee(1,"Bijoy");
System.out.println(emp +" is present = "+set.contains(emp));

}
public static void main(String[] args) {
Main main = new Main();
main.addItems();
main.getItems();
}
}

In  Employee.java shown above , we are not overriding  hashCode() and equals() . So all objects are having different hash code  values. Even the emp1 and emp objects are having different hash codes. So the output is false.Let us verify it.(For more details about hashCode() and equals() ,see my older post )

Output

Id = 1 Name = Bijoy  : is present = false

Case 2)Employee.java with overridden hashCode() and equals()

Now let us override  hashCode() and equals() methods in Employee.java.So the changed Employee.java becomes:

public class Employee {
private int id;
private String name;
public Employee(int empId, String name) {
this.id = empId;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return "Id = " + getId() + " Name = " + getName();
}
public int hashCode() {
return getId();
}
public boolean equals(Object object) {
boolean status = false;
Employee employee = (Employee) object;
if (getId() == employee.getId()) {
status = true;
} else {
status = false;
}
return status;
}
}

Use the Main.java shown in case 1 .Run Main.java .In this case the emp and emp1  are having the same hash code value , because the hash code value depends on the attribute ‘id’.So the search occurs in the same memory slot where emp1 is stored. The  equals() method also returns true.So  ‘true’ is going to be the output.

Output

Id = 1 Name = Bijoy   is present = true

Summary

Set avoids duplication of elements .Element are storing in Hashset in random order . In LinkedHashSet order of insertion is preserved . A LinkedHashSet implementation relies on hash code of objects storing in it.So if we need to store objects of a class in LinkedHashSet ,then we need to  override hashCode() and equals() methods in that class.If  our class  does not override hashCode() then:

1)Insertion of multiple objects with same attribute values(meaningfully same objects ) can happen. So meaningfully same objects can present in multiple times in a  LinkedHashSet.This is  duplication.

2)Search for an object may not be effective.Because meaningfully equal objects are  having different hash code values in this case .So  it is not possible to identify such objects.(As of the example in case 1  explained above)