如果我从同一组创建2个列表,我可以确定在两个列表中都得到相同的排序吗? (只要两个列表具有相同的顺序,并且我在创建两个列表之间没有对集合执行任何操作,我不关心排序。)
List l = new ArrayList(set);
List l1 = new ArrayList(set);
我知道有保证创建这些列表并获得相同顺序的方法,并且我没有充分的理由以这种方式创建两个列表,但我想知道为什么元素的排序如果没有对其执行修改操作,则集合将会改变。
编辑:该集合是无序的HashSet
答案 0 :(得分:5)
您可能在列表l
和l1
中获得相同的排序。但由于大多数集合都是无序的,因此您没有保证将会有相同的顺序。
从技术上讲,您可以编写Set
接口的实现,每次调用任何方法时都会更改其顺序。这仍然可以实现界面。
由于在构造函数new ArrayList(Collection)
中调用了集合的toArray
方法,因此我们可以查看Set#toArray()
的{{3}}:
返回包含此set中所有元素的数组。如果此set对其迭代器返回的元素的顺序做出任何保证,则此方法必须以相同的顺序返回元素。
虽然Set#iterator()
的Javadoc说没有一般保证:
返回此set中元素的迭代器。元素以无特定顺序返回(除非此集合是某个提供保证的类的实例)。
鉴于此,我强烈建议您不要依赖列表的排序。
答案 1 :(得分:4)
public ArrayList(Collection c)构造一个列表 包含指定集合的元素,按顺序排列 由集合的迭代器
返回
所以它真的取决于Set
接口实现类,如果顺序是常量的。
例如,如果您使用LinkedHashSet
,则迭代顺序是可预测的。
答案 2 :(得分:0)
有些结构可以保证他们的订单。如果我们提到Java实现的Set
接口,则无法保证。很可能ArrayList
的构造函数使用了Set
的迭代器。所以这两个列表当然包含总是相同的元素但是顺序这实际上是Set
使用contains
关键字而不是find
来检查元素是否存在的原因。
它的子接口
SortedSet
表示已排序的集合 根据一些标准。在Java 6中,有两个标准 实现SortedSet
的容器。他们是TreeSet
和ConcurrentSkipListSet
除
SortedSet
界面外,还有。{LinkedHashSet
课程。它记得的顺序 元素被插入到集合中,并返回其中的元素 顺序。
答案 3 :(得分:0)
在Set
等无序集合上强加所需(自然或其他)订单的一种方法是从中创建有序Set
(换句话说,SortedSet
)给定的集合。如果你的集合不是太大而你所关心的是一个可预测的迭代顺序,你可以这样做:
// set = ...
List<? extends Comparable> list = new TreeSet<>(set).stream().collect(Collectors.toList());
这假定该集合由可比较的元素组成。或者,您可以在TreeSet
构造函数中使用自己的比较器。然而,如果元素本身不具有可比性,那么创建这样的比较器可能存在一些问题。
答案 4 :(得分:-2)
这里有一些很好的答案,我可以提出解决方案。
List list = new ArrayList(set);
List secondList = new ArrayList(list);