带位置索引的地图

时间:2014-10-27 23:17:43

标签: java algorithm sorting

哪个集合将满足以下测试程序:

public class TestOrderedList {

  // The class I'm looking for:
  MapWithIndex<String,Person> ol = new MapWithIndex<String, Person>();

  // class Person left out for brevity

  public TestOrderedList() {

    Person benny = new Person("Benny");
    Person charles = new Person("Charles");
    Person alvin = new Person("Alvin");
    Person calvin = new Person("Calvin");

    ol.put("Benny", benny);     // should return 0
    ol.put("Charles", charles); // should return 1
    ol.put("Alvin", alvin);     // should return 0
    ol.put("Calvin", calvin);   // should return 2

    int index = ol.findIndex("Benny"); // should return 1 
    Person adam = new Person("Adam");
    ol.put("Adam", adam);              // should return 0 (new pos)
    index = ol.findIndex("Benny");     // should return 2
    ol.remove("Alvin");                // should return 1 (existing pos)
    index = ol.findIndex("Benny");     // should return 1
  }
}

该集合不必实现任何特定的接口,也不必转换为另一个集合(但是这可能会很好)。

它不必是线程安全的,但如果它是......好!

未找到时返回-1或错误情况正常。

收集的目的是我很快就需要知道新插入记录的位置。我还想查看记录的存在位置。

该集合不需要支持重复密钥。

---更新----

我选择了ArrayList解决方案,在插入之前通过二进制查找对其进行排序(以获取应插入的索引)。这样,列表中的位置始终对应于行号(在与此列表同步的表中)。它快速而简单。我确定必须存在比我更强大的实现吗?!?!

3 个答案:

答案 0 :(得分:1)

您可以使用具有&#34; find&#34;的二进制搜索实现的数组,问题在于使用数组添加/删除项目的成本很高。 indexable skip list更适合增长/缩小,使用相同的平均情况查找作为数组,但是数组具有更好的最坏情况查找,并且还可以具有更好的缓存性能。如果您期望频繁添加/删除,那么我会说使用可索引的跳过列表,如果它们很罕见则使用数组。可能还有某种方法来缓冲数组的添加/删除以获得更好的摊销性能,但是我不知道你是如何做到的。

答案 1 :(得分:0)

使用linkedHashMap确保订单并将其索引保存在单独的地图实施中。

答案 2 :(得分:0)

import java.util.Map;  
import java.util.Set;  
import java.util.TreeMap;  

public class MySortMap {


// The class I'm looking for:
  Map<String,Person> ol = new TreeMap<String, Person>();

  // class Person left out for brevity

  public void TestOrderedList() {

    Person benny = new Person("Benny");
    Person charles = new Person("Charles");
    Person alvin = new Person("Alvin");
    Person calvin = new Person("Calvin");

    ol.put("Benny", benny);     // should return 0
    ol.put("Charles", charles); // should return 1
    ol.put("Alvin", alvin);     // should return 0
    ol.put("Calvin", calvin);   // should return 2

    int index = getIndex(ol.keySet(), "Benny"); // should return 1 
    System.out.println("expected 1, index="  + index);
    Person adam = new Person("Adam");
    ol.put("Adam", adam);              // should return 0 (new pos)
    index = getIndex(ol.keySet(), "Benny");     // should return 2
    System.out.println("expected 2, index="  + index);
    ol.remove("Alvin");                // should return 1 (existing pos)
    index = getIndex(ol.keySet(), "Benny");     // should return 1
    System.out.println("expected 1, index="  + index);

  } 

  private int getIndex(Set<String> paramSet, String paramSearchStr) {
      int result = -1;
      for (String strSetValue : paramSet) {
        result++;
        if (strSetValue.equals(paramSearchStr)) {
            return result;
        }
    }
      return -1;
  }
/**
 * @param args
 */
public static void main(String[] args) {
    MySortMap mySortMap = new MySortMap();
    mySortMap.TestOrderedList();
}

    class Person {
        public Person(String paramPerson) {

        }
    }
}

RESULT:  
expected 1, index=1  
expected 2, index=2  
expected 1, index=1