To use, or not to use…

Recently, I have started use Scala in my daily job actively. And now I have better understanding of all these people who shout that Java sucks. Being big Java  fan for a long time I can’t deny that for some task it is not designed well. More modern languages do the same job much better. This post is just another (there are plenty of them in internet) example, but it comes from real life scenario, so I think it worth to share it.

Let’s say we have a collection of entities in an arbitrary order. And we have list of entities ids. What we want is method that returns list of entities in the same order as provided list of ids. Example, below shows how you can implement it in Java while it still readable and easy to understand:

private List<Entity> sortEntitiesById(Collection<Entity> unsortedEntities, List<Long> ids) {
    Map<Long, Entity> entitiesMappedById = new HashMap<Long, Entity>();
    for (Entity entity : unsortedEntities) {
        entitiesMappedById.put(entity.getId(), entity);
    }

    List<Entity> sortedEntities = new ArrayList<Entity>();
    for (Long id : ids) {
        Entity entity = entitiesMappedById.get(id);
        if (entity != null) {
            sortedEntities.add(entity);
        }
    }
    return sortedEntities;
}

Pretty straightforward code. We create temporary map, where we place entity id as a key and entity itself as value. And then iterate through the list of sorted ids and build result list using newly created map. No rocket science at all. Easy to understand what is going on. And not so difficult to write, isn’t it?

But that’s what all these java haters call boilerplate. Let’s take a look how can you implement it in scala, for example.

def sortEntitiesById(entities: List[Entity], ids: List[Int]) = {
    ids.flatMap(id => entities.find(e => e.id == id))
}

Feel the difference? It is hard to deny that second looks at least much shorter. What about readability then? Well, it is just matter of getting used to language syntax, after all it is much easy to read 3 lines instead of 15.

What about functional libraries which brings you functional style to a Java program, you can ask. Unfortunately, it is far not so elegant as it can be solved in some modern languages. For example, look at Java code with Guava which solves the same problem in a more functional style:

    private List<Entity> sortEntitiesByIds(final List<Entity> entities, final List<Integer> ids) {
        List<Entity> sortedEntities = transform(ids, new Function<Integer, Entity>() {
            @Override
            public Entity apply(final Integer id) {
                return find(entities.iterator(), new Predicate<Entity>() {
                    @Override
                    public boolean apply(Entity entity) {
                        return id == entity.getId();
                    }
                }, null);
            }
        });
        sortedEntities.removeAll(newArrayList((Entity) null));
        return sortedEntities;
    }

From my personal opinion, it looks even worse than purely imperative style from the first example. And that is not because of Guava, which is very nice and useful library. It is because of Java.

Instead of conclusion I would like to share some thoughts. Looking at modern functional and hybrid languages like Haskell or Scala, it is obvious that Java has to adopt features from other languages, and preferably do it as soon as possible. And Oracle engineers are doing great understand it and doing great job. But for developers there is no excuse anymore to work with Java only. Scala, for example, and other JVM based languages solve some tasks in much more elegant and efficient way than Java. I don’t say that we should stop using Java, because for a lot of tasks it still a good and maybe best option. But we should also realize that Java is just another tool. Powerful, stable and mature but just a tool. And if other tools suite better for solving some problem let’s would not be conservative and start use new tools.

Leave a comment

2 Comments

  1. Dzmitry Busel's avatar

    Dzmitry Busel

     /  July 24, 2012

    Shorter code and “good style” are not enough reasons, I think. You do not know how this code works. At the best – end implementation is the same. But it may be difficult to understand shorter code.

    Reply
    • D. Kuzniatsou's avatar

      I am not sure that I interpret your comment correctly, but will try to give my opinion about it anyway. If you talking about that it is not clear from a shorter version of code what it is doing or in other words that code is nor readable, then I believe it is just a matter of getting used to a new syntax.

      Basically, Scala code in the example above it is pretty straightforward. It iterates through the list of ids and for each id it executes function which finds entity with the same id. Result is a list of all found entities.

      There are lots of hardly readable Scala code examples, but there are tones of Java unreadable code also. So it is not matter of language, but people who write it. Maybe, I will write a new post about it with some examples.

      If you talk about performance and inner algorithms then it is a little bit different topic, but you can always deserialize java bytecode and measure performance also. From my experience, I have not seen Scala causes performance issue. But I can imagine that can happen. But in this case, that is what this post about. Know your tools and use appropriate. Don’t use a screwdriver when you need hammer, and other way around.

      Reply

Leave a reply to Dzmitry Busel Cancel reply