2011-12-01 72 views
1

在下面的switch语句的情况5中,我希望用户输入数组中的一个学生,并从模块数组中选择一个模块来注册它们而不重复。任何想法/例子都会非常有用。提前致谢。在Java中添加新元素而不重复Java

控制类:

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 

} 
} 

回答

2

如果你想避免重复,不要用数组或列表。使用一套。

+1

很好的答案。 LOL比我的简洁得多! –

0

如果可能的话,我会使用Set而不是数组。然后,您可以在您的Student类中实现.equals和.hashcode,并控制应用程序中“重复”的含义。

如果顺序也很重要,也许LinkedHashSet ...

+0

你能否给我一个例子,因为我很难理解Java API集。不熟悉与集相关的语法。附:顺序并不重要。 – newToJava

+0

当然,它是Collection的一个直接扩展,和ArrayLists一样,你可以调用.add,并且可以遍历一个集合,只要你喜欢。好的区别是,任何试图添加一些东西到一个集合将被忽略,该项目已经在集合中。 '设置 students = new HashSet (); students.add(new Student(“jane”));' 诀窍是,为了让一个set知道两个自定义类是'相同的',就是实现一个.equals方法(也是一个。散列码方法)。所以你的学生班可能会有一个比较名字的平等。 – Colby

+0

这个.equals方法和.hashcode方法是什么样的?对不起,我对Java非常陌生。到目前为止,我在驱动程序中创建了两个哈希集:'代码'设置 students = new HashSet (); students.add(new Student(“jane”)); students.add(新生(“alex”)); Set modules = new HashSet (); modules.add(new Module(“ufce1”)); modules.add(new Module(“ufce2”)); – newToJava

1

您可以使用集实现(HashSet的,LinkedHashSet),以避免重复。

或使用ArrayList。但是,在这种情况下做检查

list.contains(obj) 

插入

用一个HashSet你不会知道插入的订单。但LinkedHashSet和ArrayList可以

,如果需要,你可以使用

toArray() 

功能设置或ArrayList中的列表转换为数组

+0

如果你偏爱一点点执行时间使用额外的内存,LinkedHashSet可能真的是你最好的选择。它维护插入顺序,但不必在每次插入时都扫描整个列表(因为它可以使用LinkedHashSet的Set功能)。但是,除非您至少有数百个条目,否则您不会看到任何可衡量的性能差异...... – ziesemer

0

虽然我与情绪同意使用集,有时列表感觉更好或更自然,因为它具有排序的概念。例如,你可以通过GPA进行排序并申请第三名最好的学生。

你可以做类似

synchronized boolean addFoo(Foo foo) { 
    if mList.contains(foo) 
    return false; 
    else 
    return mList.add(foo); 
} 
1

在你的榜样,标识符和测试的唯一性为学生的名字(简/亚历克斯/麦克风)。

如果您使用了一个名称为HashMap的索引,那么向HashMap添加(使用.put)将会添加新的但不重复的数据。

您可能想要考虑重写equals()和hashCode()来告诉Java如何确定两个学生是否相同。如果你有两个同名的不同学生,这个名字会给你带来麻烦。

0

您的平等标准是名学生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. 

或更改为设置执行,所以从列表学生它将成为设置 ,然后在您的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

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) {... 
} 

(见complete code example

每一个设计方案是一个折中。这里明显的缺点是'getModules'方法,它必须走地图才能收集给定学生已注册的所有模块。您可以选择第二张地图来跟踪这种反向查找,这种查找速度更快,但会给您一个再次重复记账。在单独的班级中进行双重簿记与在不同的班级中进行双重簿记相比,要少一点痛苦......

另一个经常使用并且非常有效的方法来模拟这种情况,就是跟踪学生 - 模块关系只在一个领域类中。在这种情况下,我会选择模块,但它确实取决于您的要求。当然你还需要一个服务课来注册学生并进行查找。

在关闭几句话:

  • 创造一个合适的类模型是未落动物的情况下 - >哺乳动物 - >牛就像他们经常让你相信在OOP 101
  • 质量一个班级模型的衡量标准是理解它的容易程度,以及现在和(希望)将来如何解决您的问题。
  • 一个好的模型划分责任的理解的方式和共同定位状态和behaviore在可能
  • 当某种行为并没有明确在一个类属,它通常是创建一个单独的(服务)是个好主意上课做这项工作。
  • 如果你发现很难为一个类(或方法)提出一个好名字,这通常意味着你的模型不适合这个问题。在这种情况下重新思考模型(和问题)。

我希望这有助于!

+0

+1将它带回到对象模型和深思熟虑的评论。 – rajah9