Revisit equals and hashCode contract

I have written a blog post about equals and hashCode contract. But now realised that this does not paint complete picture. There are some other scenario which needs to be covered.

Here is list of two videos which explain clearly about internal details about Hash based collection and why equals and hashCode contract is required in Java. I will try to explain all possible scenario that can be wrong when we don’t follow the contract.

Case 1 When class does nothing about equals and hashCode : When we do nothing to hashCode and equals method, each object will have their own default hashCode and these will be treated differently. Let’s assume if we have a HashSet of Employee object.

HashSet<Employee> employees = ….;

Employee key = new Employee….

employees.get(employee)

When we try to fetch employee from employees, it will always return null. It is because of the fact that each Employee object will have unique hashSet(as we have not overriden hashCode method). When we try to find employee with key, there will be a very good probability that it maps to different bucket and will never be able to fetch the correct value. It is like finding a person’s home on wrong street.

Case 2 When class overrides equals but not hashCode :  It will not work because of the reason given above. equality with equals is checked, after going to a bucket. If we are in wrong bucket then even if equality returns true we are fetching wrong object. It is like two person having same house number but in two different address. If we could not find correct street number there will always be a good chance that we deliver our mail to wrong person.

Case 3 When class overrides hashCode wrong but forget to override equals :  Assume a case when we override hashCode to return a constant value(Say 100) for all objects and don’t override equals method. In this scenario, all values in the collection will map to a single bucket. When two object maps to same bucket, Java maintains a liked list to store these. So, in this scenario, we will end up with a linked list, which is inefficient. Lets check what happens when we try to fetch the value from linked list. As all object has same hashCode we will be able to reach the correct bucket, but it will always fails to do equality comparison(as Objects default equality checks memory address and two objects will never have same memory address).

Case 3 When class overrides hashCode wrong but override equals correctly:    Assume a case in which we override equals correctly but always return constant value(say 100) from hashCode. This will work correctly but the created Map will be inefficient as all value will be mapped to a single bucket and hence we virtually end with a Linked list.

Case 4 Correct implementation of hashCode and equals:  This works correctly as computed hashCode and equality  will solely depends on the state of the object and whenever we create new object with same value it will end with same hashCode and hence same bucket.

 

 

 

 

 

 

One of the best talk about Software Architect Roles

I have watched and read many articles which explains the role of Software Architect roles, and personal qualities required to be successful. But none of them is as good as this one. This one perfectly nails it down and clearly explains the role. It will clearly gives you the kind of skill required to be a successful architect, moreover it will provide you the answer that “Are you ready for this role?”.

Scala covariance and contravariance

Java introduces generic in version 1.5. When we create a class B which is subclass of class A, then List<B> is not a subclass of type List<A>. Which is little weird but its like that.

Scala extends this to next level and give flexibility where a generic class(say List)  can be or can not be subclass of A. There are 3 possibility.
 1. covariance i.e generic class [B] is subclass of generic class[A]
 2. contravariance where generic class[A] is subclass of generic class[B], reverse inheritance
 2. no relationship, like Java. This is default behaviour.
Lets check this by example. Scala list is defined as covariance, so following code will work fine.
val list:List[A] = List[B]()

Lets define a class with default behaviors, then we will modify this class to check other 2. 

scala> class GenericClass[A] {
| def sayHello = println("Hello Vivek!");
| }
defined class GenericClass

scala> val x:GenericClass[A] = new GenericClass[B]()
:13: error: type mismatch;
found : GenericClass[B]
required: GenericClass[A]
Note: B You may wish to define A as +A instead. (SLS 4.5)
val x:GenericClass[A] = new GenericClass[B]()
^

Here it clearly shows that GenericClass[B] is not subtype of GenericClass[A] and in fact suggesting us to make GenericClass covariance of type A (i.e GenericClass[+A] ) to make it work.

Lets Define GenericClass as covariance of type A

scala> class GenericClass[+A] {
| def sayHello = println("Hello Vivek!");
| }
defined class GenericClass
scala> val x:GenericClass[A] = new GenericClass[B]()
x: GenericClass[A] = GenericClass@47b77e9b

 This works pretty well. Lets check what happens when we make GenericClass as contra variance of type A ie( GenericClass[-A])

scala> class GenericClass[-A] {
| def sayHello = println("Hello Vivek!");
| }
defined class GenericClass
scala> val x:GenericClass[A] = new GenericClass[B]()
:13: error: type mismatch;
found : GenericClass[B]
required: GenericClass[A]
val x:GenericClass[A] = new GenericClass[B]()
^
scala> val x:GenericClass[B] = new GenericClass[A]()
x: GenericClass[B] = GenericClass@1c8873e3

Here we see that GenericClass's inheritance relationship is reversed. Now GenericClass[A] is subtype of GenericClass[B]

There are lots of other feature which is new(with respect to Java) in Scala type system. I will try to explain bound in next blog.
 
 

awk still rocks!

Last week I faced a unique challenging problem where I need to extract multiline soap request from a huge log file. First I thought about using java, then realised that loading a huge file is java could be problematic.  Then I thought about groovy or other interpreted language. Then lastly I found a very simple solution based on awk. I did some awk script in past, for generating huge test file based on some random criteria(Like generating CDR files for load testing). I was simply amazed to see how an awk script can solve this problem so easily.

Lets assume you have huge file with following SOAP request.

   Payload: <?xml version="1.0" encoding="UTF-8"?><vivek xmlns="com.test.vivek">
<Service>
	<Template>abc service template</Template>
	<XRef/>
	<LogMessage/>
	<CallBackUrl/>
	<Delivery>
		<Synchronous/>
	</Delivery>
</Service>
<Model>
	<Head>
		<From>test@test.com</From>
		<Subject>Technical Service &amp; Repair</Subject>
	</Head>
	<ContactUs>
		<Sender>
			<FirstName1>vivek</FirstName1>
			<FirstName2>vivek</FirstName2>
			<LastName1>kumar</LastName1>
			<LastName2>kumar</LastName2>
			<PhoneNumber>9674174848</PhoneNumber>
		</Sender>
	</ContactUs>
</Model>
</vivek>

Here is the the awk script to extract all such xml:

awk '/vivek/,/\/vivek>/'  test.txt   | awk '/Payload:/ {print "*****************"; print } !/Payload/{ print;} ' 

This awk script will extract all text from vivek to /vivek> then we run another awk script which check for work Payload and if its found then it print “***************” then rest of the line containing Payload text, if line does not contain Payload then it simply print the line. We are printing “**************” to keep a boundary between different matched request.

Here is the response from command:-

awk.png

Awk Reference

 

 

Kindle screen freeze issue

I have been using this Kindle 3 from last 8 years. I found this device very useful considering it has a very long battery life and portable. When I was reading last, I found battery to be critically low and left the device. After couple of days when I checked it, for my utter surprise its screen froze, I tried to reset from reset button(hold start button for 20 seconds), but it did not worked.

First I was heisted to open it, considering I was hopeful that it might be a charging issue and keep charging the device continually. But I did not turn up. Then one fine day, I thought as its already dead(or say gone), there is no harm if I open it up and see.
   I searched on google and found reference of a reset point, where I can shot it with a wire to restart the device. I keep trying with different option and finally it worked. It’s highlighted in below screen.
   Note that there are some version of kindle which already has a reset button(highlighted below, first image). in those type it is just a matter of pressing the reset button.
   In my case, I had no such button, the challenge was to figure out two points which needs to be shorted to reset the device. Finally I used a safety pin to short these and and it all started working.

Update after a long time..

Much time has passed since I write my last post. lots of  important things happened since I  had written my last last post, most important of those is moving to new organization and new city after a long time. I had some doubts and fear before moving to AKQA, but now I feel like its worth moving to new younger company.

Another thing, is to learn new stuff, CQ or(AEM) and whole lot of new technical movement that is  happening around in DevOps  (Chef, puppet) Microservices, which is the driving factor around all..

Here I found one interesting video about Microservices

Last but not least and most important

<

New Work

My friends has started a new site