如果对象在 ArrayList 中,我该如何更改它?

How can I change an object if it is in an ArrayList?

我有一个狗的数组列表。如果 Fluffy 在 ArrayList 中,我想将其名称更改为 Fido。如果不在ArrayList中,我想添加,然后改名为Fido。

所以我可以检查 Fido 是否存在于 ArrayList 中,但我如何检索它以便进行更改?以下是我最接近的。我正在寻找符合 dogs.getElementEqualTo(new Dog("Fido"));

的内容
import java.util.ArrayList;

public class Dog {

    public static void main(String[] args) {
        ArrayList<Dog> dogs = new ArrayList<>();
        dogs.add(new Dog("Fido"));
        Dog dog = new Dog("Fido");
        if (dogs.contains(dog)) {
            dog.name = "Fluffy";
        }
        System.out.println(dogs.get(0).name); //prints Fido
    }

    String name;

    public Dog(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Dog)) return false;

        Dog dog = (Dog) o;

        return !(name != null ? !name.equals(dog.name) : dog.name != null);
    }

    @Override
    public int hashCode() {
        return name != null ? name.hashCode() : 0;
    }
}

编辑:

我尝试将我的主要方法更改为此,但它不起作用:

ArrayList<Dog> dogs = new ArrayList<>();
dogs.add(new Dog("Fido"));
Dog dog = new Dog("Fido");
if (dogs.contains(dog)) {
    dogs.get(dogs.indexOf(dog)).name = "Fluffy";
}
System.out.println(dogs.get(0).name);

您可以使用以下方式获取 Fido 的(第一个)索引:

int indexOfFido = dogs.indexOf(new Dog("Fido"));

然后使用以下方法检索元素:

dogs.get(indexOfFido);

但是,根据您使用的 List 的具体实现,遍历列表可能更有效:

Dog fido = new Dog("Fido");
for (Dog dog : dogs) {
  if (fido.equals(dog)) {  // Do the comparison this way round, since
                           // elements of list can be null in general.
    // Do whatever.
    break;  // Unless you want to do the same to all instances of Fido.
  }
}
boolean found = false;
for(Dog a : dogs) {
    if(a.name.equals("Fluffy") {
        a.name = "Fido";
        found = true;
}

if(!found) {
    dogs.add(new Dog("Fido"));
}

我不完全确定你的 Dog 对象在内部是如何工作的,我的回答是基于 Dog class 是这样的想法:

public static String name;
public Dog(String name) {
    this.name = name;
}

if (dogs.contains(dog)) 的计算结果如您所愿,但您修改的是局部变量 dog 而不是 ArrayList[=17 中的 Dog 对象=]

改变

dog.name = "Fluffy";

dogs.get(dogs.indexOf(dog)).name = "Fluffy";

你会得到你想要的结果。

public static void main(String[] args) throws Exception {
    ArrayList<Dog> dogs = new ArrayList<>();
    dogs.add(new Dog("Fido"));
    Dog dog = new Dog("Fido");
    if (dogs.contains(dog)) {
        dogs.get(dogs.indexOf(dog)).name = "Fluffy";
    } else {
        dogs.add(dog);
    }

    System.out.println(dogs.get(0).name); //prints Fido
}

如果您使用 Java 8,您可以在 List 流上使用 filter,然后按顺序使用 findAny,最后 ifPresent

这是一个简单的例子:

public static void main(String[] args) {
    List<Thing> things = new ArrayList<>();
    things.add(new Thing("thing one"));
    things.add(new Thing("thing two"));
    System.out.println(things);
    things.stream().filter(t -> t.toString()
            .contains("one"))
            .findFirst()
            .ifPresent(t -> t.setName("three"));
    System.out.println(things);
}

public static class Thing{
    private String name;
    public Thing(String s){name=s;}
    public String toString(){return "Thing{name="+name+"}";}
    public void setName(String s){ name = s;}
    public int hashcode(){return name.hashCode();}
    public boolean equals(Object o){
        return o != null && this.toString().equals(o.toString());
    }
}

和输出

[Thing{name=thing one}, Thing{name=thing two}]
[Thing{name=three}, Thing{name=thing two}]

请注意第一个元素已更改。