My comparator class ---------------- private static class ComparatorImpl implements Comparator { // the o1.equals(o2) prevents the "a" "a" problem Ryan pointed out public int compare(Object o1, Object o2) { return o1.equals(o2) ? 0 : -1; } } ---------------- My map thingy --------------- // comparator is a static shared instance of ComparatorImpl above ^ Map map = new TreeMap(comparator) { public String toString() { // ends with 'd' and 'e' per BEncoding way StringBuffer buffer = new StringBuffer("d"); synchronized (buffer) { Iterator iterator = keySet().iterator(); while (iterator.hasNext()) { String key = (String) iterator.next(); Object value = get(key); buffer.append(key.length() + ":" + key); if (value instanceof String) { String string = (String) value; buffer.append(string.length() + ":" + string); } else if (value instanceof Long) { buffer.append("i" + value + "e"); } else if (value instanceof List || value instanceof Map) { buffer.append(value.toString()); } } buffer.append("e"); } return buffer.toString(); } }; -------------------- My test method (well, not really) ------------------- public void testOrderedMap() { Map map = BDecode.decode("de"); map.put("length", "19267903"); map.put("path", "stage1-x86-2006.0.tar.bz2"); java.util.Iterator iterator = map.entrySet().iterator(); while (iterator.hasNext()) { java.util.Map.Entry e = (Map.Entry) iterator.next(); System.out.println(e); } System.out.println(map); } -------------------- output is... path=stage1-x86-2006.0.tar.bz2 length=19267903 d4:path25:stage1-x86-2006.0.tar.bz26:length8:19267903e which is okay, except toString at the bottom should be d6:length8:192679034:path25:stage1-x86-2006.0.tar.bz2e Since 'length' key-value pair was placed BEFORE 'path' was.