It is as described in documentation you have quoted - merge can interleave the outputs, while concat will first wait for earlier streams to finish before processing later streams.
In your case, with single-element, static streams, it is not making any real difference (but in theory, merge could output words in random order and still be valid according to spec). If you want to see the difference, try following (you will need to add some sleep afterwards to avoid early exit)
Observable.merge(
Observable.interval(1, TimeUnit.SECONDS).map(id -> "A" + id),
Observable.interval(1, TimeUnit.SECONDS).map(id -> "B" + id))
.subscribe(System.out::println);
A0
B0
A1
B1
B2
A2
B3
A3
B4
A4
versus
Observable.concat(
Observable.interval(1, TimeUnit.SECONDS).map(id -> "A" + id),
Observable.interval(1, TimeUnit.SECONDS).map(id -> "B" + id))
.subscribe(System.out::println);
A0
A1
A2
A3
A4
A5
A6
A7
A8
Concat will never start printing B, because stream A never finishes.
s/stream/observable/g ;)
Documentation gives nice graphs to show the difference. You need to remember that merge gives no guarantee of interleaving items one by one, it is just an one of possible examples.
Concat
Merge
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…