使用添加方法

时间:2019-07-01 12:21:00

标签: java arraylist

我有两个类,一个类名为Bird,另一个名为Runtime。鸟类创建鸟-名称,拉丁名称。 Runtime类有4种方法,只有一个对这个问题很重要,即'add'方法。调用add方法时,需要从用户那里获取名称和拉丁名称的输入,它们被保存到字符串变量“ name”和“ latin name”中,我调用Bird类构造函数并将这些字符串变量传递给它参数,最后将其添加到ArrayList中。但是,如果我要写两次相同的鸟,我会得到重复的值。

我试图将ArrayList转换为集合,然后再次将其转换回ArrayList,我在add方法中做到了这一点,但这没有用。我怀疑这归因于我对如何将对象存储在ArrayList中的理解不足。我还在Bird类中创建了一个getName方法,因此我可以使用list.get(i).getName,如果名称等于用户键入的名称,它将相应地提示用户,如果没有,则将其添加到我的ArrayList中。这也没有用。我还尝试了一个遍历ArrayList的for循环,并且if语句将确定ArrayList中是否存在用户键入的名称,这也行不通,尝试还很早,所以我不记得确切的错误了消息,但是add方法是从while循环中调用的,我认为错误消息是并发修改,我不确定,因此请忽略这一点,我的意思是展示了我尝试过的各种解决方案。

下面是The Bird类

    public class Bird{

       int obeservation = 0;
       String name;
       String latinName;

       public Bird(String name, String latinName){
         this.name = name;
         this.latinName = latinName;
       }

       public void addBird(String name, String latinName){
         this.name = name;
         this.latinName = latinName;
       }

       public String getName(){
         return this.name;
       }

       public String statistics(){
         return this.name + " (" + this.latinName + ") : " +         
         this.obeservation + " observation";
       }
   }

下面是运行时类

    public class Runtime {

        ArrayList<Bird> birds = new ArrayList<Bird>();

        Scanner scan = new Scanner(System.in);

        public void scan() {
            System.out.println("?");
            String answer = scan.nextLine().trim();
            while (!answer.equalsIgnoreCase("EXIT")) {
              System.out.println("?");
              answer = scan.nextLine().trim().toUpperCase();
            if (answer.equalsIgnoreCase("ADD")) {
                add();
            } else if (answer.equalsIgnoreCase("OBSERVATION")) {
                observation();
            } else if (answer.equalsIgnoreCase("STATISTICS")) {
                System.out.println("jhjh");//just to see if this is     
                working
                statistics();
            } 
        }
    }

下面是add方法,我也评论了尝试, 当前,add方法没有if语句来确定重复项。

    public void add() {

         System.out.print("Name: ");
         String name1 = scan.nextLine().trim().toUpperCase();

         System.out.print("Latin Name: ");
         String latinName1 = scan.nextLine().trim().toUpperCase();

         birds.add(new Bird(name1, latinName1));


         /*
         Bird newBird = new Bird(name1, latinName1);

         for (int i = 0; i < birds.size(); i++) {
             if (birds.get(i).getName().equals(name)) {
                 System.out.println("Bird already exist");
                 return;
             } else {
                 birds.add(newBird);
             }
         }
         /*
          * hBirds.addAll(birds); birds = new ArrayList<Bird>();     

        birds.addAll(hBirds);
            * 
            * // Bird newBird = new Bird(name, latinName); 
            * /* if(birds.contains(name)){
            * System.out.println("That name already exist"); 
            * return; 
            * }else{ 
            * birds.add(newBird(name, latinName));
            * 
            * }
            */
     } 

statistics方法打印出ArrayList,遍历ArrayList的foreach循环将其打印出来。如果我两次输入海鸥,则预期结果应该是一个海鸥值而不是两个。我如何拒绝重复的物品?

2 个答案:

答案 0 :(得分:3)

您可以在此处使用两种方法:

  • 第一:遍历ArrayList,如果找不到同一只鸟,请将其添加到ArrayList。这是一种更糟糕的方法。

  • 第二个:将鸟类存储在HashSet中。在这种情况下,您需要覆盖.hashCode().equals(Object obj)方法。这是一种更好的方法。

在讨论如何生成.hashCode().equals(Object obj)方法之前,我想先介绍一下.hashCode()方法和HashSet<T>

HashSet<T>在其中提供了一组独特的元素。为此,使用了类的.hashCode()方法。如果您在任何类中都覆盖.hashCode()方法,则可以获得使用HashSet<T>的好处。如果不重写此方法,Java将自动返回对象的内存地址。这就是为什么您的HashSet<Bird>包含重复的元素。

.hashCode().equals()方法可以由许多IDE生成。我将您的Bird类复制并粘贴到Eclipse。通过将Alt+Shift+S -> h用于Eclipse或将Alt+Insert -> equals() and hashCode()用于IntelliJ,将自动生成以下方法:

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((latinName == null) ? 0 : latinName.hashCode());
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    result = prime * result + obeservation;
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Bird other = (Bird) obj;
    if (latinName == null) {
        if (other.latinName != null)
            return false;
    } else if (!latinName.equals(other.latinName))
        return false;
    if (name == null) {
        if (other.name != null)
            return false;
    } else if (!name.equals(other.name))
        return false;
    if (obeservation != other.obeservation)
        return false;
    return true;
}

如果将这些方法(建议您在IDE中生成)添加到Bird类,则可以使用HashSet<Bird>。为避免重复,只需将所有Bird对象添加到已定义的HashSet<Bird>中。您不需要任何其他数据结构或相等性检查来控制任何两个Bird类型的对象是否相等。

您只需要将对象集合从ArrayList<Bird> birds = new ArrayList<Bird>();更改为Set<Bird> birds = new HashSet<>();

答案 1 :(得分:-1)

add移出循环:

    for (int i = 0; i < birds.size(); i++) {
        if (birds.get(i).getName().equals(name1)) {
            System.out.println("Bird already exist");
            return;
        }
    }
    birds.add(new Bird(name1, latinName1));