在下面的switch语句的情况5中,我希望用户从阵列中输入一个学生,并从modules阵列中选择一个模块,以便在不重复的情况下注册它们。任何想法/例子都非常有用。提前谢谢。
控制类:
import java.util.Scanner;
public class Control {
public void run() {
while (true) {
Menu menu = new Menu();
menu.getMainMenu();
try {
Scanner scan = new Scanner(System.in);
int selection = scan.nextInt();
switch (selection) {
case 1:
for (Student student : students) {
System.out.print(student.getName() + " ");
}
break;
case 2:
for (Module module : modules) {
System.out.print(module.getName() + " ");
}
break;
case 3:
...
case 4:
...
case 5:
// Print out students
System.out.println("select a student: ");
for (int i = 0; i < students.length; i++) {
System.out.println(i + " " + students[i]);
}
selection = scan.nextInt();
############################
Confusion here
############################
case 6:
System.out.println("Goodbye!");
System.exit(0);
break;
default:
System.out.println("Invalid option selected. You must enter a number between 1 & 6!");
} // end switch
} catch (Exception e) {
System.out.println("Invalid entry. You must enter a number between 1 & 6");
}
} // end while
}
}
答案 0 :(得分:2)
如果要避免重复,请不要使用数组或列表。使用Set。
答案 1 :(得分:1)
您可以使用set实现(HashSet,LinkedHashSet)来避免重复。
或使用ArrayList。但在这种情况下,请检查
list.contains(obj)
插入前
使用HashSet,您将不知道插入的顺序。但是使用LinkedHashSet和ArrayList,你可以
如果需要,您可以使用
toArray()
在Set或ArrayList中的函数将列表转换为数组
答案 2 :(得分:1)
在您的示例中,学生的标识符和test-for-uniqueness是名称(jane / alex / mike)。
如果您使用名称作为索引的HashMap,则将(使用.put)添加到HashMap将添加新的但不重复(如果重复)。
您可能需要考虑重写equals()和hashCode()来告诉Java如何确定两个学生是否相同。如果你有两个同名的学生,这个名字就会给你带来麻烦。
答案 3 :(得分:1)
你的班级模型存在一个概念上的弱点,它会给你带来麻烦。因为学生有一个模块列表,而一个模块也有一个学生列表,你必须在两个地方做簿记,并且可能存在不一致,例如:
jane : UFCE1, UFCE2
UFCE1 : alex, mike
这样的对象模型可以保证为您(或者在您离开后必须维护代码的开发人员)带来可怕的麻烦。
您可以做的是从学生和模块类中删除列表,并创建一个跟踪注册的服务类:
public class EnrollmentService {
private final Map<Module, List<Student>> enrollments;
public boolean addModule(Module module) {...
public boolean enroll(Student student, Module module) {...
public final List<Student> getStudents(Module module) {...
public List<Module > getModules(Student student) {...
}
每个设计决策都是权衡。这里显而易见的缺点是'getModules'方法,它必须遍历地图以收集给定学生已注册的所有模块。您可以选择第二个地图来跟踪此反向查找,这更快,但是给你一个再次双重记账。在单个班级中进行双重簿记比在单独的班级中进行双重记录要轻松一点......
另一个经常使用且完全有效的模型化方法是仅在一个域类中跟踪学生模块关系。在这种情况下,我会选择模块,但它实际上取决于您的要求。当然,您仍需要一个服务类来注册学生并执行查找。
结束时的一些评论:
我希望这有帮助!
答案 4 :(得分:0)
如果可能,我会使用Set而不是数组。然后,您可以在Student类中实现.equals和.hashcode,并控制应用程序中“复制”的含义。
如果订单也很重要,也许是LinkedHashSet ......
答案 5 :(得分:0)
虽然我同意使用集合的观点,但有时候List会感觉更好或更自然,因为它具有排序的概念。例如,您可以按照GPA排序,并要求第三好的学生。
你可以做点什么synchronized boolean addFoo(Foo foo) {
if mList.contains(foo)
return false;
else
return mList.add(foo);
}
答案 6 :(得分:0)
您的相等标准是Student add equals和hashcode实现的名称,如:
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Student)) {
return false;
}
Student other = (Student) obj;
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
return true;
}
现在,在您的Module
类addStudent()方法中,您有以下选择:
if(!students.contains(student) {
students.add(student);
} // You will add to the list only if Student with same name doesn't exist.
或者更改为Set实现,因此从List学生中它将变为Set
然后在你的addStudent
方法中,你的电话会是
students.add(student);//this call will check if there is any student object already in the set with same name, if yes it wont add or else student will be added