Skip to main content

add a method entryList() to java.util.LinkedHashMap

No replies
forax
Offline
Joined: 2004-10-07
Points: 0

There is no way to iterate on entries of a linked hashmap
in backward order. (see bug 6182958)

Is there a sun guy that could copy/paste the following
code into LinkedHashMap.
(may be, the code should be verified first :)

Rémi Forax

private class EntryListIterator implements ListIterator> {
Entry nextEntry ;
Entry lastReturned = null;
int nextIndex;

/**
* The modCount value that the iterator believes that the backing
* List should have. If this expectation is violated, the iterator
* has detected concurrent modification.
*/
int expectedModCount = modCount;

EntryListIterator(int index) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);

Entry next;
if (index < (size >> 1)) {
next = header.after;
for (int i=0; iindex; i--)
next = next.before;
}
this.nextEntry=next;
this.nextIndex=index;
}

public boolean hasNext() {
return nextIndex != size;
}

public Entry next() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();

if (nextIndex == size)
throw new NoSuchElementException();

Entry e = lastReturned = nextEntry;
nextEntry = e.after;
nextIndex++;
return e;
}

public boolean hasPrevious() {
return nextIndex != 0;
}

public Entry previous() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
if (nextIndex == 0)
throw new NoSuchElementException();

Entry e = lastReturned = nextEntry = nextEntry.before;
nextIndex--;
return e;
}

public int nextIndex() {
return nextIndex;
}

public int previousIndex() {
return nextIndex-1;
}

public void remove() {
if (lastReturned == null)
throw new IllegalStateException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();

LinkedHashMap.this.removeEntryForKey(lastReturned.key);
lastReturned = null;
expectedModCount = modCount;
}

public void set(Map.Entry entry) {
throw new UnsupportedOperationException();
}

public void add(Map.Entry entry) {
throw new UnsupportedOperationException();
}
}

/**
* Returns a list view of the mappings contained in this map. Each
* element in the returned list is a Map.Entry. The
* list is backed by the map, so changes to the map are reflected in
* the list, and vice-versa. The list supports element
* removal, which removes the corresponding mapping from the map, via the
* Iterator.remove, List.remove,
* removeAll, retainAll, and clear operations.
* It does not support the set, add or addAll
* operations.
*
* @return a collection view of the mappings contained in this map.
* @see Map.Entry
*/
public List> entryList() {
List> el = entryList;
return (el != null ? el : (entryList = new EntryList()));
}

private transient List> entryList = null;

private class EntryList extends AbstractSequentialList> {
public void clear() {
LinkedHashMap.this.clear();
}
public boolean contains(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry e = (Map.Entry) o;
HashMap.Entry candidate = getEntry(e.getKey());
return candidate != null && candidate.equals(e);
}
public boolean remove(Object o) {
return removeMapping(o) != null;
}
public ListIterator> listIterator(int index) {
return new EntryListIterator(index);
}
public Iterator> iterator() {
return newEntryIterator();
}
public int size() {
return size;
}
}