Monthly Archives: October 2014

Where Do Old Programmers Go?

Every once in a while a topic comes up on Hacker News: Where Do Old Programmers Go?” That’s a good question. Where do they go? What does the future hold for software engineers as they progress in their careers?

Speculation ranges from moving into management, to moving on to different fields, to continuing coding with business as usual. I don’t know the answer myself (in fact, there may be no single answer, it may vary by location or time, or multiple factors may be at play). But I read something from good old Uncle Bob recently that seemed to make a lot of sense, so wanted to share it here.

Go ahead and read Uncle Bob’s view, I’ll wait for you.

He says: “… where did they all go? Why are half the programmers in the world under 30? Do older programmers quit? Do they move on to management? Do they burn out and become chicken farmers? Why does the age distribution fall off so rapidly after age 30? Actually, most of the old programmers are still here and are still coding. The problem isn’t that the old programmers are fading away. The problem is that the number of programmers is growing by a huge factor every year.”

He backs up his assertions with facts and some math, which make the argument much more compelling than the idle speculations and anecdotes that so frequently appear on discussion forums.

Anyway, hopefully this will be some food for thought to those who are older (40’s, 50’s, 60’s, and beyond) wondering why the age distribution is what it is.

2 Comments

Filed under Software Engineering

Using Optional to Prevent Null Checking

We’ve all written (or at least seen) code like this:

if(myObject != null) {
    myObject.callSomeMethod();
}

Null checking, if left unchecked (!), can grow out of control. Fortunately, there are ways to structure your code to avoid too many null checks. For instance, keeping all null checks at the boundaries of your application lets the rest of the code presume no nulls. Additionally, judicious use of the Null Object Pattern can help to keep things clean.

Keeping those techniques in mind, we can do even more to prevent null checks from cluttering our code: Java’s Optional class.

Oracle has an excellent article explaining how to use Optional to circumvent null checking, and I recommend reading it. My blog post here is not intended to replace that article. I just want to do a little exposition about using it in a real world scenario.

In a recent blog post we were talking about implementing a HashMap. We don’t need to rehash (!) all the details here, but here’s a quick explanation of one method in particular:

private LinkedList<Entry<K,V>> getElementList(K searchKey) {
   int index = searchKey.hashCode() % elements.length;
   if(elements[index] == null) {
      elements[index] = new LinkedList<>();
   }
   return elements[index];
}

In english: we’re calculating the index of an array of lists, and if the array at that index has a list in it we return the list. Further, if that index is empty we create a new list, assign it to that element in the array, and return it. One way to circumvent the null check is to initialize the array with new lists before we start using it. But we might not want to do that if we want our map not to allocate too much memory up front, or to be faster to initialize.

This is a short method, but can we do better? How about using the ternary operator to reduce the check to a one-liner:

private LinkedList<Entry<K,V>> getElementList(K searchKey) {
   int index = searchKey.hashCode() % elements.length;
   elements[index] = (elements[index] == null) ? new LinkedList<>() : elements[index];
   return elements[index];
}

It’s more concise, sure, but the complexity is the same (the method has a cyclomatic complexity of 2 because there are two logical paths through the method). Can we do better? Using Apache Commons ObjectUtils lets us reduce the cyclomatic complexity to 1 since there is only one path through the method.

private LinkedList<Entry<K,V>> getElementList(K searchKey) {
   int index = searchKey.hashCode() % elements.length;
   elements[index] = (LinkedList<Entry<K,V>>)ObjectUtils.defaultIfNull(elements[index], new LinkedList<>());
   return elements[index];
}

The cyclomatic complexity has been reduced, but a new object (the new LinkedList()) is instantiated each time whether we need it or not. Can we do better? We can use Optional with a lambda (here, () -> new LinkedList()) which is only called if the element is not present.

private LinkedList<Entry<K,V>> getElementList(K searchKey) {
   int index = searchKey.hashCode() % elements.length;
   elements[index] = Optional.ofNullable(elements[index]).orElseGet(() -> new LinkedList<>());
   return elements[index];
}

Finally we are using Optional for its intended use case!

So at this point we have:

  • eliminated null check from three lines to one
  • reduced complexity from two to one
  • only instantiate the new list if it’s actually needed.

Not bad for using Optional in the wild! Hopefully things gives a small taste of how useful Optional can be.

Leave a comment

Filed under Software Engineering

Equals and HashCode Part IV: The Implementation

Over the last few posts we have been looking at the equals and hashcode methods by way of implementing our own HashMap, and followed up with how to unit test them. Now that we have an understanding of the equals and hashcode contract, and have a good way to test implementations, let’s look at some ways to actually implement them.

Roll Your Own

It’s not recommended to write your own from scratch since there are libraries and other ways to do this that take the guesswork out of how to best implement it. Nonetheless, implementing your own can at least be instructional.

I recommend some foundational reading just to have an understanding of the issues involved. To really have a good grasp of implementation concerns, I highly recommend reading Josh Bloch’s Effective Java. In the 2nd edition, Chapter 3 Items 8 and 9 (“Obey the general contract when overriding equals” and “Always override hashCode when you override equals”) he covers equals and hashCode implementation concerns in great detail, and it is a must read for anybody who’s implementing equals and hashCode.

IDE auto generate

Better than writing your own code is to let your IDE generate it for you. Any of the major IDE’s (Netbeans, Eclipse, IntelliJ) will do this. For example, in Netbeans you can navigate to Source > Insert Code > “equals() and hashCode() …” and select the fields to be included.

The positive side is that the generated methods will take care of all the boilerplate such as checking for null, checking class equivalency, and so on. The knowledge of how to use fields to best generate these methods has been collected and refined over the years, and baked in to the IDE itself for your benefit. It’s not a bad idea to leverage that knowledge and experience instead of going out on your own.
The downside is that you need to remember to regenerate these methods if you add a member variable. Also if you prefer using a lightweight IDE you may not have source generation capabilities available to you.

Apache Commons

Another alternative, and one that is perhaps easier to read than IDE-generated code (and perhaps more consistent across IDE’s) is the capability provided by Apache Commons Lang. You can use EqualsBuilder and HashCodeBuilder to implement these methods very effectively. The details for using them are in the javadocs, but in a nutshell you can just write code like this:

public class Person {
   String name;
   int age;
   boolean smoker;
   ...

   public int hashCode() {
     // you pick a hard-coded, randomly chosen, non-zero, odd number
     // ideally different for each class
     return new HashCodeBuilder(17, 37).
       append(name).
       append(age).
       append(smoker).
       toHashCode();
   }
 }

This gets around the requirement to depend on your IDE, but you still need to remember to modify these methods yourself if you add a new member variable.

Project Lombok

Finally, there is Project Lombok. Using the @EqualsAndHashCode annotation you essentially get equals and hashCode for free. The accumulated knowledge about implementation is embedded in the library for you to leverage. And can even ignore having to modify those methods if you add new member variables! So this solves all of our problems, right? Well… kind of.

For one thing, you should always be aware of what equals and hashCode are doing in relation to your member variables, so you will still need to at least consider if new members should be included or excluded in those methods. So no matter what technique you use, you need to keep those methods in mind.

Another thing about Project Lombok is that there are some caveats for using the library. You should carefully consider the costs and benefits of the library and evaluate whether use of this library is right for you.

Conclusion

Whether you roll your own, generate the code, or use a library: knowing your options and the related tradeoffs are a foundational part of being a good Java developer. Again, I encourage everybody to read up on it, understand it, and at least be able to recall the possibilities for implementing these methods. Your code – and your customers – will thank you!

Happy HashCoding!

Leave a comment

Filed under Software Engineering

Equals and HashCode Part III: Unit Testing

Over the last two posts we have been looking at the equals and hashcode methods by way of implementing our own HashMap.

If you are feeling daring and want to start actually overriding these methods, you will of course want to test them. In the interest of test-first, let’s look at testing techniques before we get to the nuts and bolts of implementing equals and hashcode! Let’s review some of the options for unit testing equals and hashCode:

Roll Your Own

Many people start by reviewing the contracts as defined the the API and writing individual unit tests for each part of the contract for equals and hashcode. After a point, they realize that the testing of their code can be refactored into reusable code. The sample listed here looks useful albeit not actively developed.

JUnit Extensions

If you like sticking with what your framework gives you, you will probably look at JUnit Extensions and find EqualsHashCodeTestCase. This option is closer to being an actual part of JUnit, but the code here is older and requires your test classes extend a particular TestCase, not to mention requiring you to write code for specific objects to test against.

JUnit Theories

There is a way to use JUnit Theories to test equals and hashCode. This technique is newer than EqualsHashCodeTestCase but a little harder to use, as again you need to define all the objects as @DataPoints for use in testing. Additionally it requires the test to be run with its own test runner which would require you to break your test apart if you want to test these methods in a test class already using another test runner.

EqualsVerifier

After a bit of research I found a test technique that I think is the most modern, comprehensive, and easy to use: EqualsVerifier. Once you include the library as a test dependency, unit testing your equals and hashcode methods can be as simple as

@Test
public void testEqualsHashCode() {
    EqualsVerifier.forClass(My.class).verify();
}

The library is actively maintained and you can feel free to jump in to the google group or check out the code on github. The owner is friendly and responsive, so issue reports and pull requests are welcome!

1 Comment

Filed under Software Engineering