Open In App

Maven Project – LinkedHashMap and LinkedHashSet usage Along with JUnit Testing

Last Updated : 15 Nov, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

In software programming, there are many instances where we need the usage of LinkedHashMap and LinkedHashSet.

LinkedHashSet

Though HashSet is available, if we need the ordered version of HashSet, we need the LinkedHashSet. The advantage is when we iterate the LinkedHashSet, we get the display of the elements in the inserted order. Because of the existence of equals and hashcode methods, duplicate data is not allowed.

LinkedHashMap

Though HashMap is available, if we need the ordered version of HashMap, we need the LinkedHashMap. The advantage is when we iterate the LinkedHashMap, we get the display of the elements in the inserted order. Though duplicate keys are allowed, overwriting will occur with the new values in place of old values. Via a sample maven project, let us see the whole project. Let us take “GeekArticles” as a bean class containing a few attributes namely 

  • articleName
  • articleId
  • publishedUnder
  • rating
  • authorName

Example Maven Project

Project Structure:

Project Structure

 

Maven Project and hence the required dependencies are specified in

pom.xml

XML




<?xml version="1.0" encoding="UTF-8"?>
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
  
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.gfg.LinkedCollectionServicesInJava</groupId>
    <artifactId>LinkedCollectionServicesInJava</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
  
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <junit.version>5.3.1</junit.version>
        <pitest.version>1.4.3</pitest.version>
    </properties>
  
    <dependencies>
  
        <!-- junit 5, unit test -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
  
    </dependencies>
    <build>
        <finalName>maven-mutation-testing</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M1</version>
            </plugin>
  
            <plugin>
                <groupId>org.pitest</groupId>
                <artifactId>pitest-maven</artifactId>
                <version>${pitest.version}</version>
  
                <executions>
                    <execution>
                        <id>pit-report</id>
                        <phase>test</phase>
                        <goals>
                            <goal>mutationCoverage</goal>
                        </goals>
                    </execution>
                </executions>                
                <!-- Need this to support JUnit 5 -->
                <dependencies>
                    <dependency>
                        <groupId>org.pitest</groupId>
                        <artifactId>pitest-junit5-plugin</artifactId>
                        <version>0.8</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <targetClasses>
                        <param>com.gfg.LinkedCollectionServicesInJava.*LinkedCollectionServicesInJava*</param>
                    </targetClasses>
                    <targetTests>
                        <param>com.gfg.LinkedCollectionServicesInJava.*</param>
                    </targetTests>
                </configuration>
            </plugin>
  
        </plugins>
    </build>
  
</project>


Bean class

GeekArticles.java

Java




public class GeekArticles {
    public GeekArticles(String articleName, int articleId, String publishedUnder, int rating, String authorName) {
        super();
        this.articleName = articleName;
        this.articleId = articleId;
        this.publishedUnder = publishedUnder;
        this.rating = rating;
        this.authorName = authorName;
    }
  
    public GeekArticles() {
        // via setter methods, rest fields are done
    }
  
    String articleName;
    int articleId;
    String publishedUnder;
    int rating;
    String authorName;    
  
    public String getArticleName() {
        return articleName;
    }
  
    public void setArticleName(String articleName) {
        this.articleName = articleName;
    }
  
    public int getArticleId() {
        return articleId;
    }
  
    public void setArticleId(int articleId) {
        this.articleId = articleId;
    }
  
    public String getPublishedUnder() {
        return publishedUnder;
    }
  
    public void setPublishedUnder(String publishedUnder) {
        this.publishedUnder = publishedUnder;
    }
  
    public int getRating() {
        return rating;
    }
  
    public void setRating(int rating) {
        this.rating = rating;
    }
  
    public String getAuthorName() {
        return authorName;
    }
  
    public void setAuthorName(String authorName) {
        this.authorName = authorName;
    }
  
    // We need to override 2 methods namely 
    // equals and hashcode whenever we no need
    // to store two article objects     
    // if their names are same
    @Override
    public boolean equals(Object o) {
        if (o instanceof GeekArticles) {
            GeekArticles other = (GeekArticles) o;
            return articleName.equals(other.getArticleName());
        }
  
        return false;
    }
  
    @Override
    public int hashCode() {
        return articleName.hashCode();
    }
  
}


Here are two important methods we need to note: Because of the existence of the “equals” method which checks the similarity of articleName and it finds out whether duplicates are there are not. Moreover, hashCode() gives the checked articleName hashCode. With this, it disallows duplicates. In case they are commented out, it allows duplicates in the case of LinkedHashSet. Hence it is a must to add these 2 methods without fail.

LinkedHashMapSample.java

Java




import java.util.LinkedHashMap;
  
public class LinkedHashMapSample {
    // In order to represent LinkedHashMap does not allow 
    // duplicates in a LinkedHashMap for the same key "Excellent",
    // two separate article data is added
    // Though adding is allowed, instead of keeping 
    // 3 different entries, only 2 will be the size and for
    // "Excellent" key, last data is updated
    public int addArticles(LinkedHashMap articleMap) 
    {
        articleMap.put("Excellent",new GeekArticles("DSA", 1, "DSA", 10,"GeekA"));
        articleMap.put("Best",new GeekArticles("JavaProgramming", 2, "Java", 9,"GeekA")); 
        articleMap.put("Excellent",new GeekArticles("SoftwareTesting", 3, "Testing", 10,"GeekB")); 
        return articleMap.size();
    }
    public int getArticles(LinkedHashMap articles) {
        return articles.size();
    }
    public String getArticleName(LinkedHashMap articleMap,String articleNameKey) {
        GeekArticles geekArticles = new GeekArticles();
        if (articleMap.containsKey(articleNameKey)) {
            // Mapping the retrieved value
            geekArticles = (GeekArticles) articleMap.get(articleNameKey);            
        }
        return geekArticles.getArticleName();
    }
    public String getAuthorName(LinkedHashMap articleMap,String articleNameKey) {
        GeekArticles geekArticles = new GeekArticles();
        if (articleMap.containsKey(articleNameKey)) {
            // Mapping the retrieved value
            geekArticles = (GeekArticles) articleMap.get(articleNameKey);            
        }
        return geekArticles.getAuthorName();
    }
}


LinkedHashSetSample.java

Java




import java.util.LinkedHashSet;
  
public class LinkedHashSetSample {    
    public int addArticlesViaLinkedHashSet(LinkedHashSet articleSet) 
    {
        GeekArticles dsa = new GeekArticles("DSA", 1, "DSA", 10,"GeekA");
        GeekArticles javaProgramming = new GeekArticles("JavaProgramming", 1, "Java", 9,"GeekA");
        GeekArticles dsaProgramming = new GeekArticles("DSA", 1, "DSA", 10,"GeekB");
        articleSet.add(dsa);
        articleSet.add(javaProgramming); 
        articleSet.add(dsaProgramming);        
        return articleSet.size();
    }
    public int getArticles(LinkedHashSet articlesSet) {
        return articlesSet.size();
    }
      
    public String getArticleName(LinkedHashSet article,GeekArticles geekArticle) {
        if (article.contains(geekArticle)) {
            // Mapping the retrieved value
            return geekArticle.getArticleName();            
        }
        return null;
    }
    public String getAuthorName(LinkedHashSet article,GeekArticles geekArticle) {
        if (article.contains(geekArticle)) {
            // Mapping the retrieved value
            return geekArticle.getAuthorName();            
        }
        return null;
    }
}


Now it is time to test whether our assumptions are correct or not. Automated testing like JUnit’s always helpful to justify the same. Let us see from the below set of code.

TestLinkedCollectionServicesJava.java

Java




import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
  
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
  
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
  
public class TestLinkedCollectionServicesJava {
    @DisplayName("Test check for adding geekarticles in LinkedHashMap collection ")
    @Test
    public void testCheckForAdditionOfArticlesInLinkedHashMap() {
        LinkedHashMap<String,GeekArticles> articles = new LinkedHashMap<String,GeekArticles>();
        LinkedHashMapSample linkedHashMapServicesObject = new LinkedHashMapSample();
        assertEquals(true, linkedHashMapServicesObject.getArticles(articles) == 0);
        // adding few articles
        linkedHashMapServicesObject.addArticles(articles);
        // "Excellent" key is duplicated and hence we expect only 2
        assertEquals(true, linkedHashMapServicesObject.getArticles(articles) == 2);
        // "Excellent" key is duplicated, now lets assert that the last 
        // taken value is updated for "Excellent" key
        assertEquals(true, linkedHashMapServicesObject.getArticleName(articles,"Excellent").equalsIgnoreCase("SoftwareTesting"));
        assertEquals(true, linkedHashMapServicesObject.getAuthorName(articles,"Excellent").equalsIgnoreCase("GeekB"));
        assertTrue(linkedHashMapServicesObject.getAuthorName(articles,"Excellent").equalsIgnoreCase("GeekB"));
        // "Best" key is available only once,
        assertEquals(true, linkedHashMapServicesObject.getArticleName(articles,"Best").equalsIgnoreCase("JavaProgramming"));
        assertTrue(linkedHashMapServicesObject.getArticleName(articles,"Best").equalsIgnoreCase("JavaProgramming"));
                  
    }
    @DisplayName("Test check for adding geekarticles in LinkedHashSet collection ")
    @Test
    public void testCheckForAdditionOfAuthorsInLinkedHashSet() {
        LinkedHashSet<GeekArticles> articles = new LinkedHashSet<GeekArticles>();
        LinkedHashSetSample collectionObject = new LinkedHashSetSample();
        assertEquals(true, collectionObject.getArticles(articles) == 0);
        // adding few articles
        collectionObject.addArticlesViaLinkedHashSet(articles);
        // "dsa" article is duplicated and since we have 
        // overridden equals and hashcode method,
        // only 1 time "dsa" named article is added and hence
        // the total number of articles are 2
        assertEquals(true, collectionObject.getArticles(articles) == 2);
        GeekArticles dsa = new GeekArticles("DSA", 1, "DSA", 10,"GeekA");
        // "dsa" article is duplicated and since we have overridden equals and hashcode method,
        // duplicates are not allowed and hence we get only "dsa" as the output
        assertEquals(true, collectionObject.getArticleName(articles,dsa).equalsIgnoreCase("DSA"));
        assertTrue(collectionObject.getArticleName(articles,dsa).equalsIgnoreCase("DSA"));
        assertEquals(true, collectionObject.getAuthorName(articles,dsa).equalsIgnoreCase("GeekA"));
        assertTrue(collectionObject.getAuthorName(articles,dsa).equalsIgnoreCase("GeekA"));
    }
}


Before running the above code, make sure that the “GeekArticles” class contains the “equals” and “hashCode” methods. With that, we can get all assert to be correct. In the case of LinkedHashMap, when the duplicate key is present, the old value is updated with the new value. Thus at a time, duplicate keys are not possible. In the case of LinkedHashSet, when duplicate data is tried to get inserted, it is not accepted because of the existence of the “equals” and “hashCode” method. Thus the output will be success

 

As indicated earlier, commenting out equals and hashCode() methods and trying to execute the same

/* Commenting out to show that duplicates are accepted in LinkedHashSet and hence our existing JUNIT will
provide false results
// We need to override 2 methods namely
// equals and hashcode whenever we no need
// to store two author objects     
// if their names are same
@Override
public boolean equals(Object o) {
        if (o instanceof GeekArticles) {
            GeekArticles other = (GeekArticles) o;
            return articleName.equals(other.getArticleName());
        }

        return false;
    }

    @Override
    public int hashCode() {
        return articleName.hashCode();
    }
*/

Now running the code again

 

Conclusion

Depending upon business requirements, we can go either LinkedHashMap/HashMap or LinkedHashSet/HashSet. But for all 4 collections, make sure that when we are inserting a class object like GeekArticle, equals and hashcode methods are overridden.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads