防止重复(唯一护照)

prevent duplicate (Unique Passport)

我试图阻止用户使用相同的护照添加 2 名与会者我尝试了很多事情,例如制作布尔变量来检查之前是否添加过与会者但是我所有的尝试都失败了真的不能想制作这个的方法

public class Test {
    public static void main(String[] args) {
        try {
            Workshop Available_Work_Shops = new Workshop();
            Scanner sc = new Scanner(System.in);
            String passportNumber, workshop;
            boolean isAttendeeMatch;
            ArrayList<Attendee> attendeeList = new ArrayList<>();
            int choice;
            do {
                System.out.println("1. Add New Attendee");
                System.out.println("2. Add Existing Attendee to Workshop");
                System.out.println("3. Remove Attendee from Workshop");
                System.out.println("4. Print WorkShop List");
                System.out.println("5. Print All Attendees");
                System.out.println("0. Close Program");
                System.out.println("Please Enter a number to choose");
                choice = sc.nextInt();
                sc.nextLine();
                switch (choice) {

                    case 1 -> {
                        System.out.println();
                        System.out.println("Adding New Attendee");
                        System.out.println("____________________");
                        System.out.print("Please Enter Attendee Name: ");
                        String Attendee_name = sc.nextLine();
                        System.out.print("Please Enter Attendee Passport Number: ");
                        String Attendee_passport = sc.nextLine();
                        System.out.print("Please Enter Attendee Age: ");
                        String Attendee_Age = sc.nextLine();
                        System.out.print("Please Enter Attendee Phone Number: ");
                        String phone = sc.nextLine();
                        attendeeList.add(new Attendee(Attendee_name, Attendee_Age, Attendee_passport, phone));
                        for (Attendee attendee : attendeeList) {
                            if (attendeeList.contains(attendee.PassportNumber)) {
                                System.out.println("Existing User Found please enter '3' to remove the duplicate user");
                            }
                        }
                    }

马上,我发现了一些会破坏代码的问题:

  1. 您正在将与会者添加到列表中,然后检查它是否存在于列表中(如果检查正确,添加后它总是会这样做)。
  2. if (attendeeList.contains(attendee.PassportNumber)) 永远不会 return true 因为你正在检查整个 List 是否有一个对象等于其中的 PassportNumber (与对象中的 PassportNumber 相反)。应该是 if(attendee.getPassportNumber().equals(Attendee_passport)).

不确定您是多少初学者,但研究命名约定之类的东西可能也很有用(通常 Java 变量应以小写首字母命名,每个新词都有一个大写字母),使用 List<Attendee> 作为声明的变量类型而不是 ArrayList,以及使用 Java 流过滤列表以查看是否已经存在的东西。当您只想存储唯一值时,Java 也有 Set 作为 List 的替代方法(ListSet 之间还有其他区别,因此请确保您如果您想使用它,请查看它)。

问题

让我们关注这两行

...
for (Attendee attendee : attendeeList) {
  if (attendeeList.contains(attendee.PassportNumber)) {
...

由于您已将 attendeeList 定义为包含 Attendee 个对象的 ArrayList,因此您应该将 Attendee 个对象传递给 attendeeList.contains()。虽然 contains() 函数 does accept any Object,但只有当列表的元素之一 .equals() 是您传入的对象时,它才会 return 为真。

解决方案

我建议更改此代码块...

attendeeList.add(new Attendee(Attendee_name, Attendee_Age, Attendee_passport, phone));
for (Attendee attendee : attendeeList) {
  if (attendeeList.contains(attendee.PassportNumber)) {
    System.out.println("Existing User Found please enter '3' to remove the duplicate user");
  }
}

...像这样

Attendee potentialAttendee = new Attendee(Attendee_name, Attendee_Age, Attendee_passport, phone)
// Check if the potentialAttendee's passport number is already used by someone in the list.
boolean passportRegistered = false;
for (Attendee attendee : attendeeList) {
  if (attendee.PassportNumber.equals(potentialAttendee.PassportNumber) {
    System.out.println("That user passport number has already been registered. It can't be added again.");
    passportRegistered = true;
  }
}
// Only add the potentialAttendee if his/her passport number wasn't already used by someone in the list.
if (!passportRegistered) {
  attendeeList.add(potentialAttendee);
}

主要区别在于,在您首先验证 he/she 满足要添加到该列表的要求之前,您不应将 potentialAttendee 添加到该列表。

潜在的增强功能

  • 将参加者存储在 HashMap 而不是 ArrayList 中。如果您关闭 PassportNumber,那么根据定义,您不能在与会者集合中有两个具有相同 PassportNumber 的参与者。
  • Java 有一个很好的 Streaming API 可以使验证更接近一个衬里。