Custom Java Class : Peculiar Cases

This post is about understanding the type of interview questions which can come from a Custom Java class where we can override equals, hashcode, toString or implements the Interface to sort the list of this custom Java class.

Lets go one by one, where you start your coding round and the first information provided is

1. Create a Customer Java class which has Name, Age and Profession attributes. The interviewer also added override the toString method to display it in below format.

name: "", age: "", profession: ""

Customer.java

class Customer{

    private String name;
    private int age;
    private String profession;

    Customer(String name, int age, String profession){
        this.name = name;
        this.age = age;
        this.profession = profession;
    }

    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 String getProfession() { return profession;}
    public void setProfession(String profession) { this.profession = profession;}
 
    @Override
    public String toString(){
    return "name: "+this.name
            + " age: " + this.age
            + " profession:" + this.profession;
    }
} 

2. Create a service implementation which takes Customer class, create a Set and add the customer object by calling the addCustomer() method.

class CustomerServiceImpl {
    Set<Customer> customers = new HashSet<>();

    public void addCustomer(Customer newCust){
        customers.add(newCust);
    }
}

3. From the main method, call this addCustomer() and insert two records with same name, but different age and profession. After that call the toString() method.

CustomerServiceImpl impl = new CustomerServiceImpl();
impl.addCustomers(new Customer("DynamicallyBlunt", 10, "Developer"));
impl.addCustomers(new Customer("DynamicallyBlunt", 11, "Data Scientist"));

System.out.println(impl.customers);

Here questions could be:

  • How many elements will be added to the Set ? Answer: Since it is a set, it won't allow duplicate object in the set, but since the set elements are object and we have two different object (luckily having same name), there will be 2 elements in the customers set.

  • If its not 1, then why is it happening so ? and Can we fix it ? Answer: Since the default object's equals and hashCode is generated by including all the attributes of the custom class, it will create the hashCode of by combining all attributes and then does an equals on the entire object which will be different for both the records. Hence allowing to insert the second record with the same name. We can fix it, by overriding the equals and hashcode method as per business requirement.


4. Write the overridden methods which will not allow Customer object with same name to be inserted in the Set.

@Override
public int hashCode(){
    return this.name.hashCode();
}

@Override
public boolean equals(Object obj){
    Customer cObj = (Customer)obj;
    return this.getName().equalsIgnoreCase(cObj.getName());
}

Here, another questions could be

  • What is the change from the previous output ? Answer: This will stop the insertion of the second record in the Set with the same name, which answers the previous question of fixing it.

  • What if another Customer object is added with same name, but having lowercase characters (name: 'dynamicallyblunt', age:11, profession: 'Devops Engg') ? Answer: Here, even though we have used equalsIgnoreCase() in our equals() method, still it will add this new record into the Set. Because the hashCode which it gets will be different for strings with different cases. We can test this by printing the hashCode of same strings with different cases (It could be different if executed on your machine. depends on the JVM)

System.out.println("dynamicallyblunttech".hashCode());
1630329008

System.out.println("DynamicallyBluntTech".hashCode());
-464150320

So, we have to either convert the name attribute used in hashCode() method to

uppercase or to lowercase, such that if the strings is same, irrespective of the lowercase

or uppercase, it will not insert into the Set.

@Override
public int hashCode(){
    return this.name.toLowerCase(Locale.ROOT).hashCode();
}

5. Tell the output, if we use a sorted set instead of HashSet.

class CustomerServiceImpl {

    SortedSet<Customer> customers = new TreeSet<>();

    public void addCustomers(Customer newCust){
        customers.add(newCust);
    }
}

So, as asked, we are now using a TreeSet which is a sorted set implementation. And since the sorting behavior is not defined, it will throw an exception saying my custom Java class Customer.java is not implementing Comparable interface.


This will be the exact error message

Now to fix this, we have to implement the Comparable Interface and provide the logic for its compareTo() method which takes one argument.

class Customer implements Comparable<Customer>{

    private String name;
    .
    .
    .
    .
    
    @Override
    public int compareTo(Customer o) {
        return this.name.toLowerCase(Locale.ROOT).compareTo(o.getName());
    }
    

Using this, now my Sorted set will be sorted in ascending order by the ASCII code.


For the following records inserted

impl.addCustomers(new Customer("dynamicallyBlunt", 10, "Developer"));
impl.addCustomers(new Customer("tech", 11, "Devops"));
impl.addCustomers(new Customer("com", 11, "Data Scientist"));

We will get the following output

[name: com age: 11 profession:Data Scientist, 
 name: dynamicallyBlunt age: 10 profession:Developer, 
 name: tech age: 11 profession:Devops]

6. Sort based on the customer age, If we are using List instead of Set.

class CustomerComparator implements Comparator<Customer>{

    @Override
    public int compare(Customer o1, Customer o2) {
        if(o1.getAge() < o2.getAge())
            return -1;
        else if (o1.getAge() > o2.getAge())
            return 1;

        //Both scenario not matching then it is same age
        return 0;
    }
}

So, in this portion the interviewer is hinting to use Comparator interface instead of Comparable. Because you can sort based on any attribute using Comparator, and comparator can be implemented with Collections.sort(), or Arrays.sort() method.


So, for the following records inserted

impl.addCustomers(new Customer("tech", 11, "Devops"));
impl.addCustomers(new Customer("com", 11, "Data Scientist"));
impl.addCustomers(new Customer("interview", 9, "Developer"));
impl.addCustomers(new Customer("dynamicallyBlunt", 10, "Developer"));

Collections.sort(impl.customers, new CustomerComparator());
System.out.println(impl.customers);

We will get the following output sorted based on the age in ascending order.

[name: interview age: 9 profession:Developer, 
 name: dynamicallyBlunt age: 10 profession:Developer, 
 name: tech age: 11 profession:Devops, 
 name: com age: 11 profession:Data Scientist]

This concludes the set of basic interview questions on custom Java class and its different implementation and sorting ways which gets tricky once the interviewer ask to implement it during the coding round. Its always advisable to practice before presenting.


Hope this helps a bit in understanding the different techniques and the order of the questions that can come up. Do let me know if I am missing any other interview questions on Custom Java Class or if anything here can be enhanced.


Please do suggest more content topics of your choice and share your feedback. Also subscribe and appreciate the blog if you like it.

172 views0 comments

Recent Posts

See All