【问题标题】:List vs Map/Dictionary列表与地图/字典
【发布时间】:2011-03-15 14:10:22
【问题描述】:

在某些情况下,您会使用列表,无论是数组还是链接。在其他情况下,您可以使用 Map、Java、Dictionary 或其他类似的东西。

当 Map 提供完全相同的功能时,您为什么还要使用 List,即通过索引访问(在本例中为整数...)。

不应该总是首选地图而不是列表吗?我在这里想念什么?

【问题讨论】:

标签: java list dictionary map


【解决方案1】:

this question 的重复。

但要针对您的问题给出具体答案,请考虑使用 Map 结构来维护按整数索引的集合的效率。

考虑这段代码:

public void add(Map map, Object o) {
    int index = map.size();
    map.put(index, o);
}

public static void add(List list, Object o) {
    list.add(o);
}

现在看看编译器把它变成了什么(使用javap 或者在像Eclipse这样的IDE中打开类文件):

public void add(java.util.Map map, java.lang.Object o);
     0  aload_1 [map]
     1  invokeinterface java.util.Map.size() : int [16] [nargs: 1]
     6  istore_3 [index]
     7  aload_1 [map]
     8  iload_3 [index]
     9  invokestatic java.lang.Integer.valueOf(int) : java.lang.Integer [22]
    12  aload_2 [o]
    13  invokeinterface java.util.Map.put(java.lang.Object, java.lang.Object) : java.lang.Object [28] [nargs: 3]
    18  pop
    19  return
      Line numbers:
        [pc: 0, line: 8]
        [pc: 7, line: 9]
        [pc: 19, line: 10]
      Local variable table:
        [pc: 0, pc: 20] local: this index: 0 type: MapListTest
        [pc: 0, pc: 20] local: map index: 1 type: java.util.Map
        [pc: 0, pc: 20] local: o index: 2 type: java.lang.Object
        [pc: 7, pc: 20] local: index index: 3 type: int

  // Method descriptor #38 (Ljava/util/List;Ljava/lang/Object;)V
  // Stack: 2, Locals: 2
  public static void add(java.util.List list, java.lang.Object o);
    0  aload_0 [list]
    1  aload_1 [o]
    2  invokeinterface java.util.List.add(java.lang.Object) : boolean [39] [nargs: 2]
    7  pop
    8  return
      Line numbers:
        [pc: 0, line: 13]
        [pc: 8, line: 14]
      Local variable table:
        [pc: 0, pc: 9] local: list index: 0 type: java.util.List
        [pc: 0, pc: 9] local: o index: 1 type: java.lang.Object

将集合维护为 List 的工作量要比 Map 少得多。所以 List 是一种更有效的数据结构。

【讨论】:

    【解决方案2】:

    在我看来,通过索引访问地图是一个不寻常的用例。通过键访问 Map 是一种更为常见的用例。

    在我看来,如果我需要使用定义明确的键在结构中查找对象,我会使用 Map。如果我通常想要遍历对象集合,我会使用 List。

    在我看来,使用键值实际上是索引的 Map 似乎您使用了错误的数据结构。

    【讨论】:

      【解决方案3】:

      从语义的角度来看,Map<Integer, E>List<E> 之间的区别如下:

      • 该列表包含从0list.size() 的所有索引,而地图可以包含任何索引(甚至是负索引),带有大孔。
      • 将元素添加到没有索引的列表时,您会自动获得一个新索引。对于地图,没有这样的操作。 (不过,您可以轻松地在 SortedMaps 上实现它。)
      • 添加或删除带有索引的元素时,列表中的后续索引会移动 1。在地图中,没有这种变化(添加的元素可能会替换现有的元素)。

      也就是说,我曾经创建了一个由HashMap<Integer, E> 支持的稀疏列表(主要包含null) - 但在那里我禁用了结构修改(类似于 Arrays.asList)。

      【讨论】:

        猜你喜欢
        • 2016-07-19
        • 1970-01-01
        • 2013-04-06
        • 1970-01-01
        • 1970-01-01
        • 2013-01-15
        • 2011-02-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多