Search code examples
javadata-structuresgraphcollectionsjung

How to get the same output order from a Java Collection


I have some code:

Collection<MyGraph.MyVertex> vertCollection = graph.getVertices(); 

where getVertices is part of the JUNG package and is defined like:

public interface Hypergraph<V, E> {
    Collection<E> getEdges();

    Collection<V> getVertices();
...
...
}

> If I print out the collection I may get something like [v1,v2,v4,v3]
> and on another run something like [v2,v3,v1,v4]

That gives me back a list of vertices in random order each time. Because of this my results elsewhere in the code are not repeatable and it gets hard to trace.

I want to get the elements back in order each time the same way. My current guess is I'd have to convert the collection to some sort of data structure that preserves order then sort it so that the results are repeatable but is there a better way to do this? (I'm not sure if converting from a Collection to something else like an array would break the code elsewhere as I'm new to Collections). Any help would be great!


Solution

  • I understood that Hypergraph.getVertices() is a library method that you cannot modify. So you have to manipulate the result from a call to that method. Sorting is the option here, as suggested by Yamil's answer.

    But this requires that either your implementation of <V> (MyGraph.MyVertex in your sample) will implement java.lang.Comparable, or that you provide an implementation of java.util.Comparator that ensures a static sort order for your vertices.

    And java.util.Collections.sort() takes a List as argument; an instance of List is always an instance of Collection, too, but unfortunately not every instance of Collection is an instance of List – it could be a Set or even something absolute strange …

    Considering this, and assuming that VertComparator is the comparator I talked about, your solution might look like this:

    …
    VertComparator comparator = new VertComparator();
    List<MyGraph.MyVertex> vertCollection = new ArrayList<>( graph.getVertices() );
    Collections.sort( vertCollection, comparator );
    …
    

    If all other code in your program does only deal with Collection instances of vertices (that means that no hidden assumptions are made somewhere what kind of collection it is), you should be safe.

    Unfortunately, even if the returned Collection is already an instance of List (… instanceof List yields true), Collections.sort() may not work: create your list with List.of() and try to sort it …

    Quite often, when a method returns a Collection that somehow represents the internal status of the object, this is an unmodifiable collection. Obviously sorting will fail here, too. So the only safe way is to copy the result and sort the copy.