1

I had this crazy initialisation --

documentList = new ArrayList<Map<String,Integer>>();

which I intended to store a new map everytime in a loop but unfortunately put itself inside the loop. And you know the havoc.

How do you detect such mistakes? I might be looking for suggestions on 'recommended debugging techniques' but am also looking for more expert advice

closed as primarily opinion-based by gnat, user53019, user40980, Jimmy Hoffa, Kilian Foth Nov 21 '13 at 14:14

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 4
    In a question about looping, it would help to see the loop in addition to the data structure. In all likelihood, you are coding some primitive function like map, filter, or reduce or some combination of them as a loop. Java 8 will have these primitive functions. Scala and Clojure have them already. – GlenPeterson Nov 19 '13 at 13:11
8

These mistakes are detectable by the system and simple to avoid: embrace immutability.

At least declare your documentList as final. This immediately causes the compiler to inform you about this particular error. Unfortunately, Java does not have all the good things from functional programming, like real immutable lists and higher-order functions (yet), but at least final means you cannot replace your initial list with a completely new one. You can still make mistakes like calling documentList.clear(), but those are much less likely to happen by chance.

Hence, as usual, I try not to even go down the road of having to detect such mistakes, but I try to write code in a style that immediately ensures such a mistake cannot happen at all. For good reasons, mutability is spelled as t-r-o-u-b-l-e, so never walk that road unless you have to. The more parts of your code that can be declared final, the better.

2

The best way to catch such bugs is to prevent them from rearing their head during runtime. You can achieve that in several ways (which are not mutually exclusive):

  1. Write your code in a style that allows a compiler to pick up on the errors. Some examples are to make liberal use of immutability (const/final, as also described in the answer by @Frank), or to write equality test like this: 42 == x in a context where assignment would also be legal.

  2. Have a second pair of eyes look over your code (as in, perform a code review).

-3

In general you should write unit tests for preventing mistakes. With test driven development you build your components in small increments and constantly strengthen your test harness. As a result you have a more-or-less bug-free component which you don't need to debug afterwards.

  • Why the down-vote? If you consider unit testing and TDD as a bad idea then please elaborate. – Muton Nov 19 '13 at 10:28
  • Errors in loops are often subtle, particularly in code which uses mutability and side-effects. While it is usually easy to write unit tests which test boundaries and simpler edge cases, it can be hard for them to find errors which may only manifest in repeated iterations over a dataset. For that you would need something more like QuickCheck. Even then, while it will detect an error in the output, it can't point you at the cause. – itsbruce Nov 19 '13 at 10:29
  • 1
    Muton, you acknowledge you didn't really understand the question and your answer is not very useful to the specific case given, nor even as useful as you think in the general case. – itsbruce Nov 19 '13 at 10:30
  • 1
    The problem is that the OP put the variable initialization inside a loop causing the list to be cleared on each iteration. What he wanted was to initialize it outside the loop and then populate it in the loop. A simple test with more than one element in the data-set would reveal this bug. – Muton Nov 19 '13 at 10:55
  • 4
    Again, you assume a direct correspondence between this block of code and the output of a library or api call. Your advice is generic and applies equally to any coding error. It says nothing about how to avoid this particular error nor does it even give good advice about how to detect it (as I said, a test platform like QuickCheck is much more likely to detect this class of errors than unit testing). – itsbruce Nov 19 '13 at 11:50

Not the answer you're looking for? Browse other questions tagged or ask your own question.