Categories
java.time Kotlin

Finding a Date From a Year and an ISO Week Number

Once a year inevitably the time arrives when you need to print a new calender for your pinboard. You know, end of february. And this year I wanted try a new layout, focused on weeks.

I vaguely remember coding some calender generator that would output a simple SVG file but for the life of me I couldn’t find it. I knew I had to have had it last year because I printed last year’s calender with it but the source code was nowhere to be found, and no combination of search phrases could make it show up.

That meant I had to solve all those tiny little problems again because no matter the API, dates are simply a horrible concept and should be abolished in favour of something simpler.

One especially pesky problem I needed to solve was to find a date given a year and an ISO week number. The only solution I could find was rather ugly:

DateTimeFormatter.ISO_WEEK_DATE
  .parse("${year}-W${"%02d".format(week)}-1")

Even though this is an incredibly terrible solution I am giving this type of calender a try this year:

If you are interested in trying it as well, grab the PDF!

Categories
Kotlin Testing

Mocking Without Mockito

In recent years I have grown to like Mockito, everybody’s favourite and invaluable testing helper, less and less. Using a bytecode-twiddling framework to get your code to behave well in tests makes it hard to reason about the tests, and because Mockito (and other mocking frameworks) tend to use a lot of global state to configure the mocks, it’s possible to break test code by refactorings that on “normal” code are totally safe.

I have adopted a different approach for software I develop that does not use Mockito or any other mocking framework but relies on basic JVM features like interfaces and their implementations.

Categories
Java Kotlin Streams / Collections

Getting a Ratio Using a Single Iteration

Recently I came across the question of how to calculate the ratio of elements of a stream to the total number of elements in said stream. The naïve solution would be:

collection.stream()
  .filter(it -> it.completed())
  .count() / collection.size()

However, depending on where collection came from this might iterate it twice, producing unnecessary load or I/O while doing so. Also, we would need to cast one of the two values to a double otherwise your result would be 0 pretty much all the time.

This is very ugly.

One possible solution is to use a Collector to do the ratio calculation for us. For this we would need a Collector that keeps track of the total number of elements and the number of elements that are completed. Lucky for us there is such a Collector already: the averaging collector. If we map all completed elements to a 1 and all not-completed elements to a 0, the result of the average will match the ratio we are expecting:

collection.stream()
    .collect(Collectors.averagingInt(it -> it.completed() ? 1 : 0));

In Kotlin, there is an average function defined on Iterable<Int> so you can do something very similar:

collection.map { if (it.completed()) 1 else 0 }.average()

You could even combine that with an extension method and turn it into:

collection.map(Foo::toCompletion).average()
…
private fun Foo.toCompletion() =
  if (completed()) 1 else 0
Categories
Kotlin Topics

How to Correctly Bind Instances With Guice

Yesterday I have had a weird experience with Guice. I always thought that I pretty much knew what it did when you restricted yourself to the simpler binding methods, such as toInstance or toProvider. Take a look at this (Kotlin) code:

Categories
Kotlin Sone Topics

Sone Is Being Kotlinized

About a year ago Jetbrains released Kotlin 1.0, a new JVM-based programming language. I took a short look at it and pretty much immediately fell in love with it: it is very similar to Java, uses considerably less boiler-plate, has properties, improved collection interfaces (while using all the known java.util stuff under the hood), and lambdas.

I started to introduce it in the company I currently work for and nobody who has used it for more than two lines wants to go back to writing Java code.

Needless to say, I started using it for my private projects, too. One of the good things about Kotlin is that it integrates with existing Java code very nicely. Compiling Java and Kotlin source code with Gradle with both parts depending on the other works out of the box. Java code can use Kotlin classes and the other way around with pretty much no restriction. This makes it very easy to update existing projects: write new code in Kotlin, continue using the old Java code until it’s time to replace it.

So far, Sone profitted from Kotlin most of all: as I am in the process of writing lots and lots of tests for everything that Sone does (and it is amazing how many bugs you find once you actually unit test your code) the news tests will – of course – be written in Kotlin. I also already added some new features to Sone, again using Kotlin.

Several places in Sone collect elements (such as posts) from all over the place, filter them, sort them, all using Guava and Java 1.6-compatible syntax only. This requires a lot of extra code to be written. Take a look at this:

Collection posts = new ArrayList<>(sone.getPosts());
for (String friend : sone.getFriends()) {
  Optional friendSone = core.getSone(friend);
  if (!friendSone.isPresent()) {
    continue;
  }
  posts.addAll(friendSone.get().getPosts());
}
posts.addAll(core.getDirectedPosts(sone));
posts = Collections.filter(posts, Post.FUTURE_FILTER);
posts = Collections.sort(posts, Post.DESCENDING_BY_TIME);

Code very similar to this exists in several places in Sone. Now take a look at the equivalent Kotlin code:

val posts = (sone.posts +
    sone.friends.mapNotNull(core::getSone).map(Sone::posts) +
    core.getDirectedPosts(sone))
  .filter { it.time <= System.currentTimeMillis() }
  .sortedByDescending { it.time }

Now go ahead and tell me that this isn’t better (this even works for almost arbitrary definitions of “better.” Yes, Kotlin is just that good).

In addition to actually making me want to work on Sone again it will also reduce the amount of production code in Sone, making it easier to review. However, as I don’t expect any review activity to take place before 2030 (and probably not even before the Great Singularity™) this was not a criterium which played any role in my decision to gradually convert Sone to Kotlin.

Simply put: Kotlin makes programming fun again.