【问题标题】:Remove object from Arraylist If it equals userinput and else print out something only once从 Arraylist 中删除对象如果它等于用户输入,否则只打印一次
【发布时间】:2018-05-25 05:20:28
【问题描述】:

我现在一直在尝试大多数事情,但它似乎不起作用。如果用户输入特定名称,我想从 Arraylist 中删除特定对象。如果不是,我希望程序打印“找不到狗”。我在我的其他类中有一个 getName 和 toString 方法,它与我在这个程序中的所有其他选项配合得很好,这是唯一不起作用的东西。

案例 4 是应该进行移除的地方。但是我也想让你看一下案例 3,比较一下案例 3 无论如何都打印出“找不到狗”,而案例 4 打印出“找不到狗”的次数与有物体一样多。

这里是主要方法:

ArrayList<Dog> doglist = new ArrayList<Dog>();
Scanner myscan = new Scanner(System.in);
boolean running = true;

while (running) {
    System.out.println("\n************************************");
    System.out.println("\nVälkommen till Kennelklubben!");
    System.out.println("\n************************************");
    System.out.println("\n[1] Register new dog");
    System.out.println("[2] Print out list");
    System.out.println("[3] Increase age");
    System.out.println("[4] Remove dog");
    System.out.println("[5] Quit program");
    System.out.println("\n************************************");
    System.out.println("\nChoose: ");

    int option = myscan.nextInt();

    switch (option) {
        case 1:
            System.out.println("Write name:");
            String name = myscan.next();
            System.out.println("Write race:");
            String race = myscan.next();
            System.out.println("Age:");
            int age = myscan.nextInt();
            System.out.println("Weight:");
            double weight = myscan.nextDouble();

            Dog dog = new Dog(name, race, age, weight);

            doglist.add(dog);

            break;
        case 2:
            System.out.println("Minimum length of tail:");
            double userInput1 = myscan.nextDouble();

            for (Dog d : doglist) {
                if (d.getTailLength() >= userInput1) {
                    System.out.println(d.toString());
                } else {
                    System.out.println("Can't find dog");
                }
            }
            break;
        case 3:
            System.out.println("Name of dog:");
            String userInput2 = myscan.next();

            for (Dog d : doglist) {
                if (d.getName().equals(userInput2)) {
                    d.increaseAge();
                    break;
                }
            }
            System.out.println("Can't find dog");
            break;
        case 4:
            System.out.println("Name of dog:");
            String userInput3 = myscan.next();
            for (Dog d : doglist) {
                if (d.getName().equals(userInput3)) {
                    doglist.remove(d.toString());
                } else {
                    System.out.println("Can't find dog");
                }
            }
            break;
        case 5:
            running = false;//Avslutar loopen och därmed programmet
            System.out.println("Programmet avslutat");
            break;
        default:
            System.out.println("Nu blev det fel, välj mellan [1] [2] [3] [4] [5]");//Felmeddelande om valet är någon annan siffra än de som menyn innehåller
            break;
    }
}

这是我的方法的另一个类

public class Dog
{
    private String name;
    private String race;
    private int age;
    private double weight;
    private double tailLength;

    public Dog (String name, String race, int age, double weight)
    {
        this.name = name;
        this.setRace(race);
        this.age = age;
        this.weight = weight;

        if(race.equals("tax"))
        {
            this.setTailLength(3.7);
        }
        else
        {
            this.setTailLength((age - weight) / 10);
        }
    }


    public String getRace()
    {
        return race;
    }

    public void setRace(String race)
    {
        this.race = race;
    }

    public double getTailLength()
    {
        return tailLength;
    }

    public void setTailLength(double tailLength)
    {
        this.tailLength = tailLength;
    }

    public int increaseAge()
    {
        age++;
        return age;
    }

    public String toString()
    {
        return name + " " + getRace() +
                " " + age + " " + "år" + " " + weight + " " + "kg" + " " + getTailLength();
    }

    public String getName()
    {
        return name;
    }
}

【问题讨论】:

  • 您即将遇到一个名为ConcurrentModificationException 的令人讨厌的异常。当您遍历列表并尝试同时从列表中删除项目时会发生这种情况
  • 在情况 4 中不能按名称删除
  • 该列表中是否可以有多只同名的狗?
  • @smac89 好的,我明白了,但是如果我想按名称删除对象,我该怎么做?
  • @smac89 这是可能的,但我们可以假设现在还不行,如果这会让事情变得更容易?

标签: java for-loop arraylist remove-if


【解决方案1】:

为清楚起见,以下是您目前拥有的:

            System.out.println("Name of dog:");
            String userInput3 = myscan.next();

            for(Dog d : doglist) 
            {
                if(d.getName().equals(userInput3)) 
                {
                    doglist.remove(d.toString());
                }
                else
                {
                    System.out.println("Can't find dog");
                }
            }

            break;

dogListArrayList&lt;Dog&gt;

ArrayList.remove()documentation states

从该列表中删除第一次出现的指定元素(如果存在)。如果列表不包含该元素,则保持不变。

在这里,您使用参数d.toString() 调用remove()d 是您要删除的 Dog 实例。 d.toString() 返回一个 String

所以dogList.remove(d.toString()) 将尝试从列表中删除String。显然这个String 不在列表中,因为它是Dog 的列表。将找不到此 String,也不会删除任何内容。

如文档所述,您需要传递要删除的实例。您需要致电doglist.remove(d)。但是,这会导致错误,因为您在迭代列表时无法从列表中删除项目。

因此,您需要将Dog 实例存储在一个临时变量中,并在对其进行迭代后将其删除。

这样的事情会起作用:

Dog dogToRemove = null;
for (Dog d: dogList) {
    if (d.getName().equals(userInput3)) {
        dogToRemove = d;
    }
}

if (dogToRemove == null) {
    System.out.println("Could not find dog with name " + userInput3);
} else {
    dogList.remove(dogToRemove);
}

请注意,还有其他方法可以做到这一点,这只是其中一种。我鼓励您寻找替代方案,以便您了解如何更好地工作。

【讨论】:

  • 非常感谢!!这行得通,我想我现在明白了,但我会更多地研究这样的事情,但是谢谢!
【解决方案2】:

对于案例 3:

  • 尝试添加一个 else 并在那里输入您的消息

            System.out.println("Name of dog:");
            String userInput2 = myscan.next();
    
            for (Dog d : doglist) {
                if (d.getName().equals(userInput2)) {
                    d.increaseAge();
                    break;
                }
                else {
                    System.out.println("Can't find dog");
                }
            }
    
            break;
    

对于案例 4:您可以按索引删除

System.out.println("Name of dog:");
            String userInput3 = myscan.next();
            for (Dog d : doglist) {
                if (d.getName().equals(userInput3)) {
                    doglist.remove(doglist.indexOf(d));
                } else {
                    System.out.println("Can't find dog");
                }
            }
            break;

【讨论】:

  • 很遗憾,即使找到了狗并增加了年龄,它仍然打印出“找不到狗”?
  • 打印一次“找不到狗”?
  • 是的 :) 无论如何打印一次
  • 您确定您确实删除了循环外的 Sysout 吗?
  • 试试这个代码:case 3: System.out.println("Name of dog:"); String userInput2 = myscan.next(); int flag = 0; for(Dog d : doglist) { if(d.getName().equals(userInput2)) { d.increaseAge(); flag = 1; break; } } if (flag == 0){ System.out.println("Can't find dog with name:" + userInput2); } break;
【解决方案3】:

使用 Java 8 有更好的方法。

doglist = doglist.stream().filter(dog -> !dog.getName().equals(userInput3)).collect(toList());

一行代码,易读,无活动部件

如果你想要一条消息,如果没有找到狗,那么:

if (doglist.stream().anyMatch(dog -> dog.getName().equals(userInput3)){
  doglist = doglist.stream().filter(dog -> !dog.getName().equals(userInput3)).collect(toList());
} else {
   System.out.println("Can't find dog");
}

【讨论】:

  • 不错的一个班轮,但如果你可以添加一种方法来确定是否找到了狗,那将完成这个答案
  • 编辑添加 if 语句,当找不到狗时输出
猜你喜欢
  • 2014-02-06
  • 2016-11-03
  • 2017-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-14
  • 1970-01-01
相关资源
最近更新 更多