我有一个关于java中的"contains"方法的问题。我有一个对象 Tile,其中包括 int x、int y(坐标)和字符串。我想将对象添加到队列中,没有重复项。当我说重复时,我的意思是坐标。我不在乎字符串。
但是当我写这样的东西时:
for (Tile x : neighbours)
{
if (!queue.contains(x))
queue.add(x);
}
它是全部相加,我的猜测是他看到一个参数不相等(字符串)正因为如此,他把X放在队列中。
你知道我如何仅根据坐标将新对象放入队列中吗?两个坐标相同但字符串不同的对象对我来说是同一个对象。
谢谢。。。
若要检查与属性匹配的元素,但不相等,使用循环可能是最简单的方法。但是,如果要使用单个方法,可以将 lambda 作为谓词传递给 anyMatch
:
for (Tile x : neighbours) {
if (!queue.stream().anyMatch(t -> x.x == t.x && x.y == t.y)) {
queue.add(x);
}
}
我已经做了这个功能。 我虽然有一个短暂的"魔法"。
public static boolean containsCoordinates (LinkedList<Tile> queue, Tile obj)
{
for (Tile queueTile : queue)
{
if (queueTile.getX()==obj.getX())
{
if (queueTile.getY()==obj.getY())
return true;
}
}
return false;
}
无论如何,谢谢....
如果你想使用一些"魔法",那么你可以考虑以下测试:
for (Tile x : neighbours) {
if (!queue.contains(new Object() {
public boolean equals(Object t) {
return x.x == ((Tile) t).x && x.y == ((Tile) t).y;
}
})) {
queue.add(x);
}
}
我不会将给定的 Tile t
传递给 contains
方法,而是传递具有重写equals
方法的Object
实例。这有效,因为contains
接受任何类型的对象。
然而,从程序逻辑来看,这个版本等同于@Joe给出的答案
来自 java.util.Collection 的文档(它定义了 contains
方法,它是 Queue 的超级接口):
boolean contains(Object o)
如果此集合包含指定的元素,则返回 true。更正式地说,当且仅当此集合包含至少一个元素时返回 true,
e
使得(o==null ? e==null : o.equals(e))
.
因此,请覆盖Title
的equals
方法以满足您的需求。 例如
class Tile {
...
@Override
public boolean equals(Object o) {
if (o == null || !(o instanceof Title)) {
return false;
}
if (this == o) {
return true;
}
return this.x == o.x && this.y == o.y;
}
...
}
像Eclipse或IntelliJ Idea这样的IDE能够生成equals
和hashCode
方法(当你覆盖一个方法时,你也应该始终覆盖另一个方法)。