Java 如何计算HashMap中唯一值的数量?
关于如何使用ArrayList和HashMaps,我在这里看到了很多不错的解决方案,但问题是我仍然无法解决我的问题 所以,我们的想法是,很少有人喝啤酒、葡萄酒和可乐。所以,它看起来是这样的,例如:Java 如何计算HashMap中唯一值的数量?,java,arraylist,hashmap,Java,Arraylist,Hashmap,关于如何使用ArrayList和HashMaps,我在这里看到了很多不错的解决方案,但问题是我仍然无法解决我的问题 所以,我们的想法是,很少有人喝啤酒、葡萄酒和可乐。所以,它看起来是这样的,例如: Steve wine Steve cola Ben cola Frank wine Ben cola Ben cola Frank wine 最后,我需要数一数他们每人喝了多少杯酒。因此,答案应该是这样的: Steve wine 1 Steve cola 1 Ben cola 3 Frank win
Steve wine
Steve cola
Ben cola
Frank wine
Ben cola
Ben cola
Frank wine
最后,我需要数一数他们每人喝了多少杯酒。因此,答案应该是这样的:
Steve wine 1
Steve cola 1
Ben cola 3
Frank wine 2
我的想法是创建一个对象PersonString名称String drink。然后我把所有的人都放到ArrayList。在此之后,我创建了HashMap,如果密钥不存在,我想在那里添加一个新的Person,如果密钥已经存在,我想增加到1
Map<Person, Integer> map = new HashMap<Person, Integer>();
for (Person p : persons)
{
if (map.containsKey(p)) {
map.put(p, map.get(p)+1);
} else {
map.put(p,1);
}
}
所以,据我所知,这应该是另一个技巧。也许你还可以告诉我其他关于如何计算酒杯数的方法,而不是使用HashMap?
非常感谢 将Person对象存储为密钥是一个错误 您必须存储人名,一个字符串作为键,它将正常工作
Map<String, Integer> map = new HashMap<>();
for (Person p : persons)
{
if (map.containsKey(p.getName())) {
map.put(p.getName(), map.get(p)+1);
} else {
map.put(p.getName(),1);
}
}
将Person对象存储为密钥是一个错误 您必须存储人名,一个字符串作为键,它将正常工作
Map<String, Integer> map = new HashMap<>();
for (Person p : persons)
{
if (map.containsKey(p.getName())) {
map.put(p.getName(), map.get(p)+1);
} else {
map.put(p.getName(),1);
}
}
覆盖Person类中的hashcode和equals方法覆盖Person类中的hashcode和equals方法
int count = Collections.frequency("your collection", "Your Value");
我想这样说:
ArrayList<String> list = new ArrayList<>();
list.add("Steve wine");
list.add("Steve cola");
list.add("Ben cola");
list.add("Frank wine");
list.add("Ben cola");
list.add("Ben cola");
list.add("Frank wine");
System.out.println(Collections.frequency(list, "Steve wine"));
System.out.println(Collections.frequency(list, "Ben cola"));
我想这样说:
ArrayList<String> list = new ArrayList<>();
list.add("Steve wine");
list.add("Steve cola");
list.add("Ben cola");
list.add("Frank wine");
list.add("Ben cola");
list.add("Ben cola");
list.add("Frank wine");
System.out.println(Collections.frequency(list, "Steve wine"));
System.out.println(Collections.frequency(list, "Ben cola"));
首先我建议你照顾好你的孩子。在你的情况下,真正的关键是订单而不是人,因为史蒂夫可乐和史蒂夫葡萄酒是不同的,你不应该把它命名为人
之后:containsKey将使用hashcode方法,如果不在类中重写它,该方法将从对象类继承。对象类的hashcode可能会为您的实例提供不同的hashcode,因此您应该在类中重写它。例如,如果您输入订单的唯一标识符名称和饮料,并对该字符串调用hashcode方法,则可以创建一个可接受的hashcode方法。首先,我建议您选择照顾好你的孩子。在你的情况下,真正的关键是订单而不是人,因为史蒂夫可乐和史蒂夫葡萄酒是不同的,你不应该把它命名为人 之后:containsKey将使用hashcode方法,如果不在类中重写它,该方法将从对象类继承。对象类的hashcode可能会为您的实例提供不同的hashcode,因此您应该在类中重写它。例如,您可以创建一个可接受的hashcode方法,如果您为订单指定名称和唯一标识符,并在该字符串上调用hashcode方法。在中重写equals和hascode方法您的Person类是您问题的解决方案 假设您有一个带有参数名和参数名的Person类,那么您可以使用eclipse之类的IDE为您生成hashcode和equals方法 见以下代码:
public class Person {
private String name;
private String drink;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDrink() {
return drink;
}
public void setDrink(String drink) {
this.drink = drink;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((drink == null) ? 0 : drink.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (drink == null) {
if (other.drink != null)
return false;
} else if (!drink.equals(other.drink))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
在Person类中重写equals和hascode方法是解决问题的方法
假设您有一个带有参数名和参数名的Person类,那么您可以使用eclipse之类的IDE为您生成hashcode和equals方法
见以下代码:
public class Person {
private String name;
private String drink;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDrink() {
return drink;
}
public void setDrink(String drink) {
this.drink = drink;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((drink == null) ? 0 : drink.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (drink == null) {
if (other.drink != null)
return false;
} else if (!drink.equals(other.drink))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
必须重写Person类中的equals和hashCode方法。下面是示例代码:
class Person {
private String name;
private String drink;
public Person(String name, String drink) {
super();
this.name = name;
this.drink = drink;
}
@Override
public int hashCode() {
return this.getName().hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof Person)) {
return false;
}
Person person = (Person) obj;
return person.getName().equals(this.name);
}
....getters and setters
....toString method
}
在此之后,如果您尝试运行您的代码,它将为我确保以下代码的输出是正确的
Map<Person, Integer> map = new HashMap<>();
for (Person p : persons)
{
if (map.containsKey(p)) {
map.put(p, map.get(p)+1);
} else {
map.put(p,1);
}
}
for(Map.Entry<Person, Integer> person : map.entrySet()){
System.out.println(person.getKey()+" "+person.getValue());
}
希望它能对您有所帮助。您必须重写Person类中的equals和hashCode方法。下面是示例代码:
class Person {
private String name;
private String drink;
public Person(String name, String drink) {
super();
this.name = name;
this.drink = drink;
}
@Override
public int hashCode() {
return this.getName().hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof Person)) {
return false;
}
Person person = (Person) obj;
return person.getName().equals(this.name);
}
....getters and setters
....toString method
}
在此之后,如果您尝试运行您的代码,它将为我确保以下代码的输出是正确的
Map<Person, Integer> map = new HashMap<>();
for (Person p : persons)
{
if (map.containsKey(p)) {
map.put(p, map.get(p)+1);
} else {
map.put(p,1);
}
}
for(Map.Entry<Person, Integer> person : map.entrySet()){
System.out.println(person.getKey()+" "+person.getValue());
}
希望它能帮助您。如果您可以使用Java 8 streams,这里有一个聪明的解决方案:
List<Person> people = Arrays.asList(new Person("Steve", "wine"), new Person("Steve", "cola"),
new Person("Ben", "cola"), new Person("Ben", "cola"), new Person("Steve", "wine"),
new Person("Steve", "wine"));
Map<Person, Long> map = people.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
然后代码如下所示:
Map<Person, Long> map = people
.stream()
.collect(groupingBy(identity(), counting()));
如果您可以使用Java 8 streams,这里有一个聪明的解决方案:
List<Person> people = Arrays.asList(new Person("Steve", "wine"), new Person("Steve", "cola"),
new Person("Ben", "cola"), new Person("Ben", "cola"), new Person("Steve", "wine"),
new Person("Steve", "wine"));
Map<Person, Long> map = people.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
然后代码如下所示:
Map<Person, Long> map = people
.stream()
.collect(groupingBy(identity(), counting()));
密钥在哈希映射或字典C中应该是唯一的。这种情况下,在插入密钥本身时需要将名称和名称结合起来。在这里用C给出解。希望能有帮助
public class Person
{
public string Name { get; set; }
public string Drink { get; set; }
}
class Program
{
static void Main(string[] args)
{
List<Person> persons = new List<Person>();
persons.Add(new Person() { Name = "Steve", Drink = "Tea" });
persons.Add(new Person() { Name = "Bell", Drink = "Milk" });
persons.Add(new Person() { Name = "Bell", Drink = "Milk" });
persons.Add(new Person() { Name = "Bell", Drink = "Milk" });
persons.Add(new Person() { Name = "Steve", Drink = "Milk" });
Dictionary<string, int> output = new Dictionary<string, int>();
foreach(var p in persons)
{
string key = p.Name + ":" + p.Drink;
if(output.ContainsKey(key))
{
output[key]++;
}
else
{
output.Add(key,1);
}
}
foreach(var k in output)
{
string[] split = k.Key.Split(':');
Console.WriteLine(string.Format("{0} {1} {2}", split[0],split[1],k.Value.ToString()));
}
}
}
密钥在哈希映射或字典C中应该是唯一的。这种情况下,在插入密钥本身时需要将名称和名称结合起来。在这里用C给出解。希望能有帮助
public class Person
{
public string Name { get; set; }
public string Drink { get; set; }
}
class Program
{
static void Main(string[] args)
{
List<Person> persons = new List<Person>();
persons.Add(new Person() { Name = "Steve", Drink = "Tea" });
persons.Add(new Person() { Name = "Bell", Drink = "Milk" });
persons.Add(new Person() { Name = "Bell", Drink = "Milk" });
persons.Add(new Person() { Name = "Bell", Drink = "Milk" });
persons.Add(new Person() { Name = "Steve", Drink = "Milk" });
Dictionary<string, int> output = new Dictionary<string, int>();
foreach(var p in persons)
{
string key = p.Name + ":" + p.Drink;
if(output.ContainsKey(key))
{
output[key]++;
}
else
{
output.Add(key,1);
}
}
foreach(var k in output)
{
string[] split = k.Key.Split(':');
Console.WriteLine(string.Format("{0} {1} {2}", split[0],split[1],k.Value.ToString()));
}
}
}
你在Person类中重写了hashCode和equals吗?你在Person类中重写了hashCode和equals吗?它可能是一个映射的副本,不是吗?不,不是,你有两个选择,1。使用字符串名称作为键。或2.使用Person作为键,但要覆盖Person类中的hashcode和equals方法。@请参见“请再次检查”,它已更新。请回复您的-1。您不是在更正,而是在否决一个答案。@SeelenVirtuse请检查第一句,它被更正了。所以如果你能把-1拿回去就更好了。重点是关于那个男人的名字和他的饮料。如果我只用他的名字,我想关于喝酒的信息就会丢失。这是一张地图,不是很好吗
嗯?不,不是,你有两个选择,1。使用字符串名称作为键。或2.使用Person作为键,但要覆盖Person类中的hashcode和equals方法。@请参见“请再次检查”,它已更新。请回复您的-1。您不是在更正,而是在否决一个答案。@SeelenVirtuse请检查第一句,它被更正了。所以如果你能把-1拿回去就更好了。重点是关于那个男人的名字和他的饮料。如果我只用他的名字,我想关于喝酒的信息会丢失。是的,现在它起作用了。谢谢我是Java编程新手,以前从未尝试过重写HashCode方法。我想这是一个很好的,更普遍的解决任何问题的方法。是的,现在它起作用了。谢谢我是Java编程新手,以前从未尝试过重写HashCode方法。我想这是一个很好的,更一般的解决任何问题的方法。非常好的解决方案,只需一行代码!但老实说,我不明白这行代码到底是怎么回事。非常好的解决方案,只需一行代码!但老实说,我不明白这行代码到底是怎么回事。你的价值是什么?我不知道这些人的名字,也不知道他们事先喝了什么。输入将是“Steve wine”,这不起作用,因为我不知道列表中有什么。假设这是酒保提供的信息,它只是一个文本文件示例。大约有200人在晚上喝东西。所以,我不能真正使用频率,因为我不知道喝过的饮料的名称。@Boris如果你要查找频率,那么你必须有任何输入属性才能获得计数。让我们在你们的例子中说,若调酒师正在寻找频率,那个么他应该知道饮料或饮酒者。即使你有数据文件,你也必须在任何集合中有数据。是的,也许这也是一个解决方案,让集合中的每个成员一个接一个地使用频率法。你说得对。谢谢。你的价值是什么?我不知道这些人的名字,也不知道他们事先喝了什么。输入将是“Steve wine”,这不起作用,因为我不知道列表中有什么。假设这是酒保提供的信息,它只是一个文本文件示例。大约有200人在晚上喝东西。所以,我不能真正使用频率,因为我不知道喝过的饮料的名称。@Boris如果你要查找频率,那么你必须有任何输入属性才能获得计数。让我们在你们的例子中说,若调酒师正在寻找频率,那个么他应该知道饮料或饮酒者。即使你有数据文件,你也必须在任何集合中有数据。是的,也许这也是一个解决方案,让集合中的每个成员一个接一个地使用频率法。你说得对。谢谢。这不是OP使用的语言——考虑到Java中的实现是不同的,这对他没有帮助。这不是OP使用的语言——考虑到Java中的实现是不同的,这对他没有帮助。