Results tagged “Java”

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.

|

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 few days ago I hit a problem while refactoring some legacy Java Code. Following my own advice to use safe and simpler library methods I changed the code-block

List<String> list = dao.getEntries(id);
if(list != null && list.size() > 1) {
  doFancyLogic(list);
}

to

List<String> 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 http://commons.apache.org/collections/apidocs/org/apache/commons/collections/CollectionUtils.html 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 https://commons.apache.org/proper/commons-collections//apidocs/org/apache/commons/collections/CollectionUtils.html, 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 https://commons.apache.org/proper/commons-collections/javadocs/api-release/org/apache/commons/collections/CollectionUtils.html. 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.

|

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.

|

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.

|

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 ;)

| | Comments (1)

After quite some time this is another instance of the Java Tips. It's an addition to the Apache Commons related framework tips 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 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<String> getCategoriesAllowedToViewBySearchFilter() {
    Set<String> result = null;
    if ((this.filter != null && this.filter.getCategory() != null) && (!this.filter.getCategory().isEmpty())) {
        result = new HashSet<String>();
        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<String> getCategoriesAllowedToViewBySearchFilter() {
    Set<String> 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<String>(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.

|

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.

|

On to the next Java Tip. 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.
<Map>.entrySet() vs. <Map>.keySet() vs. <Map>.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<String, Object> 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.

|

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.

|

Tip #5 in my Java Tips series is again focussing around the Apache Commons framework. In the same manner the StringUtils simplifies many common operations on Strings (see also Java Tip #3), DateUtils ease some of the pain when working with Java Date objects.


Advice

Use Commons DateUtils to manipulate and calculate dates.

Code-Example

Before

...
private static Date add(Date date, int field, int amount) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    cal.add(field, amount);
    return cal.getTime();
}
...
public static Date getNextDay() {
    return add(getCurrentDay(), Calendar.DATE, 1);
}
...

After

...
public static Date getNextDay() {
    return DateUtils.addDays(getCurrentDay(), 1);
}
...

Benefit

Huge readability gain. By using DateUtils for calculating and manipulating Dates the code footprint gets smaller and easier to read. Furthermore by using explicit methods like addDays() it is clearer which part of a date is to be modified, compared to the partly ambiguous constants in the Calendar class. DateUtils also contains methods to round or truncate Dates to certain parts of the date, eg. truncate() by Calendar.HOUR sets minutes, seconds and miliseconds to zero.

Remarks

None.

|

Tip #4 of the Java Tips series is just a quick tip to enhance the codes robustness.


Advice

When comparing constants, always compare the constant to the unknown value.

Code-Example

Before

if(str != null && str.equals("XYZ")) { ... }
if(value != null && value.equals(SomeEnum.ENUM_1)) { ... }

After

if("XYZ".equals(str)) { ... }
if(SomeEnum.ENUM_1.equals(value)) { ... }

Benefit

Safety gain. Minor readability gain. The constant value can be compared to a null value without resulting in a NullPointerException. The check for null can be skipped because when the constant is compared to null the condition simply evaluates to a boolean false.

Remarks

None.

|

The next tip in my series of Java Tips deals with the usage of Java frameworks. Some people still have a certain hatred against Java frameworks because many of them have been not easy to deal with in in their past. Nevertheless, while those have either disappeared or evolved in a more usable shape, there have always been some frameworks which were rock-solid and widely accepted as simple and extremely useful. One of those is the Lang package in the library collection of the Apache Commons. In my opinion this one is a must-have for almost every Java project or application. Use it. Period.


Advice

Use Commons StringUtils for checking Strings content for null, emptiness or blankness.

Code-Example

Before

if(str != null && !str.equals("")) { ... }
if(str != null && !str.trim().equals("")) { ... }
if("".equals(str)) { ... }
if(str == null || "".equals(str.trim())) { ... }

After

if(StringUtils.isNotEmpty(str)) { ... }
if(StringUtils.isNotBlank(str)) { ... }
if(StringUtils.isEmpty(str)) { ... }
if(StringUtils.isBlank(str)) { ... }

Benefit

Huge readability gain. Safety gain, as StringUtils methods are null-safe. By using the provided utility methods from StringUtils the intent of a condition is much easier and faster to recognize. Furthermore, since all methods of StringUtils are able to correctly process null Strings, there is no danger of an unexpected NullPointerException anymore because of a forgotten null-check.

Remarks

None.

|

And on to the next in a series of Java Tips. While last time the performance gain was very tiny and only affected high-load scenarios, this tip may considerably speed up even simple applications where there is String-processing involved.


Advice

Use StringBuilder instead of + or += to concatenate Strings in non-linear cases (when concatenation not appears immediately one after another), ie. in loops.

Code-Example

Before

  String test = "";
  for(int i = 0; i < 50000; i++) {
     test += "abc";
  }

After

  StringBuilder test = new StringBuilder();
  for(int i = 0; i < 50000; i++) {
     test.append("abc");
  }

Benefit

Huge performance gain! The unoptimized code forces Java to create new Strings and copy the contents around all the time (because Strings are immutable in Java). The optimized code avoids this creation/copying by using StringBuilder. While the Java compiler can optimize linear concatenations, ie.

String test = "a" + "b" + "c";

into using a StringBuilder internally, it is not clever enough to apply this optimization correctly if there is more logic than just concatenation involved. Even if the concatenation is the only operation inside some loop-logic, the Java compiler falls back into creating a whole lot of String (or to be more exact: StringBuilder) objects, copying them around like crazy and causing a huge performance impact in some cases. I confirmed this example for measurement of StringBuilder performance: concatenating 50000 times "abc" in a loop takes ~11000ms, using StringBuilder keeps the time spent at near 0ms. (I tried concatenating with 500000 iterations, but stopped the execution of the first loop after ~10 minutes running unfinished, so the impact is nonlinear. Second loop finished in 15ms with 500000, for the record.)

Remarks

It is not necessary to optimize code like

String email = user + "@" + domain + ".com";

as javac is clever enough for these cases and it would reduce readability considerably. But even with the simplest loops involved the conditions change. For example, internally the first loop gets compiled by javac into following bytecode

 13  new java.lang.StringBuilder [24]
 16  dup
 17  aload_1 [test]
 18  invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [26]
 21  invokespecial java.lang.StringBuilder(java.lang.String) [32]
 24  ldc <String "abc"> [35]
 26  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [37]
 29  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [41]
 32  astore_1 [test]
 33  iinc 4 1 [i]
 36  iload 4 [i]
 38  ldc <Integer 50000> [45]
 40  if_icmplt 13

where for each iteration of the loop(13-40) a new StringBuilder is instantiated and initialized with the result of the previous' loop StringBuilders value before appending the constant String just once each time. The optimized code results in this bytecode

 81  new java.lang.StringBuilder [24]
 84  dup
 85  invokespecial java.lang.StringBuilder() [62]
 88  astore 4 [builder]
 90  iconst_0
 91  istore 5 [i]
 93  goto 107
 96  aload 4 [builder]
 98  ldc <String "abc"> [35]
100  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [37]
103  pop
104  iinc 5 1 [i]
107  iload 5 [i]
109  ldc <Integer 50000> [45]
111  if_icmplt 96

in which the loop(96-111) just appends the constant String to the same StringBuilder each time which was created only once before the loop started. No copying around and creation of additional objects necessary, thus a huge performance-gain.

| | Comments (2)

This is my long promised posting about my experiences with Eclipse Mylyn. It took quite some time because I did not stick to it all the time but somehow fell back to my old development-habbits where everything and much more was visible on the screen. Maybe this is caused by the always-changing project situation or changing technologies but I cannot completely blame it to that. Nevertheless, let's focus on my experiences :)

Mylyn works by hiding everything from your visual workspace which is not connected to your current task at hand. This means, you only see the files in the Package Explorer and all other many views which were touched during your current task. This also means that you have to create tasks for your work in the Task List, which is a good idea anyway. The Mylyn-filtering is activated in the moment when you click on the small circle next to such a task in the Task List. If you have worked before on that task, your previous state of the workplace (which is called Context here) gets restored, like the open files, the touched methods and landmarks. If this is a fresh task, you're presented with empty views all around. From here you then can open your initial file to work on either by using the "Open Resource" shortcut or by ALT-clicking into the Package explorer, where the hidden files are displayed then.

From that initial file on you just navigate through the structures and methods with your usual Eclipse navigation (F3, STRG-click, or whatever) and Mylyn takes care to just display and highlight the necessary information for your work. It even cleans up the stuff and removes old and never-again places if you didn't came back to them for a longer time. The same thing applies to all content-assists like the method-overview or all of the Find-shortcuts where the list gets two-parted with your context-relevant results at the top and only the remaining hits after a separator.

You can also mark certain methods or files as "Landmarks" which are then displayed in bold text in your Outline or Package Explorer. This is especially handy if you're hunting a bug and found important places you want to remember or where you nailed down the cause but will fix it at a later time.

I also tried to connect my Mylyn Task List with a local installation of Bugzilla to better manage my tasks and make them available even outside of my own workspace. This worked quite good. It's also possible to attach the Context to each task if you're working with an external task repository. This would allow other people on the same repository to open the Context in the same state as it was when you last saved it to the task repo. Easy moving tasks from one person to another :) But we didn't come around to test this, as I've been the only one to work with Mylyn longer than just for a short tryout.

All in all I can say that if you get used to the way how Mylyn hides everything unnecessary from your display and how it presents the important information, the speed of development really goes up and the amount of distraction minimizes. But to get to that point you have to really work through the initial get-used phase which can be somewhat confusing and make you switch back to the previous development-mode where everything is displayed. I also fell into this a few times. But if you stick to it, you'll soon get the benefit of being able to focus!

If you also want to try it out or are just curious how it feels to work with it, take a few minutes and watch the Eclipse Mylyn 3.0 webcast video and read through the Mylyn 2.0 Tutorial (still applies 100% even if it's been written for 2.0) how to get started, you won't regret it!

|

As promised last time I'm presenting here the first in a series of Java Tips. To start easy I'll begin with one of the simplest tip to implement.


Advice

Use StringBuilder instead of StringBuffer.

Code-Example

Before

  StringBuffer str = new StringBuffer();
  str.append("foo");
  String x = str.toString();

After

  StringBuilder str = new StringBuilder();
  str.append("foo");
  String x = str.toString();

Benefit

Small performance gain. StringBuilder is a 1:1 drop-in replacement for the StringBuffer class. The difference is that the StringBuilder is not thread synchronized and therefore performs better on most implementations of Java. Even javac internally translates String x = "foo" + "bar"; into a StringBuilder operation (confirmed with Java 1.6.0_18). A small testcase

public static void main(String[] args) {
    long start = System.currentTimeMillis();
    StringBuffer buffer = new StringBuffer();
    for(int i = 0; i < 1000000; i++) {
        buffer.append("abc");
    }
    System.out.println("Time lapse using StringBuffer: " + (System.currentTimeMillis() - start) + " milliseconds");

    start = System.currentTimeMillis();
    StringBuilder builder = new StringBuilder();
    for(int i = 0; i < 1000000; i++) {
        builder.append("abc");
    }
    System.out.println("Time lapse using StringBuilder: " + (System.currentTimeMillis() - start) + " milliseconds");
}

using Java 1.6.0_18 shows that StringBuilder is roughly 100% faster than StringBuffer. Although on my machine this testcase keeps below 100ms for both with one million appends so this won't be the magical solution for most of your performance issues.

Remarks

Even if this tip can be applied in 98% of all cases one has to be sure that the String is used afterwards and the StringBuilder instance does not get passed between several threads. Since StringBuilder is not thread-safe this would be the only case where StringBuffer should be used. And of course it's not the silver performance bullet but just one slice in string-heavy applications.

|

Over the last ten (or so) days, just right for Easter, my health status went down again. I cought a small cold, not enough to keep me from working but bad enough so that I spent my non-work time in bed to recover faster. This helped somewhat in the way that it did not get worse anymore and today I'm not really feeling much of that issue anymore.

But this recovering was paid expensive. My spine aces returned, most probably caused by the lying-in-bed and limited exercising because of my injured ankle. Currently it's bad, not as bad as back in 2006, but still enough so that it causes me a constant pain in the lumbar spine. For now I just can fight this with pain killers but I know I need to get back to exercising as fast as possible to strengthen my muscles in this area again and get stabilized. Of course, I have to pay attention to the possible remainings of the cold and that I do nothing which could harm my wounded ankle.

Totally unrelated to this, some time ago I began collecting the different improvements I make to our sourcecode at work. I did this because I recognized, that I often applied the same improvements over and over again to other people's sourcecode and a lot of them are quite similar to each other. Most of this improvable code exists, because people just don't know that similar functionality already exists in common frameworks and so algorithms and operations get reingeneered again and again.

I plan to develop this collection so that each improvement has a before-after-example, a detailled explaination why this improvement is better, maybe a categorization into different areas (eg. Collections, Framework, Java5-Enhancement, etc.) and a difficulty-level. Maybe if this turns out well, I could also organize an internal training-event to spread this knowledge and raise the quality of our code just a tiny bit :)

Nevertheless, I'm also thinking of publishing each tip here in the blog for free availability and open discussion, so stay tuned if you're a Java developer, maybe there's also something in for you.

|

Yes, there has been silence for some time. Cause of that are the upcoming exams this weekend in lectures which awesomeness-level lies below that of a rotting potato.

Nevertheless, there has been some progress. I finally decided a name and hoster for my project which I've been pondering now for almost two semesters at University. And with some traces of proudness I finally present you the

Contours Framework

To admit, the hardest part was really to find a proper name for it, which should hint a bit into the direction of the topic without colliding with other projects. Another earlier try was "Shapes" but there are already several projects around with that term in their name and which are probably more popular on search terms than my project will ever be.

In more details, the project is about creating a framework which allows Java application developers to create a file-reader for arbitrary binary files which then allows easy access to the content data from the file. This is done by providing a custom file-description language in which the structure of the file can be laid out. Then this format description is taken by the Contours framework which produces all necessary Java code for a file reader for files of this structure. This reader can then be easily be integrated into the own Java application.

I know, it's not a very common problem this addresses and there are other preferable ways for most similar problems. But I needed something which makes it easy to follow changes in file formats without the need to regenerate and review large parts of existing Java code. Furthermore when I'm dealing with more than one or two different formats, the maintenance of several different readers written by different people gets unhandy quite fast. And finally one of the goals was to produce code which allows high processing speed. When I started my project, there was no framework around addressing all of these points (and there still is none). Nowadays there are some available (one of them being Preon) but none of them seems to fit the performance requirement. And I've gotten already quite far when I discovered those, so I chose to continue with it and if it's just for learning purposes.

Nevertheless, the page is up, some content already present (notably the architecture description of Contours) and all source committed to the Contours SVN source repository. Feel free to have a look at it and if you have any comments, comment here or raise an Issue (when I come around to enable and configure that part of the project properly).

|

Sun makes it not easy to get your hands on previous versions of their software, especially if it is somehow connected to the Java technology. Their frontpages only contain the links to the latest software and (if you're lucky) tiny hints how to get to the previous version of eg. the JRE. But if you're looking for example for the outdated JRE 1.2, y

Thanks goes to a friend who gave me the link to the Java Technology Downloads Archive where a lot of previous editions for the different Java software components are available through a single page for download.

This includes all versions of JRE, JDK, J2EE, several additional Java technologies and even the Java SE Tutorials.

The only thing I'm currently missing are deprecated versions of the J2ME technologies, but I don't know if there are older versions even existing of J2ME.

The full list of downloadable items currently: Java Certification Program, J2EE IDE Toolkit, JavaBeans Activation Framework, JDBC, Java 2 Platform Enterprise Edition (J2EE), Java Platform Standard Edition (Java SE), Java Development Kit (JDK), Java Cryptography Extension, Java Authentication and Authorization Service, Java Secure Socket Extension, Java Foundation Classes (JFC), Swing, Java HotSpot Server VM, Java Internationalization and Localization Toolkit, Java Message Service, Java Plugin (+ Converter), Java Servlet, RMI over IIOP and the Java SE Tutorials.

|

Last time I've been posting about how you can increase your java development speed by knowing and using common and handy keyboard shortcuts. This time I'll be showing you some plugins which I have used over the time. For most of them I can say that they not so much speed up development but instead raise the quality of your sourcecode by giving you hints or adding certain aspects to testing.

So let's dive in.

Subclipse and Subversive are with high probability the most-installed plugins for distributed development and source code versioning. As Eclipse still does not provide builtin functionality for this (because of some licensing issue), these plugins add the required connectors so that it becomes possible to synchronize your source with a SVN server. Both plugins provide everything needed for most of the SVN tasks and differ just in edge cases or the handling and UI details. I'm personally using Subversive for years now because it has a Checkout-Wizard with more functionality than Subclipse offers but that plugin also has evolved since I checked it the last time. I should give it a try again in the near future.

The JD-Eclipse plugin is a decomplier addon for Eclipse which helps you out if you happen to stumble into Java bytecode eg. during debugging or when you follow references into external libraries. It reconstructs the Java source from the compiled code, so what you get is not the real sourcecode but something which resembles exactly the same function. Nevertheless it's often interesting how the code behind the APIs works you're using. Or, if you're depending on other projects which are currently just closed in your workspace.

Findbugs is a static source-code-analysis tool which checks your sourcecode for common mistakes optimization potential. It covers a very wide range of different bug types and each found bug or issue in your sourcecode has a small description added. Of course, since it's a statical analysis this tool is unable to analyze the whole logic in your sourcecode and therefore may also generate false positives, so be sure to not blindly follow each suggestion. But it's usefulness in general is undeniable.

Also a static analysis is done by Checkstyle but this one focusses less on programming errors but more on the layout of the code and the correctness of the documentation. For example if your javadoc for a method is missing a new parameter which you just added, Checkstyle would highlight this mismatch for you. It has an extensive ruleset so don't be surprised if it makes annotations all over your code if you check it for the first time.

EclEmma and Coverlipse are two plugins which deal with identifying the runtime coverage of your code. They add measuring instruments which allow you to determine which parts of your code are reached by eg. unittests and which parts of your code are still untested and need additional attention. EclEmma is the simpler one of the two but also is faster to get started with. Coverlipse on the other side needs a bit more work to get started but allows deeper inspection and offers a wider range of statistics and visualizations of the covered and uncovered code.

Another tool to aid with testing is Infinitest. It analyzes your JUnit tests and runs them silently in the background after each change in your sourcecode. It adds some intelligence so that only those tests are run which could be influenced by your changes. Furthermore errors in the tests are directly displayed as source-errors in your sourcecode. Of couse, this is only useful if your testcases can be executed fast and do not need an extended time to execute. The plugin has moved from the free Google-Code project to a commercial website but as far as I can see, the plugin itself is for now still available without cost.

If you want to quickly set up a shared task repository for your small team without having to set up a full blown Bugzilla, maybe even with a touch of Scrum, Scrum Vision may be the tool for you. It connects the task management of Eclipse (Mylyn) with a Google spreadsheet which also can be shared with other instances of Eclipse for other developers. The IDE aligns with the Scrum methodology to support agile development. This alignment also propagates in the spreadsheet where you can display reports and have a virtual taskboard and also a Burndown Graph.

If you'd like to close editor tabs the same way as you do in Firefox, by middle-clicking the tab, the Middle Click Closes Tab plugin (although last updated for Eclipse 3.3, it still works with Galileo) enhances your Eclipse with this feature.

As for Mylyn, which is already completely integrated in Eclpse: Since my last post according Mylyn I collected some additional experience with Mylyn. I also connected it to a local instance of Bugzilla to play a bit around with its integration and how it deals with sharing files and context. But I also think that I should use it more again, as I've become a bit lazy with it and fallen back to the previous everything-on-the-screen overloaded development. The promised blog post which hasn't been posted until now is still on my list for the future, when I know even more about Mylyn. But I already can suggest Mylyn as a tool to leverage the development effectivity by helping the developer to focus on the actual task at hand. If you're curious, have a look at the excellent Mylyn 3.0 webcast to get started.

That's it for now. I hope, there is also something useful in this post which is helpful for your Java development with Eclipse.

|

2  

Archives