Death by boilerplate: Iterating over lines in a file in Java (vs Scala, Ruby, Groovy)

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInEmail this to someone

This post comes to us from the Code General. It’s a good read and points to some issues that we hope to see resolved when JDK 8 is rolled out.

How to iterate over lines in a file in Java, Scala, Ruby and Groovy

Iterating over the lines of a small text file is a pretty common (and simple) operation. Given how routine this task is you would think that it would require minimal code. Java is quite famous for requiring lots of code to get the job done. Using the standard libraries in Java 6 we typically end up with code looking something like this:

Java 6:

Every Java programmer has at one stage or another had to write code that looks a lot like this. I’ve probably written code looking a lot like this many, many times. Even for someone who can type very quickly it’s a lot of boilerplate. It’s not particularly complicated code, just very verbose. While there are 3rd party libraries (Apache commons,io) that make this much simpler many (most?) developers will rather just use the standard libs.

This may seem perfectly reasonable to a seasoned Java dev, but for anyone coming from Python, Ruby or even C# the amount of code required for this simple task seems excessive. Java 7 improves on this somewhat with ARM (Automatic Resource Management) and by providing utility methods in java.nio.file.Files. I was originally going to write a blog post about how useful this class is for doing file reads with minimal boilerplate code, but alas it still requires some extra plumbing. The readAllLines(Path path, Charset cs) method cuts down on much of the boilerplate. Unfortunately it still requires a path object to be created, along with a charset (no option to use the default on the local system). This results in code along these lines:

Java 7:

If we compare this with virtually any well known modern language the difference is obvious. Consider for example the code required to perform this tasks in Scala, Ruby or Groovy:

Scala:

Groovy:

Ruby:

Notice how much less boilerplate is involved. It only takes one line of code to perform the task. The question which needs to be asked is this: after more than 15 years, reading from a file in Java is still more painful than virtually any other modern language. This would be easy to fix by providing sensible methods with defaults. Imagine something more like:

Please Oracle, add something sensible like this to JDK 8.

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInEmail this to someone

14 Comments

  • Heh, the lack of “Files.readAllLines” is not the biggest problem with Java and is easily fixable with a library function. What is not fixable is the lack of easy control flow abstractions (i.e. functions to be first-class objects).

  • The Groovy code could be further shortened to:

    new File(“blah.txt”).eachLine { println it }

  • Sensible method params plus Lambdas in J8 perhaps should make these look closer to the other langs

  • c_cube says:

    Wait, the java code clearly does not do the same thing as the other snippets! You try/catch exceptions that may occur, which takes 4 additional lines, and would also take several lines in the other languages you make a comparison with…

  • With exception handling in scala:

    allCatch.withApply(err => println(“oops ” + err.getMessage))(Source.fromFile(“blah.txt”).getLines.foreach { println })

    or just use try-catch like the Java version.

  • Thiago says:

    A way shorter way to do that in Java (try/catch not included):
    Scanner scanner = new Scanner(new File(“test.xml”));
    while (scanner.hasNextLine()) { System.out.println(scanner.nextLine()); }

  • Thiago says:

    I forgot to mention that java.util.Scanner is present since Java 5 and it seems to be overlooked by even most Java programmers.

  • cayhorstmann says:

    In Java 7, you can use

    Files.copy(Paths.get(“/home/cay/.bashrc”), System.out);

  • Frisian says:

    Re-inventing the wheel takes more lines in Java. Big deal. Java is clearly doomed.
    Java is not only a language, but an eco system. That’s why sane programmers take a look at the JRE or at open-source-projects, that do the job at hand. Preferrably faster, better tested and on a higher level. How many ORM tools, application servers or databases are available for Scala, JRuby or Groovy if it weren’t for the JVM?
    Besides, the Java version you presented is imho easier to read compared to the code in other languages.

  • says:

    If you import Source.fromFile instead of just Source, you can get the Scala example to be as short as:

    fromFile(“blah.txt”).getLines foreach println

  • Gimi says:

    We must not forget, that java needs some more lines, but also try catches IOErrors, and as mentioned by @Thiago, there is the Scanner class which enables you to write the code as one-liner.

    Nonetheless the question is:
    1) Is shorter code more readable?! IMHO not necessarily.
    2) How about debugging? The Java Code is definitely much easier to debug, right?!
    3) You can write a static method, which can do all the stuff for you and it needs only a method call in order to print a file. So it is definitely (still) the way to go, since we are not talking here for “hello world” programs but in most cases about projects with millions of LOCs
    4) Is a developer more productive, when he/she has to write less code? Again, not necessarily, since you have IDEs, which writes a lot of this code for you. i.e. to write a main method in Java, you need in eclipse exactly 7 key presses.
    5) why waste so much time and energy to point out something everyone knows and millions of other bloggers already pointed out? everyone knows that java is more verbose than other languages..

  • agimi says:

    We must not forget, that java needs some more lines, but also try catches IOErrors, and as mentioned by @Thiago, there is the Scanner class which enables you to write the code as one-liner.

    Nonetheless the question is:

    1) Is shorter code more readable?! IMHO not necessarily.

    2) How about debugging? The Java Code is definitely much easier to debug, right?!

    3) You can write a static method, which can do all the stuff for you and it needs only a method call in order to print a file. So it is definitely (still) the way to go, since we are not talking here for ”hello world” programs but in most cases about projects with millions of LOCs

    4) Is a developer more productive, when he/she has to write less code? Again, not necessarily, since you have IDEs, which writes a lot of this code for you. i.e. to write a main method in Java, you need in eclipse exactly 7 key presses.

    5) why waste so much time and energy to point out something everyone knows and millions of other bloggers already pointed out? everyone knows that java is more verbose than other languages..

  • Ants Bull says:

    ugh – what a biased article – why don’t you just ignore the exceptions in the Java code like you are doing in the other languages?

    Additionally multiple Java statements can be executed on the same line also – but you chose to space your Java code out, yet the other three have opening and closing code blocks on the same line.

    Biased much?

    Ruby etc is great for little prototype projects or small web-sites that no-one ever visits. Try running Ruby for an enterprise scale project, and you will quickly ditch it, much like Twitter did. I got sick and tired of the Twitter servers continually not being able to service requests – all thanks to Ruby. Haven’t had that problem once since they put a decent Java architecture behind it.

Leave a Reply

Subscribe to get the latest updates