我在这里看到了很多关于如何使用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 wine 2
我的想法是创建一个对象Person(String name,String drink)。然后我将所有人都放到ArrayList中。之后我创建了HashMap,并希望在键不存在的情况下添加一个新Person,如果key已经存在则增加到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);
}
}
它不起作用。它只返回我的结果:
Steve wine 1
Steve cola 1
Ben cola 1
Frank wine 1
Ben cola 1
Ben cola 1
Frank wine 1
所以,据我所知,这应该是其他一些技巧。也许你还可以告诉任何其他关于如何计算饮料杯数而不是使用HashMap的想法? 非常感谢!
答案 0 :(得分:7)
在Person类
中覆盖hashcode和equals方法答案 1 :(得分:5)
如果您可以使用Java 8流,这是一个聪明的解决方案:
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()));
修改: 要减少代码,您可以静态导入方法,如下所示:
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.counting;
import static java.util.function.Function.identity;
然后代码看起来像这样:
Map<Person, Long> map = people
.stream()
.collect(groupingBy(identity(), counting()));
答案 2 :(得分: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);
}
}
答案 3 :(得分:1)
在人类中覆盖等于和 hascode 方法是解决您问题的方法。
假设你有Person类参数 name 和 drink ,那么你可以使用像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;
}
}
答案 4 :(得分:1)
您必须在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 [name=Steve, drink=wine] 2
Person [name=Ben, drink=cola] 3
Person [name=Frank, drink=wine] 2
希望它会对你有所帮助。
答案 5 :(得分:1)
键在哈希映射或字典(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()));
}
}
}
答案 6 :(得分:0)
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"));
答案 7 :(得分:0)
首先,我建议你照顾好自己的名字。在你的情况下,真正的关键是订单不是一个人(因为史蒂夫可乐和史蒂夫葡萄酒不同,你不应该把它命名为人)。
之后:containsKey将使用hashcode方法,如果你不在类中覆盖它,它将从Object类继承。 Object类的哈希码可能会为您的实例提供不同的哈希码,因此您应该在类中覆盖它,例如如果您连接名称和饮料(这是订单的唯一标识符)并在该字符串上调用哈希码方法,则可以创建可接受的哈希码方法。