10

I want to print an ordered list in Map using the following:

Map<Float, String> mylist = new HashMap<>();

mylist.put(10.5, a);
mylist.put(12.3, b);
mylist.put(5.1, c);

SortedSet<Float> orderlist = new TreeSet<Float>(mylist.keySet());

for (Float i : orderlist) {
    System.out.println(i+" "+mylist.get(i));
}

The above code prints:

5.1 c
10.5 a
12.3 b    

But how do I the print the orderlist in reverse order like below:

12.3 b
10.5 a
5.1 c
Ram Patra
  • 16,266
  • 13
  • 66
  • 81
user2109581
  • 187
  • 2
  • 2
  • 11
  • Are you against placing the items from the set in another data structure? Additionally, are you required to have the items in the `SortedSet` in the specific order they're already in, or would you be okay with storing them in reverse order? – augray Feb 01 '16 at 03:18
  • I just want to print the list. There is no requirement to SortedSet if there is a better way. It is ok if I can store items in reverse order. – user2109581 Feb 01 '16 at 03:21

6 Answers6

12

If you're willing to store the elements in the SortedSet in reverse order, the only change you need to make is to construct the TreeSet with an appropriate constructor which takes a custom Comparator:

Map<Float, String> mylist = new HashMap<>();

mylist.put(10.5, a);
mylist.put(12.3, b);
mylist.put(5.1, c);

SortedSet<Float> orderlist = new TreeSet<Float>(Collections.reverseOrder());
orderList.addAll(mylist.keySet());

for (Float i : orderlist) {
    System.out.println(i+" "+mylist.get(i));
}

Note the neat method here is Collections.reverseOrder() which returns a Comparator which compares in the opposite of the natural ordering of elements.

augray
  • 3,043
  • 1
  • 17
  • 30
  • Thanks, that is awesome! – user2109581 Feb 01 '16 at 03:42
  • 5
    No problem! [SO etiquette for a thank-you is an upvote and a "mark as answer"](http://meta.stackexchange.com/questions/126180/is-it-acceptable-to-write-a-thank-you-in-a-comment) ;-) – augray Feb 01 '16 at 03:44
6

You can also try this :

    Map<Float, String> mylist = new HashMap<Float, String>();
    mylist.put(10.5, a);
    mylist.put(12.3, b);
    mylist.put(5.1, c);

    SortedSet<Float> orderlist = new TreeSet<Float>(mylist.keySet()).descendingSet();

    for (Float i : orderlist) {
        System.out.println(i+" "+mylist.get(i));
    }
Niks
  • 175
  • 7
2

Try to use NavigableSet:

 public NavigableSet<E> descendingSet()

Like this:

  SortedSet<Float> orderlist = new TreeSet<Float>(mylist.keySet());
  SortedSet<Float> treereverse = new TreeSet<Float>();
  // creating reverse set
  treereverse=(TreeSet)orderlist.descendingSet();

Finally you have treereverse with the reverse order.

Abdelhak
  • 8,299
  • 4
  • 22
  • 36
0

You can try this implementation (source):

public sealed class OrderedSet<T> : ICollection<T>
{
    private readonly IDictionary<T, LinkedListNode<T>> _dictionary;
    private readonly LinkedList<T> _linkedList;

    public OrderedSet()
        : this(EqualityComparer<T>.Default)
    {
    }

    private OrderedSet(IEqualityComparer<T> comparer)
    {
        _dictionary = new Dictionary<T, LinkedListNode<T>>(comparer);
        _linkedList = new LinkedList<T>();
    }

    public int Count => _dictionary.Count;

    public bool IsReadOnly => _dictionary.IsReadOnly;

    void ICollection<T>.Add(T item)
    {
        Add(item);
    }

    public void Clear()
    {
        _linkedList.Clear();
        _dictionary.Clear();
    }

    public bool Remove(T item)
    {
        var found = _dictionary.TryGetValue(item, out var node);
        if (!found)
        {
            return false;
        }

        _dictionary.Remove(item);
        _linkedList.Remove(node);
        return true;
    }

    public IEnumerator<T> GetEnumerator()
    {
        return _linkedList.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public bool Contains(T item)
    {
        return _dictionary.ContainsKey(item);
    }

    public void CopyTo(T[] array, int arrayIndex)
    {
        _linkedList.CopyTo(array, arrayIndex);
    }

    public void Add(T item)
    {
        if (_dictionary.ContainsKey(item))
        {
            return;
        }

        var node = _linkedList.AddLast(item);
        _dictionary.Add(item, node);
    }

    public void Reverse()
    {
        var head = _linkedList.First;
        while (head.Next != null)
        {
            var next = head.Next;
            _linkedList.Remove(next);
            _linkedList.AddFirst(next.Value);
        }
    }
}

Please note that this is an OrderSet which preserves the insertion order unlike SortedSet which keeps the set sorted according to some comparator (e.g. alphabetically).

I added the Reverse() method from here.

BullyWiiPlaza
  • 17,329
  • 10
  • 113
  • 185
0

Starting with the upcoming Java 21, the reversed() method can be used to return a reversed view on the set, which can then be iterated over using an enhanced for statement:

for (Float i : orderlist) {
    System.out.println(i+" "+mylist.get(i));
}
M. Justin
  • 14,487
  • 7
  • 91
  • 130
0

Rather than creating a SortedSet for just the keys and looking up the value for each key, you can use a SortedMap and iterate over the map's entries. The map can be sorted in reversed order using the Comparator.reversed() comparator.

Map<Float, String> mylist = new HashMap<>();

mylist.put(10.5, a);
mylist.put(12.3, b);
mylist.put(5.1, c);

SortedMap<Float, String> orderlist = new TreeMap<Float>(Comparator.reversed());
orderlist.putAll(mylist);

for (Map.Entry<Float, String> e : orderlist.entrySet()) {
    System.out.println(e.getKey() + " " + e.getValue());
}

If you aren't using mylist as a HashMap separately from this iteration, the SortedMap can be used directly.

SortedMap<Float, String> mylist = new TreeMap<>(Comparator.reversed());

mylist.put(10.5, a);
mylist.put(12.3, b);
mylist.put(5.1, c);

for (Map.Entry<Float, String> e : mylist.entrySet()) {
    System.out.println(e.getKey() + " " + e.getValue());
}
M. Justin
  • 14,487
  • 7
  • 91
  • 130