【问题标题】:How to keep List index fixed in Java如何在 Java 中保持列表索引固定
【发布时间】:2012-01-21 13:48:39
【问题描述】:

我想保持 Java 列表中项目的索引固定。

示例代码:

import java.util.ArrayList;
public class Test {
    public static void main(String[] args) {
        ArrayList<Double> a = new ArrayList<Double>();
        a.add(12.3);
        a.add(15.3);
        a.add(17.3);

        a.remove(1);
        System.out.println(a.get(1));
    }
}

这将输出17.3。问题是 17.3 在索引 2 上,现在它在索引 1 上!

有没有办法在移除一个元素时保留其他元素的索引?还是有其他更适合此目的的类?

注意:我不想要一个固定大小的集合。

【问题讨论】:

    标签: java list collections indexing fixed


    【解决方案1】:

    您可能希望将java.util.SortedMapint 键一起使用:

    import java.util.*;
    public class Test {
    
        public static void main(String[] args) 
        {
            SortedMap<Integer, Double> a = new TreeMap<Integer, Double>();
            a.put(0, 12.3);
            a.put(1, 15.3);
            a.put(2, 17.3);
    
            System.out.println(a.get(1)); // prints 15.3
            System.out.println(a.get(2)); // prints 17.3
    
            a.remove(1);
    
            System.out.println(a.get(1)); // prints null
            System.out.println(a.get(2)); // prints 17.3
        }
    }
    
    • SortedMap 是一个可变大小的集合
    • 它存储映射到有序键集的值(类似于List 的索引)

    java.util.List#remove(int) 的任何实现都不能保留索引,因为规范是这样写的:

    删除此列表中指定位置的元素(可选操作)。将任何后续元素向左移动(从它们的索引中减去 1)。返回从列表中移除的元素。

    【讨论】:

    • 如果你不想自己跟踪下一个索引,你可以继承SortedMap并添加一个public V put(V value),并在子类内部跟踪下一个索引。
    【解决方案2】:

    您可以调用a.set(1, null),而不是调用a.remove(1)。这将使所有元素保持在同一个位置,同时仍然“删除”索引 1 处的值。

    【讨论】:

    • 这样,我应该实现一个新的列表类型,有什么标准吗?
    • set方法List接口的标准方法。见docs.oracle.com/javase/6/docs/api/java/util/…
    • "set" 肯定是标准的,我的意思是我想要一个使用这种机制的标准类
    • @MhdSyrwan:不可能有这样的类,因为List#remove(int) 的语义要求实现“将任何后续元素向左移动”。
    • @maerics 指出得很好,我已要求将其添加到已接受的答案中。
    【解决方案3】:

    如果索引和值之间的关系应该始终相同,则使用java.util.Map

    【讨论】:

      【解决方案4】:

      不是通过调用 remove 来删除元素,而是将元素设置为 null:

      即:

      import java.util.ArrayList;
      public class Test 
      {
          public static void main(String[] args) 
      {
              ArrayList<Double> a = new ArrayList<Double>();
              a.add(12.3);
              a.add(15.3);
              a.add(17.3);
      
              a.set(1, null);
              System.out.println(a.get(1));
          }
      }
      

      【讨论】:

        【解决方案5】:

        您可以使用HashMap&lt;Integer, Double&gt;。您可以使用添加项目

        myMap.put(currentMaximumIndex++, myDoubleValue);
        

        这样,索引将是唯一的,如果您需要稀疏存储,那么您会相当不错,并且删除一个值不会损害现有的。

        【讨论】:

        • +1。这似乎是存储值而不更改索引的最节省空间的方式。
        【解决方案6】:

        除了上面的答案,它还建议您使用LinkedHashMap&lt;Integer,Double&gt;,而不是常规的 Hashmap 它将保留您插入元素的顺序。

        【讨论】:

          猜你喜欢
          • 2021-06-08
          • 2014-03-03
          • 2017-09-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-03-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多