TreeMap没有返回所有键

时间:2013-09-06 08:32:19

标签: java hashmap treemap

我有一个要求,就像我需要根据属性文件条目中定义的某些序列对Map内的键进行排序。所以输出应该根据用户在属性条目上定义的顺序来进行。为此,我尝试过使用TreeMapComparator

我的属性文件条目是

seq=People,Object,Environment,Message,Service

以下是我的代码:

Properties prop=new Properties();
prop.load(new FileInputStream("D:\\vignesh\\sample.properties"));
final String sequence=prop.getProperty("seq");
// Display elements
     final String sequence=prop.getProperty("seq");
     System.out.println("sequence got here is "+sequence); 
      //Defined Comparator
      Comparator<String> comparator = new Comparator<String>() {
          @Override
          public int compare(String key1, String key2) {
              return sequence.indexOf(key1) - sequence.indexOf(key2);
          }
      };
SortedMap<String,String> lhm = new TreeMap<String,String>(comparator);
       // Put elements to the map
          lhm.put("Object", "biu");
          lhm.put("Message", "nuios");
          lhm.put("Service", "sdfe");
          lhm.put("People", "dfdfh");
          lhm.put("Environment", "qwe");
          lhm.put("Other", "names");
          lhm.put("Elements", "ioup");          //Not showing in output
          lhm.put("Rand", "uiy");               //Not showing in output
//Iterating Map
      for(Entry<String, String> entry : lhm.entrySet()) {
            System.out.println(entry.getKey());
        }

输出

sequence got here is People,Object,Environment,Message,Service
Other
People
Object
Environment
Message
Service

现在我对这段代码有些问题。

  • 我的地图中有近8个元素。但输出只显示6个 为什么最后两个元素没有来?

  • 与序列不匹配的值位于顶部 现在。我想把那些放在最底层。有办法吗?

  • 这里我已经声明了从属性文件中读取的字符串 作为final,所以我不能每次都改变财产。当我 删除最终标识符,它在我的IDE中显示错误。我怎么能 避免这样做?

  • HashMap中的我的键可能不完全等于属性条目
    所以我需要检查我的序列中是否包含该序列 HashMap key.Do我需要更改我的Comparator吗?

2 个答案:

答案 0 :(得分:2)

并不是因为你的元素没有打印,而是它们没有被添加到地图中!

在已排序的地图中,您有:

  

有序映射使用compareTo(或compare)方法执行所有键比较,因此从排序映射的角度来看,这种方法认为相等的两个键是相等的。

但地图不能有两个相同的键:

  

地图不能包含重复的键;每个键最多可以映射一个值。

但是当比较ElementOther时,比较器返回零。它将这两个字符串视为等号,因此最新的字符串不会添加到地图中。

正如SortedMap的javadoc中所建议的那样:

  

注意,如果有序映射要正确实现Map接口,则由有序映射维护的排序(无论是否提供显式比较器)必须与equals一致。

所以我建议你确保当你的比较器返回0时,这是因为比较的两个元素确实是等于。 一种非常“天真”的方式是:

Comparator<String> comparator = new Comparator<String>() {
      @Override
      public int compare(String key1, String key2) {
          int returned = sequence.indexOf(key1) - sequence.indexOf(key2);

          if (returned == 0 && !key1.equals(key2))
              returned = -1;

          return returned;

      }
  };

答案 1 :(得分:0)

首先,indexOf会为-1中无法找到的任何子字符串返回String

当您插入"Other"时,indexOf("Other")会返回-1indexOf("People")会返回0,这会在第一个地图中添加"Other"位置。

但是,在添加其他字符串时,会针对"Other"对其进行测试,-1将返回-1。不幸的是,属性值字符串中也缺少所有其他元素,因此返回sequence.indexOf(key1) - sequence.indexOf(key2)。这意味着0"Other",并假设它们都等于{{1}}。