Java 如何使用泛型来简化我的搜索方法?

Java 如何使用泛型来简化我的搜索方法?,java,generics,arraylist,Java,Generics,Arraylist,在我的程序中,我试图创建一个方法,通过BaseContact的ArrayList进行搜索。BaseContact是在PersonContact和BusinessContact类中扩展的抽象类。我想创建一个搜索方法,询问用户想要搜索的属性(姓名、地址、ID号等),然后询问他们想要搜索的内容(例如“John”、“123 Oak”,2)。目前,我的代码使用扫描仪和开关盒询问用户要搜索的内容,然后运行for循环,检查他们的输入是否等于具有该属性的任何联系人。我想知道是否有任何方法可以利用泛型或其他方法来

在我的程序中,我试图创建一个方法,通过BaseContact的ArrayList进行搜索。BaseContact是在PersonContact和BusinessContact类中扩展的抽象类。我想创建一个搜索方法,询问用户想要搜索的属性(姓名、地址、ID号等),然后询问他们想要搜索的内容(例如“John”、“123 Oak”,2)。目前,我的代码使用扫描仪和开关盒询问用户要搜索的内容,然后运行for循环,检查他们的输入是否等于具有该属性的任何联系人。我想知道是否有任何方法可以利用泛型或其他方法来减少代码的重复性

public void search() {
    Boolean active = true;
    @SuppressWarnings("resource")
    Scanner sc = new Scanner(System.in);

    // While Statement for Search
    while (active) {
        System.out.println("--- Search ---");
        System.out.println(
                "\n1. Id\n2. Name\n3. Phone Number\n4. Date of Birth\n5. Hobby\n6. Website URL\n7. Street\n8. City\n9. State\n10. Zip Code");
        String choice = sc.nextLine();
        // Switch statement
        switch (choice) {

        case "1":
        case "Id":
            System.out.println("What is the Id number?");
            int id = sc.nextInt();
            sc.nextLine();
            for (BaseContact contact : contacts) {
                if (contact.getId() == id) {
                    System.out.println("Contact with the Id of " + id);
                    System.out.println("Contact- " + contact.toString() + "\n");
                }
            }
            break;

        case "2":
        case "Name":
            System.out.println("What is the Name?");
            String name = sc.nextLine();
            for (BaseContact contact : contacts) {
                if (contact.getName().equals(name)) {
                    System.out.println("Contact with the Name of " + name);
                    System.out.println("Contact- " + contact.toString() + "\n");
                }
            }
            break;

        case "3":
        case "Phone Number":
            System.out.println("What is the Phone Number?");
            String phoneNum = sc.nextLine();
            for (BaseContact contact : contacts) {
                if (contact.getPhoneNum().equals(phoneNum)) {
                    System.out.println("Contact with the Phone Number of " + phoneNum);
                    System.out.println("Contact- " + contact.toString() + "\n");
                }
            }
            break;

        case "4":
        case "Date of Birth":
            System.out.println("What is the Date of Birth? (Month Day, Year)");
            String dob = sc.nextLine();
            for (BaseContact contact : contacts) {
                if (contact.getType() == "personContact") {
                    PersonContact temp = (PersonContact) contact;
                    if (dob.equals(temp.getDob())) {
                        System.out.println("Contact with the Date of Birth of " + dob);
                        System.out.println("Contact- " + contact.toString() + ":\n");
                    }
                }
            }
            break;

        case "5":
        case "Hobby":
            System.out.println("What is the Hobby?");
            String hobby = sc.nextLine();
            for (BaseContact contact : contacts) {
                if (contact.getType() == "personContact") {
                    PersonContact temp = (PersonContact) contact;
                    if (hobby.equals(temp.getHobby())) {
                        System.out.println("Contact with the Hobby of " + hobby);
                        System.out.println("Contact- " + contact.toString() + "\n");
                    }
                }
            }
            break;

        case "6":
        case "Website URL":
            System.out.println("What is the Website URL?");
            String url = sc.nextLine();
            for (BaseContact contact : contacts) {
                if (contact.getType() == "businessContact") {
                    BusinessContact temp = (BusinessContact) contact;
                    if (url.equals(temp.getWebsite())) {
                        System.out.println("Contact with the Website URL of " + url);
                        System.out.println("Contact- " + contact.toString() + "\n");
                    }
                }
            }
            break;

        case "7":
        case "Street":
            System.out.println("What is the Street?");
            String street = sc.nextLine();
            for (BaseContact contact : contacts) {
                if (street.equals(contact.getLocation().getStreet())) {
                    System.out.println("Contact with the Street of " + street);
                    System.out.println("Contact- " + contact.toString() + "\n");
                }
            }
            break;

        case "8":
        case "City":
            System.out.println("What is the City?");
            String city = sc.nextLine();
            for (BaseContact contact : contacts) {
                if (city.equals(contact.getLocation().getCity())) {
                    System.out.println("Contact with the City of " + city);
                    System.out.println("Contact- " + contact.toString() + "\n");
                }
            }

            break;

        case "9":
        case "State":
            System.out.println("What is the State?");
            String state = sc.nextLine();
            for (BaseContact contact : contacts) {
                if (state.equals(contact.getLocation().getState())) {
                    System.out.println("Contact with the State of " + state);
                    System.out.println("Contact- " + contact.toString() + "\n");
                }
            }
            break;

        case "10":
        case "Zip Code":
            System.out.println("What is the Zip Code?");
            String zip = sc.nextLine();
            for (BaseContact contact : contacts) {
                if (zip.equals(contact.getLocation().getZipCode())) {
                    System.out.println("Contact with the Zip Code of " + zip);
                    System.out.println("Contact- " + contact.toString() + "\n");
                }
            }
            break;

        // case "5":
        case "Exit":
            System.out.println("--- EXIT Search ---");
            active = false;
            break;

        default:
            boolean exit = true;
            while (exit) {
                System.out.println("INVALID INPUT\nWould you like to Exit? Y/N");
                String Cexit = sc.nextLine();
                if (Cexit.equalsIgnoreCase("Y")) {
                    System.out.println("--- EXIT ---");
                    exit = false;
                    active = false;
                }
                if (Cexit.equalsIgnoreCase("N")) {
                    exit = false;
                }
            }
            break;

        } // End Switch Statement
    } // End while loop
}

因此,如果用户必须添加联系人的几乎所有信息 为什么不扫描所有内容,然后创建一个扩展基本联系人的
QueryContact

如果实现
equals()
方法,则可以使用Arraylist的
contains()
方法

在任何情况下,您都可以使用streams并执行以下操作:

contacts.stream()
.filter(con-> con.getAddress().equals(queryContact.getAddress())
.filter(con-> con.getName().equals(queryContact.getName())
...//etc
.collect(Collectors.toList());

当然,如果您需要实现“like”搜索,这可能会变得很棘手。

因此,如果您的用户必须添加联系人的几乎每一条信息 为什么不扫描所有内容,然后创建一个扩展基本联系人的
QueryContact

如果实现
equals()
方法,则可以使用Arraylist的
contains()
方法

在任何情况下,您都可以使用streams并执行以下操作:

contacts.stream()
.filter(con-> con.getAddress().equals(queryContact.getAddress())
.filter(con-> con.getName().equals(queryContact.getName())
...//etc
.collect(Collectors.toList());

当然,如果你需要实现一个“like”搜索,它可能会变得很棘手。

通过查看我提出的代码,重构可能会对你有所帮助

因为在switch语句的每种情况下,您都在重复该结构。我建议提取这段代码并将其转换为方法

private void数据查询(String requestMessage、String logMessage、Function expressionProvider){
System.out.println(请求消息);
字符串输入=sc.nextLine();
用于(基本联系人:联系人){
if(input.equals(expressionProvider.apply(contact))){
System.out.println(logMessage+zip);
System.out.println(“Contact”+Contact.toString()+“\n”);
}
}
}
我希望你能想象出你在每个案例中使用的相同结构

名为
expressionProvider
的参数是一个遵循函数原理(进行转换)的函数。此函数将接收BaseContact,然后返回字符串。在中间,你可以按照你想要的方式工作。

下面是方法
dataQuery
的一些调用:

案例“6”:
案例“网站URL”:
dataQuery(“什么是网站URL?”,“与的网站URL联系”,
基本联系人->{
if(baseContact.getType().equals(“buisnessContact”)){
return((BusinessContact)baseContact.getWebsite();
}
return null;//可以在不引发NPE的情况下返回null(null指针异常)
});
打破
案例“7”:
案例“街道”:
dataQuery(“什么是街道?”,“与街道的联系”,
baseContact->baseContact.getLocation().getStreet());
打破
案例“8”:
案例“城市”:
dataQuery(“什么是城市?”,“与城市联系”,
(baseContact->baseContact.getLocation().getCity());
打破
案例“9”:
案例“国家”:
dataQuery(“状态是什么?”,“与状态的联系人”,
(baseContact->baseContact.getLocation().getState());
打破
注意:为了使用此实现,您应该将联系人列表声明为全局变量,以及scanner。如果不能这样做,则必须通过方法的参数传递它们

更新: 通过创建如下枚举,还可以稍微改进switch case语句:

contacts.stream()
.filter(con-> con.getAddress().equals(queryContact.getAddress())
.filter(con-> con.getName().equals(queryContact.getName())
...//etc
.collect(Collectors.toList());
公共枚举选项{
无(“,”),
身份证(“身份证”、“1”),
名称(“名称”、“2”),
街(“街”、“3”),
城市(“城市”,“4”);//您可以继续在此处添加选项!
字符串标识符;
字符串标识符;
选项(字符串第一标识符、字符串第二标识符){
this.firstIdentifier=firstIdentifier;
this.secondIdentifier=secondIdentifier;
}
公共静态选项getOptionByIdentifier(字符串标识符){
返回Arrays.stream(Option.values())
.filter(option->option.secondIdentifier.equals(identifier)| | option.firstIdentifier
.equals(标识符))
.findAny()
.orElse(无);
}
}
然后switch语句将类似于:

Option=Option.getOptionByIdentifier(选项);
开关(选件){
案件编号:
//选择ID时的代码
打破
案例名称:
//选择名称时输入您的代码
打破
凯斯街:
//选择“街道”时的代码
打破
案例无:
//默认情况下,基本上是当输入为垃圾时
打破
}

就个人而言,我认为使用enum看起来更干净。另外,对于您的特定情况,通过查看我提出的可能有助于您的重构的代码,可以避免双格调用:D

因为在switch语句的每种情况下,您都在重复该结构。我建议提取这段代码并将其转换为方法

private void数据查询(String requestMessage、String logMessage、Function expressionProvider){
System.out.println(请求消息);
字符串输入=sc.nextLine();
用于(基本联系人:联系人){
if(input.equals(expressionProvider.apply(contact))){