java - 不允许在数组列表中重复对象
问题描述
我目前正在用 Java 开发一个家庭仇恨游戏。我有一个名为 questions 的对象问题的数组列表,它存储随机问题以在整个游戏中使用。我正在尝试以确保没有重复项的方式填充数组列表,但是它不起作用并且我得到了重复项。
初始化为一个字段是我的问题数组列表:
private ArrayList<Question> questions = new ArrayList<>();
这是我目前正在尝试的:
//Populates questions list
for(int i=0; i<15; i++)
{
Question q = new Question();
//makes sure there are no duplicates
if(!questions.contains(q))
questions.add(q); //not working for some reason cry
System.out.println(q.getQuestion());
}
当我打印出问题时,我仍然得到重复:
Name something you would see on the Jerry Springer show:
Name something that would get you thrown out of most bars:
What accent might an American pretend to have in order to sound more attractive:
Name a breed of dog that might be used as a guard dog:
Name a place where a child might get seperated from its parents:
Name something you would see on the Jerry Springer show:
Name something that would get you thrown out of most bars:
Name a place where a child might get seperated from its parents:
Name something for which you need a warranty:
Name a game that would be inappropriate at a company party:
Name something for which you need a warranty:
Name a place where a child might get seperated from its parents:
Name an activity that could be rained out:
Name something for which you need a warranty:
Name something that would get you thrown out of most bars:
我确实在我的问题类中覆盖了 equals 方法,但它并没有起到作用。这是我的问题课:
/**
* Question proposed to players to guess one of the answers on the board
*
* Each question has 5 possible answers
*
* The top answer to each question is stored at Answers(0) and is worth the most
* The last answer is stored at Answers(4) and is worth the least
*
*
* @author Stefan Gligorevic
*/
import java.util.ArrayList;
import java.util.Random;
import java.lang.String;
import java.lang.Object;
public class Question {
private ArrayList<Answer> answers;
private String question;
/**** MIGHT HAVE TO INITIALIZE ANSWERS TO AN ARRAY LIST WITH NO SIZE SO ADD CAN WORK ****/
//constructors
public Question(){
answers = new ArrayList<>();
question=getRandomQuestion();
}
//makes a random question with a set of answers
public String getRandomQuestion() {
String ask = "";
Random rand = new Random();
int n = 1 + rand.nextInt(10);
switch (n)
{
case 1:
ask="Name a place where a child might get seperated from its parents:";
answers.add(new Answer("Mall", 38));
answers.add(new Answer("Park", 23));
answers.add(new Answer("Zoo", 16));
answers.add(new Answer("Theme Park", 16));
answers.add(new Answer("Airport", 5));
break;
case 2:
ask="Name something for which you need a warranty:";
answers.add(new Answer("Car", 54));
answers.add(new Answer("TV", 23));
answers.add(new Answer("Watch", 8));
answers.add(new Answer("Computers", 4));
answers.add(new Answer("Appliance", 3));
break;
case 3:
ask="Name a fruit you can buy dried:";
answers.add(new Answer("Grape", 22));
answers.add(new Answer("Banana", 21));
answers.add(new Answer("Apricot", 21));
answers.add(new Answer("Prune", 17));
answers.add(new Answer("Apple", 15));
break;
case 4:
ask="Name an activity that could be rained out:";
answers.add(new Answer("Sports Event", 45));
answers.add(new Answer("Picnic", 34));
answers.add(new Answer("Wedding", 10));
answers.add(new Answer("Concert", 7));
answers.add(new Answer("Barbecue", 3));
break;
case 5:
ask="What accent might an American pretend to have in order to sound more attractive:";
answers.add(new Answer("French", 61));
answers.add(new Answer("British", 18));
answers.add(new Answer("Italian", 8));
answers.add(new Answer("Spanish", 8));
answers.add(new Answer("Australian", 3));
break;
case 6:
ask="Name a sport that might be played at a family reunion:";
answers.add(new Answer("Football", 54));
answers.add(new Answer("Baseball", 21));
answers.add(new Answer("Horseshoe", 8));
answers.add(new Answer("Frisbee", 7));
answers.add(new Answer("Basketball", 6));
break;
case 7:
ask="Name a game that would be inappropriate at a company party:";
answers.add(new Answer("Spin the Bottle", 41));
answers.add(new Answer("Strip Poker", 32));
answers.add(new Answer("Twister", 11));
answers.add(new Answer("Truth or Dare", 11));
answers.add(new Answer("Beer Pong", 3));
break;
case 8:
ask="Name something that would get you thrown out of most bars:";
answers.add(new Answer("Getting in a fight", 45));
answers.add(new Answer("Drinking too much", 29));
answers.add(new Answer("Not Paying", 6));
answers.add(new Answer("Stripping", 5));
answers.add(new Answer("Being underage", 3));
break;
case 9:
ask="Name something you would see on the Jerry Springer show:";
answers.add(new Answer("Fighting", 56));
answers.add(new Answer("Nudity", 22));
answers.add(new Answer("Security", 6));
answers.add(new Answer("Jerry Springer", 4));
answers.add(new Answer("Chairs Thrown", 3));
break;
case 10:
ask="Name a breed of dog that might be used as a guard dog:";
answers.add(new Answer("German Shepard", 36));
answers.add(new Answer("Pit Bull", 23));
answers.add(new Answer("Doberman Pinscher", 20));
answers.add(new Answer("Rottweiler", 8));
answers.add(new Answer("Bulldog", 5));
break;
default:
//won't reach this hehe
} //end switch
return ask;
}
@Override
public boolean equals(Object obj)
{
if(obj == null)
return false;
if(!Question.class.isAssignableFrom(obj.getClass()))
return false;
final Question q = (Question) obj;
if(q.getQuestion() == null || this.getQuestion() == null)
return false;
if(!this.getQuestion().equalsIgnoreCase(q.getQuestion()))
return false;
return true;
}
//getters and setters
public String getQuestion() { return question; }
public ArrayList<Answer> getAnswers() { return answers; }
//returns answer at given index
public Answer answerAt(int index) { return answers.get(index); }
//returns String of answer at specified index
public String getAnswerAt(int index) { return answers.get(index).getAnswer(); }
//returns point value of answer at specified index
public int getAnswerPoints(int index) { return answers.get(index).getValue(); }
//returns the points earned for this question
//points are the point values of all the answers that have been found
public int pointsEarned() {
int points=0;
for (int i=0; i<answers.size(); i++)
{
if(answers.get(i).isFound())
points += answers.get(i).getValue();
}
return points;
}
//Sets a particular answer's value
public void setAnswerVal(int index, int val) { answers.get(index).setValue(val); }
//Add a multiplier to each answer's value for the question
public void addMultiplier(int multiplier)
{
for(int i=0; i<answers.size(); i++)
{
int val = answers.get(i).getValue();
answers.get(i).setValue(multiplier * val);
}
}
//returns string of each answer
public String topAnswer() { return answers.get(0).getAnswer(); }
public String Answer2() { return answers.get(1).getAnswer(); }
public String Answer3() { return answers.get(2).getAnswer(); }
public String Answer4() { return answers.get(3).getAnswer(); }
public String lastAnswer() { return answers.get(4).getAnswer(); }
//returns values of each answer
public int topAnswerVal() { return answers.get(0).getValue(); }
public int Answer2Val() { return answers.get(1).getValue(); }
public int Answer3Val() { return answers.get(2).getValue(); }
public int Answer4Val() { return answers.get(3).getValue(); }
public int lastAnswerVal() { return answers.get(4).getValue(); }
}
我不明白为什么它不起作用:(非常感谢帮助!
解决方案
您覆盖的 equals 方法逻辑很好。只是您sysout
在错误的地方做错了事,使您相信逻辑不起作用。与其在添加问题的 for 循环内打印问题,不如在该循环外打印它。如下修改你的逻辑,你会得到预期的结果
for(int i=0; i<15; i++)
{
Question q = new Question();
//makes sure there are no duplicates
if(!questions.contains(q))
questions.add(q); //not working for some reason cry
}
for (Question question : questions) {
System.out.println(question.getQuestion());
}
请注意,每当您覆盖equals
方法时,您也应该覆盖hashCode
。因为如果你不这样做,那么Object
将使用类中的默认实现。因此,即使根据 equals() 方法它们相等,它们也可能具有不同的哈希码。您正在使用Arraylist
,因此您不会在这里遇到问题,但是某些集合(例如HashSet, HashMap
同时使用equals
和hashcode
用于添加和检索对象)。这可能会给您带来意想不到的结果。因此,请始终始终如一地覆盖它们。关联
public int hashCode(){
return question.hashCode();
}
此外,如果您的平等逻辑仅基于String question
,我建议您要么让您的Question
课程实现或为您的课程Comparable
创建一个,而不是使用来保存问题列表,使用这样 1)您不必担心实现equals和hashcode方法和2)你不必总是检查添加一个新问题。下面是一个代码片段Comparator
Question
ArrayList
Set(TreeSet)
实施Comparable<Question>
@Override
public int compareTo(Question question) {
return this.getQuestion().compareTo(question.getQuestion());
}
将问题添加到Set
Set<Question> questions = new TreeSet<>();
for(int i=0; i<15; i++)
{
questions.add(new Question());
}
for (Question question : questions) {
System.out.println(question.getQuestion());
}
推荐阅读
- python - 使用字符串的矩形函数
- r - 将 nudge_y 添加到“抖动”R ggplot2 图的数据标签中
- java - 有没有一种简单的方法可以通过使用android上的后退按钮来防止片段返回
- docker - 在已经运行的 mysql 容器中映射外部的 MySQL docker 端口
- powershell - 试图将变量从 powershell 函数传递给另一个
- python - 在 Dash Python 中单击图形时更新视频源
- java - 如何防止 Mono 被取消?
- vue.js - 当 Vue 中的根 props 是外部 JS 类时的反应性
- java - 如何在下面的代码中添加授权和日期/时间标头?
- javascript - 循环2个数组并按预期制作一个数组