Computing huge Fibonacci numbers in Java
StringBuilder sb;

    if (fromAtoB) {
        // It looks like the result is in the listB. However, as the boolean
        // fromAtoB was flipped after the last add(list1, list2), the result
        // is actually in list A.
        sb = new StringBuilder(listA.size());

        // For efficiency, we grow the digit string such that the least 
        // significant digits are in the lowest array positions. That way
        // we make sure that adding a new (most significant digit) always
        // runs in amortized constant time.
        for (int i = listA.size() - 1; i &gt;= 0; --i) {
            sb.append(listA.get(i));
        }
    } else {
        // Result is in listB.
        sb = new StringBuilder(listB.size());

        for (int i = listB.size() - 1; i &gt;= 0; --i) {
            sb.append(listB.get(i));
        }
    }

    return sb.toString();


Lots of fancy comments. Let's take em out so I can look at the actual code.

    StringBuilder sb;

    if (fromAtoB) {
        sb = new StringBuilder(listA.size());

        for (int i = listA.size() - 1; i &gt;= 0; --i) {
            sb.append(listA.get(i));
        }
    } else {
        sb = new StringBuilder(listB.size());

        for (int i = listB.size() - 1; i &gt;= 0; --i) {
            sb.append(listB.get(i));
        }
    }

    return sb.toString();


Seems all you do here is getting a string... from either listA or listB. I'd recommend putting this in a separate function...

public static String convertDigitListToString(List&lt;Character&gt; list){
    StringBuilder sb = new StringBuilder(list.size());

    for (int i = list.size() - 1; i &gt;= 0; --i) {
        sb.append(list.get(i));
    }
    return sb.toString();
}


And then you can simplify your code a bit.

if (fromAtoB) {
    return convertDigitListToString(listA);
} else {
    return convertDigitListToString(listB);
}


Maybe even a ternary? I dunno about that, though. It's shorter, but a bit more harder to read.

return convertDigitListToString(fromAtoB ? listA : listB);


The real reason it's hard to read is because fromAtoB is a pretty bad description... in this case, you're looking for something like lastListUsed... but that doesn't really fit the description either.



    if (n &lt; 0) {
        throw new IllegalArgumentException("n = " + n);
    }


You might want to give a more descriptive message, like "n must be positive", or "expected positive n, got ".