我有两个类,一个类名为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循环将其打印出来。如果我两次输入海鸥,则预期结果应该是一个海鸥值而不是两个。我如何拒绝重复的物品?
答案 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));