Tag: Java

  • Java Tip #12: Use Collection min()/max() when looking for lowest/highest item in collections

    At work I regularly stumble across a specific type of processing: sorting a collection/list and afterwards only retrieving the first or last element. Such code constructs are clearly for fetching the minimum or maximum element but sorting the whole collection for just a single item seems to be a bit of overhead. And indeed it is and the Collection class provides methods for these purposes without having to juggle items in memory and creating new collection objects which are never really required.


    Advice

    If you have a collection and want to retrieve the minimum or maximum element from it you don’t have to sort it and retrieve the first or last but java.util.Collections offers its min() and max() methods for that which are much more efficient for that exact purpose. These can also be used with custom Comparators.

    Code-Example

    Before

    // retrieve smallest element
    Collections.sort(elementList);
    Element smallest = elementList.get(0);    
    ...
    // fetch item with highest custom value
    Collections.sort(customItemsList, Collections.reverseOrder(new MyCustomComparator()));
    Item largestItem = customItemsList.get(0);

    After

    Element smallest = Collections.min(elementList);    
    ...    
    Item largestItem = Collections.max(customItemsList, new MyCustomComparator());

    Benefit

    Readability gain. Possible huge performance gain, as min()/max() run in O(n) while sorting takes O(n log(n)).

    Remarks

    If the comparison methods (compare(), equals()) do not fulfill the Comparator requirements according to the Java SDK (see here) (i.e. A.equals(B) != B.equals(A) or (A<B)!=(B>A), etc.) then the result of min()/max() may be different than the result from the approach using sorted collections.

  • Measure your assumptions, and then measure again

    Happy New Year! I planned to have a blog post finished before 2013 ended but this didn’t work out. Hopefully this one compensates that a bit.

    A little while ago I began preparing another post in my series of Java Tips. Well, this posting is still due but for now I can present you another one where I give a short look on some investigation the preparation of this Java tip required.

    It originated in a couple of Sonar warnings on one of our development systems on my job. Specifically the warning about the inefficient way of converting a number to String spiked my interest and I began evaluating the places where these warnings showed up. The warning itself told that there were conversions of numbers to Strings in the form of

    String s = new Integer(intval).toString();

    which should be better expressed from a performance point of view as

    String s = Integer.toString(intval);

    Some time during this investigation I became curious if there is really a large effect between the different solutions and wrote a short test case which measured the time of different ways of converting an Integer to a String. Interestingly it did not exactly turn out as clear as I hoped. Initially it seemed that the error claim did not match the reality as my testcase did not show a clear performance advantage of any specific solution. Most ways of converting values to strings were pretty close to each other and the results varied with each execution a bit so I considered this to be mainly a measuring inaccuracy.

    // Results with 100000 invocations of each method, timed using System.nanoTime()
    new Integer(int).toString()      : 7075890
    String.valueOf(int)              : 6570317
    Integer.valueOf(int).toString()  : 9597342
    Integer.toString(int)            : 11398929

    With those combined results I could have been satisfied and discard the Sonar warning as just some hint to write more readable code. But something didn’t feel right and after some time I had another look at this. Especially the last measurement looked quite odd. What was the difference between a static call (line 4) and a method call on a new object (line 1) so that the results are about 25% apart. And if so, why is the static call the slower one? Using the Java Decompiler Eclipse plugin I inspected the underlying source. I could have used the the source search engines available elsewhere (e.g. GrepCode) but that was just too cumbersome for a quick investigation and not safe to reflect the actual (byte-)code used. The decompiled source of java.lang.Integer made the observed difference even more mysterious.

    ...
    public String toString()
    {
      return toString(this.value);
    }
    ...
    public static String toString(int paramInt)
    {
      if (paramInt == -2147483648)
        return "-2147483648";
      int i = (paramInt < 0) ? stringSize(-paramInt) + 1 : stringSize(paramInt);
      char[] arrayOfChar = new char[i];
      getChars(paramInt, i, arrayOfChar);
      return new String(arrayOfChar, true);
    }
    ...

    Ok, so the call on toString() on a new Integer object is in turn jumping to the static toString(int) method? In that case my previous measurements must have been influenced by something else than just the sourcecode itself. Most probably some effects from JIT compilation by the HotSpot JVM. And therefore the measurements were not usable until I made the effect of JIT compilation neglectable. What’s the easy way of making JIT compilation a neglectable factor in measurements? Crank up the number of iterations of the code to measure. The 100k iterations in my first test ran in a mere seconds, maybe not long enough to properly warm up the JVM. But after increasing the iteration count by a factor of 1000 (taking significantly longer to run) following numbers were the result:

    // Results with 100000000 invocations of each method, timed using System.nanoTime()
    new Integer(int).toString()      : 6044546500
    String.valueOf(int)              : 6052663051
    Integer.valueOf(int).toString()  : 6287452752
    Integer.toString(int)            : 5439002900

    Raising the number of iterations even more did not change the relative difference between the numbers much so I think at that stage JVM and other side effects are small enough to not change the execution speed significantly. It also better fits to my expectations of the running costs when roughly brought into correlation of the execution path, logic executed and functions called of each individual conversion variant.

    At that point I’m pretty confident that I now better understand the reasons for the initial Sonar warning and that the static method call is roughly 10% faster than calling toString() on newly created objects. And that’s even without burdening an additional Integer object to the garbage collection which at a later stage takes some additional time to clean up.

    Of course, I’m aware that this is a topic which dives deep into the micro-optimization area. On the other side it can be boiled down pretty easily to using certain methods in favour of other methods, as there is no drawback on safety or functionality and at the core the same static method will be called anyway. Furthermore, ignoring simple performance and memory optimizations may not affect you on small scale like client applications or Java applets but may be pretty relevant on larger (server) systems or even time-critical installations. For a more detailled description why this is relevant on server systems and how it affects throughput and garbage collection times see this excellent list of Java Anti-Patterns.

  • A trapdoor in Apache Commons CollectionUtils (and its docs)

    A few days ago I hit a problem while refactoring some legacy Java Code. Following my own advice to [use safe and simpler library methods][1] I changed the code-block

    List
    list = dao.getEntries(id); if(list != null && list.size() > 1) { doFancyLogic(list); } to List list = dao.getEntries(id); if(CollectionUtils.size(list) > 1) { doFancyLogic(list); } Should do the same, looks nicer and should be safer too, right? Imagine my confusion when suddenly several unit tests began failing at other parts of the code not directly related to this change. When I found out that this single line was the cause of the other errors I of course looked up the JavaDoc for CollectionUtils on Google. According to the docs at the size() method should return 0 when presented with a null collection. Things were very strange here. In fact, it took me a few days to find out what’s wrong. In fact, I did not recognize that the access to the JavaDoc was redirected to , which did not show the documentation of the latest stable CollectionUtils docs (as it did until a few weeks ago) but showed the version of the SVN tip. It took a roundtrip through the Apache Commons main page to find the correct JavaDoc page for the current stable 3.2.1 CollectionUtils at . And, surprise surprise, there the API for the size() method looks a *bit* different: “Throws: java.lang.IllegalArgumentException – thrown if object is not recognised or null”.
    Well, so much for the praised null-safety of Apache Commons… In the current implementation, CollectionUtils.size() is of no use for me and I reverted the refactoring. In the end I was a victim of partly my own assumptions for the null-safety of Apache Commons and partly a very weird redirection of the Google search result URL. I still have no idea why this URL suddenly gets redirected to a different version than it did until a few weeks ago but I hope that either Google soon updates its search result (unlikely as there are loads of references to this address) or Apache corrects it to its former destination. For the safety of users in my opinion the correct version which shows up should be the one of the latest stable version, not an arbitrary SVN version. Lesson learned: also check version of JavaDoc if something smells fishy, even if it has been correct in the past. [1]: http://kosi2801.freepgs.com/2010/10/02/java_tip_9_use_collectionutils_for_evaluation_and_manipulati.html “Java Tip #9: Use CollectionUtils for evaluation and manipulation of Collections”
  • Java Tip #11: Use ObjectUtils.toString() for an implicit null-check and default value

    Another quick addition to my Java Tips series. This instance deals again with adding some safety while reducing a bit of code clutter.


    Advice

    Use Commons ObjectUtils.toString() instead of directly calling toString() on an object if it may be null. This also allows for a alternate result if the object is null.

    Code-Example

    Before

    final String projectId = (request.getParameter("projectid") != null) ? request.getParameter("projectid").toString() : "";
    final String roleId = (request.getParameter("roleid") != null) ? request.getParameter("roleid")
            .toString() : "DEFAULT";

    After

    final String projectId = ObjectUtils.toString(request.getParameter("projectid"));
    final String roleId = ObjectUtils.toString(request.getParameter("roleid"), "DEFAULT");

    Benefit

    Readability gain. Safety gain, as ObjectUtils methods are null-safe. The reduced code footprint eases recognition of the intention, which is even more significant if there should be a default text if the object instance is indeed null.

    Remarks

    None.

  • Coding trick: Toggle code with comment switch

    Some time ago I stumbled over a neat trick in programming languages which understand C++-like comment lines (single- and multi-lined comments). This allows toggling between two different blocks of code by just adding or removing a simple ‘/’ character in the first line.

        /*  <<- Add/remove one '/' here to toggle active code block
        String mode = "release";
        /*/
        String mode = "debug";
        //*/

    I found this somewhere on Stackoverflow.com but couldn’t locate the article containing this again. I found a reference to this here but I guess this trick is much, much older than this article.

  • Java Tip #10: The instanceof-operator is null-safe

    Another quick-shot Java Tip. Keeping it simple because I don’t have much time currently. It’s one of the lesser-known facts of the instanceof-operator and I’ve seen it’s applicability in some sources but YMMV.


    ##Advice Use the Java operator instanceof for implicit null-checks. Sometimes there is the need to check for both (eg. in equals()-methods), non-null and a certain class. Instead of checking for each condition seperately one can use just the instanceof operator, which handles a null-pointer in the same manner as a non-matching class.

    ##Code-Example

    Before

    ...
    if (field != null) {
        if (field instanceof SomeClass) {
            ...
        }
    }
    ...

    After

    ...
    if (field instanceof SomeClass) {
        ...
    }
    ...

    ##Benefit Small readability gain.

    ##Remarks This seems to be one of the lesser known facts about Java there can be a small confusion with other participants on the same code who interpret this to an aparently missing null-check. But this comes as no danger when the other person just re-adds the null-check, there should be no bad effect on the logic. Maybe just spread this knowledge to your participants somehow 😉

  • Java Tip #9: Use CollectionUtils for evaluation and manipulation of Collections

    After quite some time this is another instance of the [Java Tips][1]. It’s an addition to the [Apache Commons][2] related [framework tips][3] which are guiding into the direction that as a developer you should take advantage of existing and proven frameworks and know their features to leverage your development efficiency. This time complexity of the given example is a bit higher than in the previous tips.


    ##Advice Use [Apache CollectionUtils][4] for evaluation and manipulation of Collections.

    ##Code-Example A short spoiler for the following code: This is a routine which checks a given set of categories against a set of category-permissions for a user. The result is a set of categories, which the user is allowed to access.

    Before

    ...
    public boolean hasPermissionsToAccessCategory(String category) {
        return (this.permissions != null && this.permissions.contains(category));
    }
    ...
    
    ...
    public Set
    getCategoriesAllowedToViewBySearchFilter() { Set result = null; if ((this.filter != null && this.filter.getCategory() != null) && (!this.filter.getCategory().isEmpty())) { result = new HashSet (); for (String category : this.filter.getCategory()) { if (this.hasPermissionsToAccessCategory(category)) { result.add(category.toString()); } } if(result.size() == 0) { result = null; } } else { result = this.getAllCategories(); } return result; } …. After … public Set getCategoriesAllowedToViewBySearchFilter() { Set result = null; if (this.filter != null && this.permissions != null && CollectionUtils.isNotEmpty(this.filter.getCategory())) { // get only categories, which are both in permissions and filter categories result = new HashSet (CollectionUtils.intersection(this.permissions, this.filter.getCategory())); // if no results, return null if(result.isEmpty()) { result = null; } } else { result = this.getAllCategories(); } return result; } … ##Benefit Huge readability gain and a safety gain. The code and intention is much clearer here and also has a smaller footprint. The maintainability has been raised because for a developer not familiar with the routine it needs a bit of brainpower to find out what the initial code really does. The removal of the additional method and usage of *CollectionUtils.intersection()* makes it much easier to understand, how the two sets are compared to each other to retrieve the correct results. ##Remarks None if you are initially writing similar logic. If you’re refactoring a method which seems to be better off with framework-provided functionality be careful and think over it a second time. Re-evaluate the code until you’re really sure because it’s easy to overlook a small detail which changes the results for a certain special case. [1]: http://kosi2801.freepgs.com/cgi-bin/mt-search.cgi?blog_id=8&tag=Java%20Tips&limit=20 [2]: http://commons.apache.org “Apache Commons” [3]: http://kosi2801.freepgs.com/cgi-bin/mt-search.cgi?blog_id=8&tag=Java%20Frameworks&limit=20 [4]: http://commons.apache.org/collections/apidocs/org/apache/commons/collections/CollectionUtils.html “CollectionUtils (Commons Collections)”
  • Java Tip #8: Use StringUtils for concatenating Strings from Arrays or Lists

    And we’re continuing with our next Java Tip. Back on using frameworks for our convenience, I present another often useful possibility to let the StringUtils handle lots of work for you.


    ##Advice Use Apache StringUtils for concatenating Strings from Arrays or Lists, also when you need to delimit them with an arbitrary string.

    ##Code-Example Before

    ...
    SQL_WHERE += " AND V.cat_display_name IN (";
    boolean addComma = false;
    for (String category : filter.getCategories()) {
      if (addComma) {
        SQL_WHERE += ", ";
      }
      SQL_WHERE += "'" + category + "'";
      addComma = true;
    }
    SQL_WHERE += ") ";
    ...
    
    ...
    String SQL = "";
    for(String category: filter.getCategories()) {
        SQL += val + ", ";
    }
    SQL = SQL.substring(0, SQL.length()-2);
    ....

    After

    ...         
    SQL_WHERE += " AND V.cat_display_name IN (";
    SQL_WHERE += "'" + StringUtils.join(filter.getCategories(), "', '") + "'";
    SQL_WHERE += ") ";
    ...

    ##Benefit Huge readability gain and a safety gain. The code and intention is much clearer and the possibility to hide bugs in the loop-logic (which I have seen often) is not present. Also, depending on the length of the Array or List, it may also present a small performance gain (see Java Tip #2) but that’s in most such cases neglibigle.

    ##Remarks None.

  • Java Tip #7: Minimize Map processing

    On to the next [Java Tip][1]. Again, this time I’m staying within the boundaries of the Sun JDK.


    ##Advice When traversing a Map, always use the minimum necessary methods to get keys/values out.
    *

    .entrySet()* vs. *.keySet()* vs. *.values()* ##Code-Example Before … for (String number : phoneBook.keySet()) { PhoneBookEntry name = phoneBook.get(number); if (name != null) { … … for (String parameterKey : paramMap.keySet()) { Object value = paramMap.get(parameterKey); … After … // if only values are needed for(PhoneBookEntry name : phoneBook.values()) { if (name != null) { … … // if key&value are needed for(Entry entry : paramMap.entrySet()) { String parameterKey = entry.getKey(); Object value = entry.getValue(); … ##Benefit Performance gain. Map is only searched once instead twice (and also the hashing for get() is avoided), or there is only the really required data extracted and returned from the map. Furthermore having only the required data around avoids later confusion on the original intent (“… is the key maybe used somewhere or just a leftover?…”). ##Remarks None. [1]: http://kosi2801.freepgs.com/cgi-bin/mt-search.cgi?blog_id=8&tag=Java%20Tips&limit=20
  • Java Tip #6: Use the for-each of Java5 whenever possible

    The Java Tips series gets another entry, yay! I’ll keep within the plain Java language this time, no frameworks or other fancy tricks, just basic Java know-how.


    Advice

    Use Java5’s for-each loop instead of manually iterating over arrays or collections whenever it is possible.

    Code-Example

    Before

    ...
    // access using index
    for (int i = 0; i < offerList.getMembers().size(); i++) {
        CustomizedOfferOverviewDTO dto = (CustomizedOfferOverviewDTO)offerList.getMembers().get(i);
    ...
    }
    ...
    // access using iterator
    Iterator iter = m_elements.iterator();
    while (iter.hasNext()) {
        ILoadable loadable = (ILoadable)iter.next();
    ...
    }
    ...

    After

    ...
    for(CustomizedOfferOverviewDTO dto : offerList.getMembers()) {
    ...
    }
    ...
    for(ILoadable loadable : m_elements) {
    ...
    }
    ...

    Benefit

    Readability gain. The for-each makes it a lot easier to iterate over collections and arrays and to read and recognize the code. Furthermore the Java compiler might also be able to optimize the loop a bit better internally but in general this improvement is beyond measuring accuracy and therefore is not an argument in this case.

    Remarks

    This only works as long as it’s not modifying the collection or array beneath it. If deleting or replacing elements, you have to use the previous-style looping again where you have direct access to the Iterator.