【问题标题】:Java - TreeMap SolutionJava - TreeMap 解决方案
【发布时间】:2011-10-28 23:13:02
【问题描述】:

我有一段时间没学过Java了,我需要一些关于数据结构的建议和想法。

目前我正在使用 TreeMap 将字符串值映射到整数值。我现在需要做一些计算,并将地图条目的整数值除以整个地图的大小,并为每个条目存储它。我在考虑使用 Map,Integer> 但是 Java 中有 3 路泛型数据结构吗?

我目前的解决方案是这个..

            int treeSize = occurrence.size();
            String [][] weight = new String[treeSize][2];
            int counter=0;
            double score =0;
            for(Entry<String, Integer> entry : occurrence.entrySet()) {
                weight[counter][0]=entry.getKey();
                score=entry.getValue()/treeSize;
                weight[counter][1]= Double.toString(score);
                counter++;
              }

【问题讨论】:

  • 请正确缩进您的代码。

标签: java data-structures


【解决方案1】:

我会使用另一个对象来保存这些数据:

public Data {
    private int value;
    private double score;

    ...
}

然后将地图键入为Map&lt;String, Data&gt;。插入所有值后,您可以遍历这些值并更新映射中每个值的 ratio 属性。例如:

double size = myMap.size();
for(Map.Entry<String, Data> entry : myMap.entrySet()) {
    Data data = entry.getValue();
    data.setScore(data.getValue() / size); 
}

编辑

突然想到另一个想法。而不是在插入它之后计算值,你应该在插入它时计算它;这样更有效率。当然,只有事先知道值的总数才能这样做。

更好的方法是仅在您从地图中检索值时执行计算。这样做有两个好处:

  • 您不需要单独的对象。只需将映射中值的访问抽象化到另一个函数中,该函数返回与键关联的值,除以映射的大小。
  • 由于您没有单独的对象来维护计算的值,因此您无需在每次添加或删除新值时更新它。

【讨论】:

  • 我正在考虑创建自己的通用类,好主意。
【解决方案2】:

您可以使用Map.Entry&lt;Integer, Double&gt; 来保存这两个值。 (最终,您会使用 AbstractMap.SimpleEntry 或 AbstractMap.SimpleImmutableEntry)

所以您的 TreeMap 将是 TreeMap&lt;String, Map.Entry&lt;Integer, Double&gt;&gt;

但是,除非您有充分的理由不这样做,否则我强烈建议您即时进行计算。重新计算每个分数每次插入或删除任何东西都非常耗时,并且会搅动小对象,因此它可能会计算。此外,如果多个线程访问 TreeMap,重新计算将导致线程问题。相反,像

public synchronized double getFraction(String key) {
   Integer value = theTreeMap.get(key);
   if (value == null)
      return 0.0;  // or throw an exception if you prefer...

   // note, since the Map has at least one entry, no need to check for div by zero
   return value.doubleValue() / theTreeMap.size();
}

【讨论】:

  • 我决定将它添加到 ArrayList 并在它们全部添加到地图后对其进行评分。然后使用 indexOf(Collections.max(list)) 获取最高分的索引,并使用该索引从 Map 中检索它。这是一种合适的方式吗?即时进行是对的,因为它可以节省时间。
  • 这是一种方式。您可以直接使用ArrayList&lt;Double&gt; sorter = new ArrayList(theTreeMap.values());,然后对其进行排序或仅使用 Collections.max()。
  • 糟糕 - 取消我之前评论中的“排序”。对值进行排序会丢失索引!必须使用 Collections.max()。或者,您可以制作一个条目 列表,并使用比较值的比较器对它们进行排序。更通用的目的。 Guava 或 Apache 可能已经有代码可以做到这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多