2016-09-22 52 views
0

目前我已经在values字段中对我的Hashmap进行了排序。 我需要计算与散列映射中每个值关联的条目数。用于计算java中hashmap中每个值对应的条目数的逻辑

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

我试图其使用过滤器流()的其他逻辑。 应用上为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); 
     } 

在这种情况下我知道散列表中的值,但我想知道一般解决方案,它返回与每个值对应的散列表中的条目数 是否有任何其他方法来计算具有特定值的条目数知道前面的数值吗?

+1

提示:你需要创建一个新的'地图<整数,整数>'那里的新地图,关键是从第一张地图的价值,并在值新地图是条目的计数。 –

回答

2

你可以用java 8 stream 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 
     ) 
    ); 
+0

谢谢。但是在这种情况下collect没有指定Collectors.toMap()会如何返回地图?另外,将结果转换为HashMap是否安全? –

+0

作为['groupingBy']的JavaDoc(http://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#groupingBy-java.util.function.Function- java.util.stream.Collector-)函数说:“生成的收集器生成一个Map 。“ 你不能简单地从'Map'转换为'HashMap',但你可以通过使用适当的构造函数创建一个从'Map'一个'HashMap':'新的HashMap <>(计数)' –

+1

你可以得到'收藏家。 groupingBy(...)'通过使用三个参数版本:'HashMap counts = map.values()。stream().collect(Collectors.groupingBy(o - > O,HashMap中::新,Collectors.counting()))' – msandiford

0

对于较早的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. 

请参考下面的代码片段:

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的构造函数明确设置String名称的值。

这只是一个例子,根据你的解决方案,实际的实现可能会有所不同,但你可以参考这个逻辑。同时创建你的初始地图,你可以实现这一点。这将为您节省重复迭代的麻烦。

0

试试这个简单的逻辑

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); 
    }); 
+0

代码只回答未在SO鼓励。 –