如何从 Java 集合中获取相同的输出顺序
How to get the same output order from a Java Collection
我有一些代码:
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]
这每次都会返回一个随机顺序的顶点列表。因此,我在代码其他地方的结果不可重复,而且很难追踪。
我想每次都以相同的方式恢复元素的顺序。我目前的猜测是我必须将集合转换为某种保留顺序的数据结构,然后对其进行排序,以便结果是可重复的,但是有没有更好的方法来做到这一点? (我不确定从 Collection 转换为数组等其他东西是否会破坏其他地方的代码,因为我是 Collections 的新手)。任何帮助都会很棒!
你可以使用这样的东西:
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]
只需使用ArrayList 来实现Collection。 ArrayList 的行为就像一个数组。它们以相同的顺序出现。
Collection<E> list = new ArrayList<>();
Collection<V> list = new ArrayList<>();
我了解到 Hypergraph.getVertices()
是您无法修改的库方法。所以你必须操纵调用该方法的结果。正如 .
所建议的,排序是此处的选项
但这需要您实现 <V>
(示例中的 MyGraph.MyVertex
)将实现 java.lang.Comparable
,或者您提供 java.util.Comparator
的实现以确保顶点的静态排序顺序。
而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()
并尝试对其进行排序......
通常,当一个方法 returns 一个 Collection
以某种方式表示对象的内部状态时,这是一个不可修改的集合。显然,这里的排序也会失败。所以唯一安全的方法就是复制结果,然后对副本进行排序。
如您所见,JUNG 2.x 本身不提供此选项,因此您唯一真正的选择是复制输出并对其进行排序,并且假设您有一个 Comparator
这对您的顶点类型有意义。 (这也使得保留原始插入顺序变得容易。)
Guava graph library, also known as common.graph
, is used by JUNG 3.0(开发中)并在几个不同的层面上支持稳定排序:
Immutable
graphs' 访问器每个 return 具有稳定排序的 Set
。
如果你想要一个mutable graph, the built-in implementations, which are constructed using GraphBuilder
(and its sibling types) can specify using nodeOrder()
图形节点应该是以下任何一个:
- 按插入顺序(默认)
- 无序
- 自然排序(如果您的节点类型实现
Comparable
)
- 已排序
对于 Networks
(类似于 JUNG Graph
类型),您可以对图的边施加相同的排序。
您还可以构造一个可变图,它使用 incidentEdgeOrder()
在图上 Builder
.
(免责声明:我共同创建了 JUNG 并仍在维护它,还创建了 common.graph
。)
我有一些代码:
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]
这每次都会返回一个随机顺序的顶点列表。因此,我在代码其他地方的结果不可重复,而且很难追踪。
我想每次都以相同的方式恢复元素的顺序。我目前的猜测是我必须将集合转换为某种保留顺序的数据结构,然后对其进行排序,以便结果是可重复的,但是有没有更好的方法来做到这一点? (我不确定从 Collection 转换为数组等其他东西是否会破坏其他地方的代码,因为我是 Collections 的新手)。任何帮助都会很棒!
你可以使用这样的东西:
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]
只需使用ArrayList 来实现Collection。 ArrayList 的行为就像一个数组。它们以相同的顺序出现。
Collection<E> list = new ArrayList<>();
Collection<V> list = new ArrayList<>();
我了解到 Hypergraph.getVertices()
是您无法修改的库方法。所以你必须操纵调用该方法的结果。正如
但这需要您实现 <V>
(示例中的 MyGraph.MyVertex
)将实现 java.lang.Comparable
,或者您提供 java.util.Comparator
的实现以确保顶点的静态排序顺序。
而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()
并尝试对其进行排序......
通常,当一个方法 returns 一个 Collection
以某种方式表示对象的内部状态时,这是一个不可修改的集合。显然,这里的排序也会失败。所以唯一安全的方法就是复制结果,然后对副本进行排序。
如您所见,JUNG 2.x 本身不提供此选项,因此您唯一真正的选择是复制输出并对其进行排序,并且假设您有一个 Comparator
这对您的顶点类型有意义。 (这也使得保留原始插入顺序变得容易。)
Guava graph library, also known as common.graph
, is used by JUNG 3.0(开发中)并在几个不同的层面上支持稳定排序:
Immutable
graphs' 访问器每个 return 具有稳定排序的Set
。如果你想要一个mutable graph, the built-in implementations, which are constructed using
GraphBuilder
(and its sibling types) can specify usingnodeOrder()
图形节点应该是以下任何一个:- 按插入顺序(默认)
- 无序
- 自然排序(如果您的节点类型实现
Comparable
) - 已排序
对于
Networks
(类似于 JUNGGraph
类型),您可以对图的边施加相同的排序。您还可以构造一个可变图,它使用
incidentEdgeOrder()
在图上Builder
.
(免责声明:我共同创建了 JUNG 并仍在维护它,还创建了 common.graph
。)