I had an interview with a developer
Mothusi: Hello guys, today I have a Java interview with JavaSpace (aka JS) the name of my YouTube channel. Please help me welcome JS. Hello JS, please greet my LinkedIn audience.
JS: Hello everyone.
Mothusi: JS, I want to assume you know SQL right?
JS: Yes, I know SQL sir. But this is a Java interview, why SQL?
Mothusi:?Relax JS, I am glad you know SQL. I want you to implement some of the functionality in SQL within your Java code. I believe you are familiar to SQL’s ORDER BY clause right.
JS: Yeah, I know the clause and it’s pretty easy to use it.
Mothusi: Please see the table below:
And this translates to a following Java class:
Mothusi: JS, before we begin, let’s do the basic SQL first, ID column is a primary key, and I know you are aware of what it means. Assuming you were to store a list of employees and a list does not allow employees with same id. How can you achieve this?
JS: I would use Set to store the employees as it does not allow duplicates, that easy!
Mothusi: Is that all you could do?
JS: Yes, because the Set implementation will take care of the details, as long as I have chosen one of its implementation such as a HashSet I am done.
Mothusi: You are done? how will a HashSet know how to make a determination whether two employees have the same ID?
JS: Hmm, let me think. Oh snap! I have to override the equals method and have it check if two employees have the same ID.
Mothusi: If you don’t override the equals method, It could still work. Explain this scenario and why it will work.
JS: Let me think for a second.. I think you got me! I don’t know the answer.
Mothusi: Okay, let me help you, remember you have a default implementation of the equals method in Object class. Do you remember how it’s implemented?
JS: Not really.
Mothusi: Okay, let me show you. Look at the code below:
JS: Oh yes, it will work if you add the same object more than once into the Set. It would not be added because the default equals method would return true.
Yeah, so, I think that’s all.
Mothusi: But remember the implementations of the Set interface utilise a Map under the hood, as a result there is more you need to do, or else even after you override the equals method, you will not get desired behaviour for two different objects having the same employee state. What is it that you still need to do?
JS: Oh yes, I remember I have to also override a hashCode method accordingly.
Mothusi: Do you remember that this two methods have a contract?
JS: Contract? Are you kidding me? Oh sorry, forgive my language!
Mothusi: Yeah, the contract between these two is that equal objects should always have the same hash code, but the same hash code does not mean equal objects.
JS: Okay I understand now.
Mothusi: Can you elaborate on the instance where the hash code of objects are the same, how does the Map handle this. This is called coalition.
JS: hahahaha! :)
Mothusi: What? What are you laughing at bro?
JS: You remind me of minister Gigaba, so you also can’t differentiate between collision and coalition?
Mothusi: Stop it bro, you will be arrested! I meant collision. I see your tricks, you are trying to run away from the question, answer the question.
JS: To be honest, I am not sure.
Mothusi: You can find more information on this from my YouTube channel called JavaSpace. But briefly, a map maintains a table of default size 16, each index of the array has a corresponding backet. So, if two objects produce the same hash code, they will be stored in the same bucket. A bucket is a LinkedList of default size 8. We claim the HashMap has constant time performance but this in a way works against that.
JS: But now that the bucket is a LinkedList, it means we lose O(1) performance.
Mothusi: I agree but iterating through 8 elements, is still a constant time in a way because they are 8. The problem arises when the number exceeds 8, which means it could be any number n, leading to O(n) performance. Now, from Java 8, when the bucket size exceed 8, the bucket is converted into a balanced tree. Now you get O(log n). It’s enough, this interview is not about Maps. We will do a separate interview on Maps in future.
We are done with basics. Now, let’s get to the real stuff.
Mothusi: If you want to order the employees by first name you can simply execute this query
领英推荐
SELECT * FROM employee ORDER BY firstName;
If names are the same, you might want to order by both first and last name
SELECT * FROM employee ORDER BY firstName, lastName;
And this you know JS right?
JS: YES!
Mothusi: If both first and last names are the same, you might want to order by another column, add as many columns as you want in the ORDER BY clause.
JS: Yes, I agree with you.
Mothusi: Okay, let’s say I want to store employees sorted either in ascending or descending order. What data structure can I use?
JS: You can use an ArrayList.
Mothusi: Remember an ArrayList will only give you insertion order and will not order elements. Can you think of something else?
JS: A tree.
Mothusi: You are correct. You can use a TreeSet to be specific. Assuming I want to have a default ordering by employee ID when I add the elements into a TreeSet. How can I achieve this?
JS: Employee class will have to implement Comparable interface and override compareTo method.
Mothusi: That’s right. Now, let’s say we want to achieve the same functionality SQL offers with ORDER BY clause in Java, where we can further order employees by first name, then by last name, this is normally applicable when their first names are the same. How can we achieve this.
JS: Well, we can edit our compareTo method in Employee class and add if statements for additional fields as below.
Mothusi: Correct. But now you have contaminated our default ordering, because not everyone that use your application would want to order by first name and last name by default. How can we achieve the same thing without altering the original implementation of the compareTo?
JS: I guess, we can use Comparator then?
Mothusi: That’s correct, what’s the difference between these two? How do you to choose between the two?
JS: I am confused.
Mothusi: Well, you use Comparable for default ordering, and you use Comparator when you want to provide custom ordering at runtime, which means you want to override default ordering. Does that make sense?
JS: Yes it does.
Mothusi: So, now that you are sure to use Comparator, how would you order by first name and last name?
JS: I will create a separate class that implement Comparator and then pass the object of that class to TreeSet’s constructor like below:
Mothusi: Do you know that you can achieve the same thing using Lambda expressions?
JS: Nope.
Mothusi: Well, this interview is not about Lambdas, but you might want to check how to do that from my tutorials on YouTube @javaSpace.
Mothusi: So far so good. Let’s assume that in addition to ordering by first and last name, you want to also order by department and city.
JS: Shuu! I am going to have to add more if statements I guess?
Mothusi: Well, we can agree that your solution will need to have many nested if statements, which at some point will become difficult to follow? Clearly your solution has maintenance nightmare.
JS: I agree.
Mothusi: So, there must be a better solution.
JS: What is a better solution then?
Mothusi: Well,?a better solution would be to have separate comparators for each attribute and then build one comparator by combining all of them together. And you can achieve this using lambdas without creating classes. How cool will that be?
JS: Wow! I can’t wait to see the implementation.
This approach would be much cleaner and easier to read. See the code below:
Mothusi: As you can observe, the code above does not have any nested if statements nor one if statement. We have scrapped that out and delegated that to a comparator. You will see that we also used a lambda as an implementation. We do not need a "heavy weight" class to achieve that. Important to note that you can use this functional coding style if the interface used is a functional interface, that is, it has only one abstract method. Otherwise, you will not be able to write functional code.
JS: Wow, can't believe I could mimic SQL ORDER BY in Java. This is actually cool.
I have videos on lambdas from my channel. Please check them, I talk about them in details. If you found this article useful please subscribe to my channel. I have created like 90+ videos on Java to assist someone learn Java. Find the link below. Thank you.
Senior Software Engineer @ Alexander Forbes | AMIITPSA
1 年Found myself going through Mothusi’s old posts because I always learn something from what he posts. I actually didn’t fully know the implementation of a Map. The buckets and its implications on the time complexity. This also made me get more insights into how functional interfaces give Java the ability to be declarative and functional. Dankie bro!.