【问题标题】:How to sort a complex HashMap structure in Java?如何在 Java 中对复杂的 HashMap 结构进行排序?
【发布时间】:2014-05-26 15:00:16
【问题描述】:

我正在开发一个频率图,用于计算文本中词条的频率,同时保存它们的弯曲。我的数据结构如下所示:

HashMap<List<String>, HashMap<List<String>, Long>> frequencyMap = ... ;

第一个列表包含一系列词条,第二个列表包含单词的弯曲及其频率。有没有办法按频率计数对这个数据结构进行排序?

或者您会建议另一种数据结构来存储这些值,例如更容易排序。

感谢任何帮助。

【问题讨论】:

  • 您能否进一步说明您希望如何对其进行排序?我不熟悉lemmataflexion的概念。
  • TreeMap 是排序后的地图。你可以试试看。
  • 也许这个话题可以帮到你一点:here
  • 也许最好在一个类中定义这些概念(词条等),并公开明确你想用那个类做什么的方法,而不是仅仅实现Comparable关于您要排序的内容的界面...并且代码会更清晰:)
  • HashMap 不保证地图的顺序。 TreeMap 确实如此。其次,您能否提供一个示例输入和预期输出?

标签: java list sorting hashmap frequency


【解决方案1】:
List sortedKeys=new ArrayList(yourMap.keySet());
Collections.sort(sortedKeys);

试试这个!

【讨论】:

    【解决方案2】:

    您拥有的数据结构不容易排序,因为您可以为每个值列表设置一组键。

    例如,您将拥有一个与字符串和值列表映射匹配的字符串列表,其中所有这些值都可以引用不同的键。

    首先尝试简化数据结构。用 来表示。然后使用 TreeMap 或 Collections.sort,如 @Lockon 所述。

    对于 TreeMap 示例:http://tutorialswithexamples.com/java-treemap-tutorial-and-examples/

    【讨论】:

      【解决方案3】:

      此地图有两种排序方式。根据 Long 值对内部映射进行排序。或者根据内部映射中的 Long 值对外部映射进行排序。在后一种情况下,排序将仅比较内部映射中第一项的值。我认为这是您的要求。然后你可以使用下面的方法

      private Map<List<String>, HashMap<List<String>, Long>> sortMap(
              Map<List<String>, HashMap<List<String>, Long>> unsortedMap) {
      
          List<Entry<List<String>, HashMap<List<String>, Long>>> list = new LinkedList<Entry<List<String>, HashMap<List<String>, Long>>>(
                  unsortedMap.entrySet());
      
          Collections.sort(list,
                  new Comparator<Entry<List<String>, HashMap<List<String>, Long>>>() {
      
                      @Override
                      public int compare(
                              Entry<List<String>, HashMap<List<String>, Long>> o1,
                              Entry<List<String>, HashMap<List<String>, Long>> o2) {
      
                          return o1.getValue().entrySet().iterator().next().getValue().compareTo(o2.getValue().entrySet().iterator().next().getValue());
                      }
                  });
      
          Map<List<String>, HashMap<List<String>, Long>> sortedMap = new LinkedHashMap<List<String>, HashMap<List<String>, Long>>();
          for(Entry<List<String>, HashMap<List<String>, Long>> item : list){
              sortedMap.put(item.getKey(), item.getValue());
          }
          return sortedMap;
      }
      

      【讨论】:

        【解决方案4】:

        HashMaps 不支持对元素进行排序,因此您必须首先将数据复制到允许排序的数据结构中:

        ArrayList<Map.Entry<List<String>, HashMap<List<String>, Long>> items =
            new ArrayList<>(frequencyMap.entrySet());
        

        现在,写一个比较 Map.Entry 值的 Comparator

        class FrequencyComparator
        implements Comparator<Map.Entry<List<String>, HashMap<List<String>, Long>> {
            public int compare(Map.Entry<List<String>, HashMap<List<String>, Long>> a,
                               Map.Entry<List<String>, HashMap<List<String>, Long>> b) {
                // code to get a's and b's frequency counts and compare them
            }
        }
        

        现在,您可以对数组进行排序:

        Collections.sort(items, new FrequencyComparator());
        

        如果获取项目的频率计数很昂贵,那么您可以为每个项目计算一次,然后对包含这些预先计算值的数据结构进行排序:

        class FrequencySortHelper implements Comparable<FrequencySortHelper> {
            final List<String> key;
            final int score;
            public FrequencySortHelper(List<String> key, HashMap<List<String>, Long>> value) {
                this.key = key;
                score = getFrequencyCount(value);
            }
        
            public int compareTo(FrequencySortHelper other) {
                int thisVal = this.score;
                int anotherVal = other.score;
                return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
            }
        }
        
        ArrayList<FrequencySortHelper> items = new ArrayList<>(frequencyMap.size());
        for (Map.Entry<List<String>, HashMap<List<String>, Long>> item : frequencyMap.entrySet()) {
            items.add(new FrequencySortHelper(item.key(), item.value()));
        }
        
        Collections.sort(items);  // Uses FrequencySortHelper's compareTo()
        

        如果您认为Map.Entry&lt;List&lt;String&gt;, HashMap&lt;List&lt;String&gt;, Long&gt;&gt; 的所有这些东西都很尴尬,那么您是对的。您应该考虑定义一些对象来包含这些数据,而不是仅仅将集合串在一起。

        【讨论】:

          猜你喜欢
          • 2010-10-21
          • 1970-01-01
          • 2020-06-24
          • 2022-11-15
          • 1970-01-01
          • 1970-01-01
          • 2023-04-06
          • 1970-01-01
          相关资源
          最近更新 更多