Java List.contains(字段值等于 x 的对象)

新手上路,请多包涵

我想检查 List 是否包含一个具有特定值的字段的对象。现在,我可以使用循环进行检查,但我很好奇是否有更高效的代码。

就像是;

 if(list.contains(new Object().setName("John"))){
    //Do some stuff
}

我知道上面的代码没有做任何事情,它只是为了大致展示我想要实现的目标。

另外,为了澄清,我不想使用简单循环的原因是因为此代码当前将进入循环内部的循环内部循环内部。为了可读性,我不想继续向这些循环添加循环。所以我想知道是否有任何简单的(ish)替代品。

原文由 Rudi Kershaw 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 707
2 个回答

如果您使用的是 Java 8,也许您可以尝试以下方法:

 public boolean containsName(final List<MyObject> list, final String name){
    return list.stream().filter(o -> o.getName().equals(name)).findFirst().isPresent();
}

或者,您可以尝试这样的事情:

 public boolean containsName(final List<MyObject> list, final String name){
    return list.stream().map(MyObject::getName).filter(name::equals).findFirst().isPresent();
}

此方法将返回 true 如果 List<MyObject> 包含一个 MyObject 名称为 name 如果你想对每个 MyObject s that getName().equals(name) 执行操作,那么你可以尝试这样的事情:

 public void perform(final List<MyObject> list, final String name){
    list.stream().filter(o -> o.getName().equals(name)).forEach(
            o -> {
                //...
            }
    );
}

其中 o 代表 MyObject 实例。

或者,正如评论所建议的(感谢 MK10),您可以使用 Stream#anyMatch 方法:

 public boolean containsName(final List<MyObject> list, final String name){
    return list.stream().anyMatch(o -> name.equals(o.getName()));
}

原文由 Josh M 发布,翻译遵循 CC BY-SA 4.0 许可协议

你有两个选择。

1. 第一种选择是覆盖 Object 类中的 `equals()` 方法,这是更好的选择。

比方说,你有这个 Object 类:

 public class MyObject {
    private String name;
    private String location;
    //getters and setters
}

现在假设您只关心 MyObject 的名称,它应该是唯一的,因此如果两个 MyObject 具有相同的名称,则它们应该被视为相等。在这种情况下,您可能希望覆盖 `equals()` 方法(以及 `hashcode()` 方法),以便它比较名称以确定是否相等。

完成此操作后,您可以检查 Collection 是否包含名为“foo”的 MyObject,如下所示:

 MyObject object = new MyObject();
object.setName("foo");
collection.contains(object);

但是,如果出现以下情况,这可能不适合您:

  • 您同时使用名称和位置来检查是否相等,但您只想检查 Collection 是否有任何具有特定位置的 MyObject。在这种情况下,您已经覆盖了 `equals()`。
  • `MyObject` 是您无权更改的 API 的一部分。

如果是上述任何一种情况,您将需要选项 2:

2. 编写自己的实用方法:

 public static boolean containsLocation(Collection<MyObject> c, String location) {
    for(MyObject o : c) {
        if(o != null && o.getLocation.equals(location)) {
            return true;
        }
    }
    return false;
}

或者,您可以扩展 ArrayList(或其他一些集合),然后向其中添加您自己的方法:

 public boolean containsLocation(String location) {
    for(MyObject o : this) {
        if(o != null && o.getLocation.equals(location)) {
                return true;
            }
        }
        return false;
    }

不幸的是,没有更好的解决方法。

原文由 James Dunn 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题