Rewriting Java in Scala & Making Code Lovely 1 - Case Classes

This is the first in a series of posts for people who know Java and are learning Scala. Apart from teaching Scala I hope these posts show how Scala makes your code lovely...

What does more lovely mean?

Lovely covers several things:

  • More concise
  • More readable
  • Easier to debug
  • Easier to test
  • Easier to maintain

I'm not saying Scala is a silver bullet - I'm saying it gives you more time and support to get the hard parts right.

Anyway, on with the show. First up:

Case Classes

Case classes in Scala look something like:

case class Employee(name : String)
They are a short-hand for defining simple classes. They provide you with default implementations of equals, toString and hashCode. They also provide you with some handy tricks when doing pattern matching (which I'll talk about in a future post).

The great benefit of case classes is that you can take a Java class such as:

class Point {
  private int x;
  private int y;
  public Point(int x, int y) {
    this.x = x;
    this.y = y;
  }
  public String toString() {
    return "Point(x: " + x + ", y: " + y + ")";
  }
  @Override
  public boolean equals(Object obj) {
    if (!(obj instanceof Point)) {
      return false;
    }
    Point other = (Point)obj;
    return other.x == x && other.y == y;
  }
  @Override
  public int hashCode() {
    return x * 17 + y;
  }
}
and rewrite as
case class Point(x : Int, y : Int)
That's it.

No, really, that's it.

You can provide different implementations of toString, equals and hashCode if you really want to. But the majority of the time the default implementations are spot on.

What's this given us?

More concise, more readable

It's a one liner. But, it's not a Perl one liner ;-)

Easier to debug

There isn't any functionality here to debug - but the standard toString makes debugging code that uses this class far easier. The default toString will result in something like:

Point(3, 4) 
// The order here is the same as the order in the case class definition

Isn't this nicer than "Point@0x02345678" as a default?

Easier to test

There's nothing to test. It's reasonable to assume that Scala gets the default toString and equality methods correct - so why test them again?

Easier to maintain

Future maintainers don't have to look at the toString, equals and hashCode methods when they familiarise themselves with the class. As they don't exist, they can't introduce bugs there either!

Summary

Case classes are a great way of defining simple and useful classes with very little code. Goodbye huge files for simple POJOs.

Discussion

blog comments powered by Disqus

Colin Howe

I'm Colin. I like coding, ultimate frisbee and startups. I am VP of engineering at Conversocial