In fact, both bits of code above have problems.
Shay's code is very clear and straightforward, but he appends words to a String - if you'd replace firstLine by a StringBuffer, performance would be a lot better.
Kim's code tries to optimise away the StringTokenizer at the expense of readability; never a good tradeoff unless you are absolutely sure that it is necessary (sure as in "profiler"). Moreover, in "temp = temp.substring(i);" it tends to create lots of strings - potentially very large strings if "s" may contain a whole document.
What about something like
This hasn't been tested, so don't expect it even to compile - debug and adapt as needed
. Performance should be okay; there's room for improvement but not without affecting code legibility.
- Peter