首页 > 解决方案 > 对象的Java数组列表如何搜索元素错误

问题描述

我正在尝试使用 ArrayList 实现一个名为 Parade 的类,它将管理 Clown 类的实例。每个 Clown 都需要通过其名称、int id 和 double 大小的所有对象数据字符串来标识。我加入了一个新的小丑,直到游行结束。只有游行队伍前面的小丑(即第一个)可以离开游行队伍。此外,我编写了一个名为 isFront 的方法,该方法将 Clown 作为参数,如果传递的小丑在游行队伍的前面,则返回 true,否则返回 false。创建一个测试应用程序来演示如何构建由三四个小丑组成的游行队伍,并包含您自己的名字。然后,删除一两个,再添加一两个。此外,通过将不同的小丑传递给方法来测试 isFront 方法。

我有一个代码,但 isFront 方法没有返回 true,我正在尝试使用 contains 方法我也尝试使用 Comparable 接口 Clown,但效果不佳。不知道该怎么办。

import java.util.ArrayList;
public class Main
{
    public static void main(String[] args)
    {
        Parade circus = new Parade();

        circus.addClown(new Clown("Bobby",9,12.0));
        circus.addClown(new Clown("Clair", 2, 11.0));
        circus.addClown(new Clown("Tony",6,10.0));
        circus.addClown(new Clown("Sarah",3,5.0));
        circus.display();
        System.out.println(circus.isFront(new Clown("Bobby", 9, 12.0)));

    }

}
import java.util.ArrayList;
public class Parade
{
   private static ArrayList<Clown> parade;
   private int top;
   public Parade()
   {
      top=0;
      parade= new ArrayList<Clown>();
      System.out.println(parade);

   }
   public void addClown(Clown c)
   {
     parade.add(c);
     top++;
   }
   public void removeClown()   //(Clown c)
   {
     parade.remove(0);
     top--;
   }
   public void display()
   {
     System.out.println(parade);
   }
   public void getData()
   {
      parade.get(0);
   }
   public void setData()
   {
      parade.set(1,new Clown("Claire",2,5.0));
      System.out.println(parade);
   }
   public int getTop()
   {
      return top;
   }
   public boolean isFront(Clown c)
   {
      return !parade.isEmpty() && c.equals(parade.get(0));
   }

   //exceptions
}

public class Clown
{
    private String name;
    private int id;
    private double size;

    public Clown(String name, int id, double size)
    {
        this.name=name;
        this.id=id;
        this.size=size;
    }
    public String getName()
    {
        return name;
    }
    public int getId()
    {
        return id;
    }
    public double getSize()
    {
        return size;
    }
    public String toString()
    {
        return name.toString() + id + size;
    }
    public boolean equals(Object o) {
        if (o instanceof Clown c) {
            return this.getName().equals(c.getName()) && this.getId() == c.getId() && this.getSize() == c.getSize();
        }
        return false;
    }

}

他们在我们的教科书中没有太多关于Java FOundations 5th e Lewis之类的东西的信息,比如处理对象和数组列表,它会跳过它并假设你已经知道它了,哈哈。

标签: javaobjectsearcharraylistcollections

解决方案


首先,默认情况下,Java 中的对象通过引用进行比较。因此,即使您创建了两个Clown具有完全相同属性的对象,Java 也会将它们视为不同的对象,因为这两个对象引用并不相同,它们都引用了不同的内存位置。您可以覆盖此行为并要求 Java 通过覆盖类的equals()方法来根据需要进行比较Object

public class Clown {
    private String name;
    private int id;
    private double size;

    public Clown(String name, int id, double size) {
        this.name=name;
        this.id=id;
        this.size=size;
    }
    public String getName() {
        return name;
    }
    public int getId() {
        return id;
    }
    public double getSize() {
        return size;
    }
    @Override
    public boolean equals(Object o) {
        if (o instanceof Clown) {
             Clown c = (Clown) o;
             return this.getName().equals(c.getName());
        } 
        return false;
    }
    @Override
   public int hashCode() {
        return this.getId();
    }
    @Override
    public String toString() {
        return name.toString() + id + size;
    }
}

这将有助于contains()(它在内部使用equals())。其次,您可以将您的小丑与第一个小丑进行比较,看看它是否是最前面的那个:

public boolean isFront(Clown c) {
    return !parade.isEmpty() && c.equals(parade.get(0));
}

如果队列不为空并且小丑等于队列中的第一个小丑,则该isFront()方法将返回。找回游行队伍中的第一个小丑。根据您的评论,如果您希望两个小丑只有在它们的所有属性都相等时才相等,请将您的 equals 方法更改为:truecget(0)

@Override
public boolean equals(Object o) {
   if (o instanceof Clown) {
         Clown c = (Clown) o;
         return this.getName().equals(c.getName()) &&
                this.getId() == c.getId()          &&
                this.getSize() == c.getSize();
    } 
    return false;
}

equals()方法属于Object所有Java类的父类。它定义了如何比较两个对象。其签名如下:

    public boolean equals(Object obj) 

当我们重写时,它的签名在派生类中必须相同,在我们的例子中是 class Clown。它的参数是Objectnot类型ClownObject如果我将对象Clown与另一种类型进行比较,任何类型都可以转换为,例如:

Clown c = new Clown("X", 1, 10);
 if ( c.equals(objectOfAnotherType) ) {..}

它仍然可以工作。所以我们使用instanceof运算符来检查另一个对象是否也是Clown. 如果它不是 的实例Clown,我们返回,false但如果是,我们将该对象转换/强制转换为Clown,只有这样我们才能调用getName()和其他 getter 方法:

if (o instanceof Clown) {
         Clown c = (Clown) o; //Casting happens here
         return this.getName().equals(c.getName()) &&
                this.getId() == c.getId()          &&
                this.getSize() == c.getSize();
    } 
    return false;

Java 14 为此引入了一个快捷方式,而不是这些步骤:

if (o instanceof Clown) {
         Clown c = (Clown) o;

我们可以简单地写:

if (o instance of Clown c)

它为我们进行铸造并将其存储在c.

最后,我也覆盖Object.hashCode()了,因为当你覆盖时你必须这样做equals(),这就是为什么


推荐阅读