英文:
analysing the proportion of names in a set of names. my output is incorrect. ("John") should return 0.25. and mary should be 0.5
问题
以下是翻译好的内容:
public class Problem
{
private int count;
private final HashMap<String, Integer> counts;
public Problem() {
this.counts = new HashMap<>();
}
public void addName(String name)
{
Integer nameCount = counts.get(name);
if (nameCount == null)
{
nameCount = 1;
counts.put(name, nameCount);
nameCount++;
}
nameCount++;
count++;
}
// 这个函数应该计算比例
public double nameProportion(String name)
{
return counts.get(name) / (double) count;
}
public static void main(String[] args)
{
Problem namesCount = new Problem();
namesCount.addName("James");
namesCount.addName("John");
namesCount.addName("Mary");
namesCount.addName("Mary");
System.out.println("约翰的比例: " + namesCount.nameProportion("John"));
System.out.println("玛丽的比例: " + namesCount.nameProportion("Mary"));
}
}
目前输出结果是不正确的,由于某种原因没有将两个玛丽视为同一人。
英文:
my output is currently ("john") returns 0.25 and ("mary") also returns 0.25
public class Problem
{
private int count;
private final HashMap<String, Integer> counts;
public Problem() {
this.counts = new HashMap<>();
}
public void addName(String name)
{
Integer nameCount = counts.get(name);
if (nameCount == null)
{
nameCount = 1;
counts.put(name, nameCount);
nameCount++;
}
nameCount++;
count++;
}
this function should calculate the proportion
public double nameProportion(String name)
{
return counts.get(name) / (double) count;
}
public static void main(String[] args)
{
Problem namesCount = new Problem();
namesCount.addName("James");
namesCount.addName("John");
namesCount.addName("Mary");
namesCount.addName("Mary");
System.out.println("Fraction of Johns: " + namesCount.nameProportion("John"));
System.out.println("Fraction of Marys: " + namesCount.nameProportion("Mary"));
}
}
right now the output is incorrect, for some reason its not seeing the two marys as the same
答案1
得分: 0
原始类型和原始包装类型在执行nameCount++
操作时并不是不可变的,它不会改变哈希映射中键的值。它会创建另一个整数对象,并将nameCount + 1
的值放入该对象中,因此在您的代码中,哈希映射中所有键的值都是1。
英文:
Primitive and primitive wrapper are not immutable when you do nameCount++, it doesn't change the value of key in hashmap. It create another Integer object and put the value of nameCount +1 into that object, so the value of all key in hashmap in your code is 1.
答案2
得分: 0
这一切都在你的函数 Problem#addName
中。实际上,你是在函数的末尾增加了 nameCount
,但是当函数到达块的末尾时,增加后的值就丢失了(nameCount
是一个局部变量,不是成员变量)。
解决方法是,如果 nameCount
不为 null
,就将其递增,并将其放入 counts
映射中,示例如下:
public void addName(String name) {
Integer nameCount = counts.get(name);
if (nameCount == null) {
counts.put(name, 1);
} else {
counts.put(name, ++nameCount);
}
count++;
}
如果为 null
,则只需将 1
放入映射中,对应于相应的 name
。
递增 count
是可以的,因为那是一个成员变量,并且在创建的 namesCount
引用到 Problem
对象中得以保存。
英文:
It's all in your function Problem#addName
. You are actually incrementing your nameCount
at the end of the function, but the incremented value is lost when the function reaches the end of the block (nameCount
is a local variable, not a member variable).
The solution to this is to increment nameCount
if it is not null
and put that into the counts
map, like so for example:
public void addName(String name) {
Integer nameCount = counts.get(name);
if (nameCount == null) {
counts.put(name, 1);
} else {
counts.put(name, ++nameCount);
}
count++;
}
If it is null
, then simply a 1
is put into the map for the corresponding name
.
Incrementing the count
is fine, because that is a member variable and is saved within the created namesCount
reference to the Problem
object.
答案3
得分: 0
你如果名称已经存在于Map
中,则不会对其进行更新。需要注意的是,Integer
对象是不可变的;如果你不想不断丢弃先前的对象,可以使用AtomicInteger
来代替。 <sup>演示</sup>
public void addName(String name) {
Integer nameCount = counts.get(name);
if (nameCount == null) {
nameCount = 1;
counts.put(name, nameCount);
} else {
counts.put(name, nameCount + 1);
}
count++;
}
你可以使用Map#getOrDefault
来简化这个过程。 <sup>演示</sup>
public void addName(String name) {
counts.put(name, counts.getOrDefault(name, 0) + 1);
count++;
}
英文:
You never update the Map
if the name already exists in it. It is important to note that Integer
objects are immutable; you can use AtomicInteger
instead if you do not want to keep discarding previous objects. <sup>Demo</sup>
public void addName(String name) {
Integer nameCount = counts.get(name);
if (nameCount == null) {
nameCount = 1;
counts.put(name, nameCount);
} else {
counts.put(name, nameCount + 1);
}
count++;
}
This can be simplified using Map#getOrDefault
. <sup>Demo</sup>
public void addName(String name) {
counts.put(name, counts.getOrDefault(name, 0) + 1);
count++;
}
专注分享java语言的经验与见解,让所有开发者获益!
评论