Как получить такой же порядок вывода из коллекции Java - PullRequest
1 голос
/ 06 мая 2020

У меня есть код:

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

, где getVertices является частью пакета JUNG и определяется как:

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]

Это возвращает мне список вершин в случайном порядке каждый раз. Из-за этого мои результаты в другом месте кода не воспроизводятся, и их трудно отследить.

Я хочу вернуть элементы в порядок каждый раз одним и тем же способом. Я предполагаю, что мне придется преобразовать коллекцию в какую-то структуру данных, которая сохраняет порядок, а затем отсортировать ее, чтобы результаты были повторяемыми, но есть ли лучший способ сделать это? (Я не уверен, что преобразование из коллекции в что-то еще, например, массив, нарушит код в другом месте, поскольку я новичок в коллекциях). Любая помощь была бы замечательной!

Ответы [ 5 ]

1 голос
/ 07 мая 2020

Как вы видели, JUNG 2.x не предоставляет эту опцию изначально, поэтому ваш единственный реальный вариант - скопировать вывод и отсортировать его, и это предполагает, что у вас есть Comparator, который имеет смысл для вашего тип вершины. (Это также не позволяет легко сохранить исходный порядок вставки.)

Библиотека графов Guava , также известная как common.graph, используется JUNG 3.0 (в разработке) и поддерживает стабильное упорядочивание на нескольких разных уровнях:

  1. Immutable графики 'аксессоры каждый возвращают Set со стабильным упорядочение.

  2. Если вам нужен изменяемый граф , встроенные реализации, построенные с использованием GraphBuilder (и его родственного брата types) можно указать с помощью nodeOrder(), что узлы графа должны быть любыми из следующих:

    • с порядком вставки (по умолчанию)
    • без порядка
    • естественно упорядочено (если ваш тип узла реализует Comparable)
    • отсортировано

    Для Networks (которые аналогичны типу JUNG Graph) вы можете наложить тот же порядок на ребрах графа.

  3. Вы также можете построить изменяемый граф, который обеспечивает стабильное или деринг гарантий для некоторых аксессоров уровня узла (successors(), predecessors(), и c.) с использованием incidentEdgeOrder() на графике Builder.

(Отказ от ответственности: я был соавтором JUNG и все еще поддерживаю его, а также создал common.graph.)

1 голос
/ 06 мая 2020

Я понял, что Hypergraph.getVertices() - это библиотечный метод, который нельзя изменять. Таким образом, вы должны управлять результатом вызова этого метода. Сортировка - это вариант здесь, как предлагает ответ Ямила .

Но для этого требуется, чтобы либо ваша реализация <V> (MyGraph.MyVertex в вашем примере) реализовывала java.lang.Comparable, либо что вы предоставляете реализацию java.util.Comparator, которая обеспечивает статический c порядок сортировки для ваших вершин.

А java.util.Collections.sort() принимает List в качестве аргумента; экземпляр List также всегда является экземпляром Collection, но, к сожалению, не каждый экземпляр Collection является экземпляром List - это может быть Set или даже что-то совершенно странное ...

Учитывая это и предполагая, что VertComparator является компаратором, о котором я говорил, ваше решение может выглядеть следующим образом:

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

Если весь другой код в вашей программе работает только с Collection экземплярами вершин (это означает, что где-то не делается никаких скрытых предположений, что это за коллекция), вы должны быть в безопасности.

К сожалению, даже если возвращенный Collection уже является экземпляром List (… instanceof List дает true), Collections.sort() может не работать: создайте свой список с помощью List.of() и попытайтесь отсортировать его ...

Довольно часто, когда метод возвращает Collection, который каким-то образом представляет внутренний статус объект, это неизменяемая коллекция. Очевидно, что и здесь сортировка не удастся. Так что единственный безопасный способ - скопировать результат и отсортировать копию.

1 голос
/ 06 мая 2020

Вы можете использовать что-то вроде этого:

List<String> names = Arrays.asList("Alex", "Charles", "Brian", "David");

//Natural order
Collections.sort(names);    //[Alex, Brian, Charles, David]

//Reverse order
Collections.sort(names, Collections.reverseOrder());    [David, Charles, Brian, Alex]   
0 голосов
/ 06 мая 2020

Просто преобразуйте / преобразуйте Collection в List (упорядоченную коллекцию), а затем вы можете применить Collections.sort по мере необходимости.

List list;
if (vertCollection instanceof List) {
    list = (List)vertCollection;
} else {
    list = new ArrayList(vertCollection);
}
0 голосов
/ 06 мая 2020

Просто используйте ArrayList для реализации Коллекции. ArrayList ведет себя как массив. Они выходят в том же порядке, в котором были вставлены.

Collection<E> list = new ArrayList<>();
Collection<V> list = new ArrayList<>();
...