Using Apache Commons Collections I found the OrderedMapIterator
interface to navigate back and forth in OrderedMap
. Iterating to the next entry works as expected. Going to the previous element doesn't return the previous element but the current element instead.
OrderedMap<String, String> linkedMap = new LinkedMap<>();
linkedMap.put("key 1", "value 1");
linkedMap.put("key 2", "value 2");
linkedMap.put("key 3", "value 3");
OrderedMapIterator<String, String> iterator = linkedMap.mapIterator();
while (iterator.hasNext()) {
String key = iterator.next();
System.out.println(key);
if (key.endsWith("2") && iterator.hasPrevious()) {
System.out.println("previous: " + iterator.previous());
iterator.next(); // back to current element
}
}
I expected the output
key 1
key 2
previous: key 1
key 3
but got
key 1
key 2
previous: key 2
key 3
Do I use OrderedMapIterator
wrong or is this a bug?
Its because technically .previous()
does not exactly set current entry to previous, but to next.before
. Look how iteration process works:
nextEntry() {
...
last = next; //its current
next = next.after;
...
previousEntry() {
...
final LinkEntry<K, V> previous = next.before;
...
next = previous;
last = previous;
So your flow will affect the last(current)
|next
states as follows:
null|1 -> (next) -> 1|2 -> (next) -> 2|3 <- (previous?) <- 2|2 -> (next) -> 3|null
The reason i may think why is behaves so, because its intended to call .next()
, .previous()
in separate loops.
Imagine a situation where you iterate all way forward, and then need to iterate all way back.
while (it.hasNext()) {
String key = it.next();
list.add(key);
}
while (it.hasPrevious()) {
String key = it.previous();
list.remove(key);
}
With the behaviour which you want to have, you would ended up with [key 3] in list, which is not correct, but currently it works fine.