【问题标题】:Does the list returned from Arrays.asList maintain the same order as the original array collection?从 Arrays.asList 返回的列表是否保持与原始数组集合相同的顺序?
【发布时间】:2011-02-11 17:59:11
【问题描述】:

我有一个 ArrayList,我正在迭代几次,看起来它没有保持迭代的顺序。我看得更深,似乎为这次迭代(由其他人)编写的自定义迭代器标记首先采用传入的 ArrayList 并在迭代之前使用 Arrays.asList 将其桥接到 Object[] 集合。迭代顺序是否丢失?这是 Arrays.asList 所期望的吗?

编辑:

这是该操作对传递给迭代器标签的原始集合所做的操作:

if(collection.getClass().isArray()) {
    iterator = Arrays.asList((Object[]) collection).iterator();
} else if(collection instanceof Collection) {
    iterator = ((Collection) collection).iterator();
} else if(collection instanceof Iterator) {
    iterator = (Iterator) collection;
} else if(collection instanceof Map) {
    iterator = ((Map) collection).entrySet().iterator();
}

【问题讨论】:

  • 您的订单丢失了吗?
  • 似乎是这样,但我试图找出原因,或者它是否与我构建 UI 的方式有关,而不是迭代本身。至少可以说,我正在使用的自定义迭代器“很难”。
  • 你混淆了一些东西,该方法检查集合是否是一个数组,如果它被包装在一个列表中,如果集合是一个你声称的 Arraylist,那么它只返回迭代器参见 instanceof Collection 部分.

标签: java collections arraylist


【解决方案1】:

List 仍然由原始数组支持,因此项目的出现顺序应与它们在数组中的顺序相同。

另外,请注意 asList 是一个通用方法,所以Arrays.asList(T[]) 将返回一个List<T>

至于其他方向,ListtoArray

返回一个包含所有 此列表中的元素正确 序列(从第一个元素到最后一个元素)。

有两个 toArray 方法。第一个返回一个Object[],第二个将一个数组作为参数并返回相同类型的数组。

这样的事情并不少见,以字符串数组为例:

String[] y = x.toArray(new String[0]);

(此示例取自JavaDoc for List<E>

【讨论】:

  • 虽然对象有backed,但迭代现在是通过Object[],所以我认为它可能会丢失迭代顺序。
  • @hal10001:等等……那不是用ListtoArray()而不是Arrays.asList()吗?
  • 我添加了一些代码以更好地评估原始集合的情况。
  • @hal: 从什么时候开始数组中的项目没有排序?它们是按索引排序的,对吗?你是不是对 hashmaps/hashsets/hashtables 感到困惑?
  • @hal10001:我认为你很困惑......如果为您发布为collection 的代码提供了ArrayList,则将直接使用它的Iterator,因为它是Collection。如果为该代码提供了一个数组,则Arrays.asList 将用于将该数组桥接到List,而不是相反。
【解决方案2】:

如果collection 是一个地图,那么迭代可能会被抛出

 else if(collection instanceof Map) {
    iterator = ((Map) collection).entrySet().iterator();
}

如果collection 专门是HashMap,则集合元素的顺序确实被抛到了窗外。

如果collectionTreeMap,它应该根据排序维护集合的顺序。但是,如果您从 Comparable 对象的数组中创建 TreeMap,您不应该期望数组和 TreeMap 具有相同的顺序,因为 TreeMap 将对数组的内容进行排序.

您还可能会得到一些其他的Collection,它们会像HashSetPriorityQueue 等一样乱七八糟。

但是,如果 collection 从来不是 Map 并且始终是 Array,则 Arrays.asList 应该保持顺序。我最好的猜测是,您的问题要么存在于您的代码 sn-p 之外,要么存在于您传递数组之外的一种情况。

【讨论】:

  • 我刚刚意识到......如果我有一个 TreeMap,然后将它转换为一个 Map,那么迭代顺序会丢失不是吗?
  • @hal10001 如果它是 TreeMap,则不应丢失迭代顺序(仅仅因为您将 TreeMap 视为 Map 并不意味着它失去了作为 TreeMap 的特性)。如果是这样的话,我现在有点困惑:-p
  • @hal10001:强制转换永远不会改变对象的行为或结构,它只会改变您引用该对象的类型。
  • @hal10001 就像 ColinD 说的那样。仅仅因为我称灰熊为“熊”,并不意味着它不再是灰熊。据附近的每个人都知道,这是一只熊。
  • 感谢 ColinD 的直截了当的澄清。
【解决方案3】:

您可以更通用地将Collection 替换为Iterable

} else if(collection instanceof Iterable) {
    iterator = ((Iterable) collection).iterator()

注意:像int[].class.isArray() == true 这样的原始数组,但不能使用Object[] 进行强制转换

【讨论】:

  • 我正在使用几年前由其他人在 JAR 文件中开发的 API,所以很遗憾我无法更改迭代器标记实现。
猜你喜欢
  • 1970-01-01
  • 2020-01-26
  • 2020-02-06
  • 2019-11-01
  • 1970-01-01
  • 2016-06-07
  • 2022-01-13
  • 2020-05-25
  • 2015-03-13
相关资源
最近更新 更多