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

2022-08-31 05:28:35

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

类似的东西;

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

我知道上面的代码没有做任何事情,它只是粗略地演示了我试图实现的目标。

另外,为了澄清,我不想使用简单循环的原因是,此代码当前将进入循环内的循环,该循环位于循环内。为了便于阅读,我不想继续向这些循环添加循环。所以我想知道是否有任何简单的替代方案。


答案 1

如果您使用的是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();
}

如果 包含名为 .如果要对 每个 s 执行一个操作,那么您可以尝试如下操作:trueList<MyObject>MyObjectnameMyObjectgetName().equals(name)

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

其中 表示实例。oMyObject

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

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

答案 2

您有两种选择。

1. 首选是重写 Object 类中的 'equals()' 方法。

例如,假设您有以下 Object 类:

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

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

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

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

但是,在以下情况下,这可能不是您的选择:

  • 您同时使用名称和位置来检查是否相等,但您只想检查集合中是否有任何具有特定位置的“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;
    }

不幸的是,没有更好的方法可以解决这个问题。