我有一个Foo对象列表。如果名称多次出现,我想对具有该名称的第一个项目执行某些操作。
HashMap<String, Foo> map = new HashMap<String, Foo>();
for (Foo bar: this.FooList)
{
if (!map.containsKey(bar.getName()))
{
map.put(bar.getName(), bar);
}
else
{
map.get(bar.getName()).doSomeThing();
}
}
但是这不起作用,因为每个名称(唯一的或不是唯一的)都会被抛出。 HashMap是否仅检查引用相等性而不检查关键对象上的相等性?
答案 0 :(得分:3)
这是您需要的代码:
HashMap<String, Foo> map = new HashMap<String, Foo>();
for (Foo bar: this.FooList)
{
if (!map.containsKey(bar.getName()))
{
map.put(bar.getName(), bar);
}
else
{
Foo foo = map.get(bar.getName());
if (foo != null)
foo.doSomeThing();
map.put(bar.getName(), null);
}
}
这是一个测试床:
import java.util.HashMap;
import java.util.ArrayList;
public class Example
{
public static void main(String[] args)
{
new Example().run();
}
private ArrayList<Foo> FooList = new ArrayList<Foo>();
public void run()
{
FooList.add(new Foo("abc", 1));
FooList.add(new Foo("abc", 2));
FooList.add(new Foo("def", 3));
FooList.add(new Foo("abc", 4));
FooList.add(new Foo("abc", 5));
FooList.add(new Foo("ghi", 6));
FooList.add(new Foo("def", 7));
HashMap<String, Foo> map = new HashMap<String, Foo>();
for (Foo bar: this.FooList)
{
if (!map.containsKey(bar.getName()))
{
map.put(bar.getName(), bar);
}
else
{
Foo foo = map.get(bar.getName());
if (foo != null)
foo.doSomeThing();
map.put(bar.getName(), null);
}
}
}
class Foo
{
public Foo(String name, int i)
{
this.name = name;
this.i = i;
}
public String getName()
{
return name;
}
public void doSomeThing()
{
System.out.println(getName() + " " + i);
}
private String name;
private int i;
}
}
输出是:
abc 1
def 3
答案 1 :(得分:1)
嗯...如果Foo实现equals()
以便它只检查名称,你总是可以这样做:
Set<Foo> set = new HashSet<Foo>();
for (Foo bar: this.FooList)
{
if (!set.add(bar)) {
bar.doSomething();
}
}
哪个有效,因为set.add(bar)
将针对集合中已有的每个元素运行bar.equals
,如果其中任何元素相等则返回false。
编辑:由于这是一个HashSet,您还应该实现hashCode()
。哎呀,如果你无论如何都要覆盖hashCode()
,你应该始终实施equals
。
答案 2 :(得分:0)
究竟是什么问题?如果以前没有遇到过,则代码会添加Foo
,如果之前遇到过,则会在Foo
上调用操作。你有什么期望呢?
要在最后回答您的问题,HashMap
依赖于关键对象的hashCode
和equals
方法。
更新:您是否尝试仅在重复的doSomeThing
上调用Foo
?如果name
的{{1}}属性定义了它的身份(并且您正确实施了Foo
和hashCode()
),则应使用R. Bemrose's solution。如果equals()
不是name
的唯一属性,则以下代码可能有所帮助:
Foo
答案 3 :(得分:0)
HashMap在密钥对象上使用.equals()方法。