【问题标题】:Logic to count the number of entries corresponding to each value in a hashmap in javajava中计算hashmap中每个值对应的条目数的逻辑
【发布时间】:2016-09-22 05:09:24
【问题描述】:

目前我已经在值字段上对我的 Hashmap 进行了排序。 我需要计算与哈希图中每个值相关联的条目数。

最初我想遍历排序的哈希图并计算条目数,直到值没有改变。为了获得下一个值,我需要进入下一个条目,但是在一个循环迭代结束之前没有办法做到这一点。 但我只是迷失在逻辑中,无法继续。 :(

我尝试了在 stream() 中使用过滤器的其他逻辑。 对 1 到 50 的值应用过滤器,然后计算满足谓词的条目。

for(int i = 1; i < COUNT; i++){
            int count = (int) single_count.entrySet().stream().filter(v -> v.getValue() == 1).count(); //collect(Collectors.toList());
            unigram_Nc.put(i, count);
        }

在这种情况下,我知道哈希图中的值。但我想知道通用解决方案,它返回与每个值对应的哈希图中的条目数。 有没有其他方法可以在不知道事先知道值的情况下计算具有特定值的条目数?

【问题讨论】:

  • 提示:您需要创建一个新的Map&lt;Integer,Integer&gt;,其中新映射中的键是第一个映射中的值,新映射中的值是条目数。

标签: java count hashmap


【解决方案1】:

您可以使用 java 8 流 api 更轻松地做到这一点。

为此,您应该从地图中获取值:map.values()

使用.stream(),您可以获得此集合的流。

那么您可以将collect 方法与groupingBy 收集器一起使用。

最后它可能看起来像这样:

final Map<Integer, Long> counts = map.values() // get the values
    .stream()                                  // get the stream
    .collect(
        Collectors.groupingBy(                 // the result should be grouped
            o -> o,                            // the key of the result map is just the value
            Collectors.counting()              // the value of result map is the count
        )
    );

【讨论】:

  • 谢谢。但是在这种情况下,collect 如何在没有指定 Collectors.toMap() 的情况下返回地图?另外,将结果类型转换为 HashMap 是否安全?
  • 正如groupingBy 函数的JavaDoc 所说:“结果收集器产生一个Map。”您不能简单地从Map 转换为HashMap,但您可以使用适当的构造函数从Map 创建HashMapnew HashMap&lt;&gt;(counts)
  • 您可以通过使用三个参数版本使Collectors.groupingBy(...) 具有HashMap 的返回类型:HashMap&lt;Integer, Long&gt; counts = map.values().stream() .collect(Collectors.groupingBy(o -&gt; o, HashMap::new, Collectors.counting()))
【解决方案2】:

对于较旧的 JDK,您可以这样计算:

Create a class and override its equals() and hashcode() method. Create a field of your preferred type say A and add another int type field to count.
1) Your hashcode() method should return the hash value of your field A.
2) In your equals() method, increase the value of count by 1 and set the count as value

Now create 2 hashmaps, first will have your initial map's value as keys. The second one will have the result of all the counts of values.

参考下面的sn-p:

class A
{
   Integer count = 1;
   String name;

   @override
   public int hashcode()
   {
      return name.hash();
   }

   @override
   public boolean equals(Object obj)
   {
      obj.count++;   
      secondmap.put(obj.name, obj.count);         

      return true;
   }

}

Now in your main class:

static firstmap = new ConcurrentMap<A, Integer>();

static secondmap = new ConcurrentMap<String, Integer>();

iterate over yourmap
{
   put the value in firstmap as firstmap.put(yourmap value, 0);
}

在迭代结束时,您将在 secondmap 中获得所有值的计数。 注意:如果您的初始映射具有不同的签名,那么您可以通过 A 的构造函数显式设置字符串名称的值。

这只是一个示例,实际实现可能会根据您的解决方案有所不同,但是您可以参考此逻辑。此外,在创建初始地图时,您可以实现这一点。这样可以省去再次迭代的麻烦。

【讨论】:

    【解决方案3】:

    试试这个简单的逻辑

    Map<String,Integer> dataMap=new LinkedHashMap<String,Integer>(); //Your data map
        Map<Integer,Integer> countMap=new LinkedHashMap<Integer,Integer>(); //map to count data map entries
    
        //initializing with default value
        dataMap.put("a", 1);
        dataMap.put("b", 2);
        dataMap.put("c", 1);
        dataMap.put("d", 2);
        dataMap.put("e", 1);
        dataMap.put("f", 3);
        dataMap.put("g", 1);
    
        //main logic
        dataMap.forEach( (k,v) -> {
            if(countMap.get(v)==null)
                countMap.put(v, 0);
            Integer count=countMap.get(v);
            countMap.put(v,count+1);
        } );
    
        //printing the count
        countMap.forEach( (k,v) -> {
            System.out.println(k+"       "+v);
        } );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-04
      • 1970-01-01
      • 2018-04-15
      相关资源
      最近更新 更多