Поиск имен в жестко список контактов


Я в настоящее время беру уроки на моем местном колледже для программирования на Java, а также пытается узнать как я могу в свое свободное время. Хотелось бы ваше мнение о программе я написал, что бы показать любые результаты сопоставления введенного пользователем поискового запроса. Это работает, но я чувствую, что она могла быть написана лучше, или даже быть более эффективным, я не знаю, как я еще немного нового в Java. Не могли бы вы пожалуйста, дайте мне знать, если я делаю что-то неправильно, как вредные привычки кодирование, делая вещи, которые легко сделать с помощью кода, или предложите что-нибудь вы думаете, что я должен улучшить.

package controller;
import java.util.Scanner;

public class PhoneListDemo {

    public static void main(String[] args) {

        promptUser();

    }
    public static void promptUser() {

        Scanner keyboard = new Scanner(System.in);
        System.out.println("Enter a name or characters to search for: ");
        String userSearch = keyboard.nextLine();
        keyboard.close();
        searchAndDisplay(userSearch);
    }
    public static void searchAndDisplay(String userSearch) {

        String[] names = {"Harrison, Rose", "James, Jean", "Smith, William", "Smith, Brad"};
        String[] phone = {"555-2234", "555-9098", "555-1785", "555-9224"};

        for(int i = 0; i < names.length; i++) {

        if(names[i].toLowerCase().contains(userSearch.toLowerCase())) {

            System.out.println(names[i] + ":  " + phone[i]);

            }
        }
    }
}


220
3
задан 20 февраля 2018 в 12:02 Источник Поделиться
Комментарии
3 ответа

Структура

Меня удивляет, что promptUser() также выполняет поиск. Среди прочего, это делает его более трудным для вас, чтобы проверить побуждению, и это делает это тяжелее, чтобы повторно использовать функцию для чего-то другого.

Я бы ожидал main() чтобы выглядеть так:

public static void main(String[] args)
{
String search_string
= promptUser("Enter a name or characters to search for: ");
searchAndDisplay(search_string);
}

Нам нужно изменить promptUser() принимает аргумент и возвращает значение:

public static String promptUser(String prompt) {
Scanner keyboard = new Scanner(System.in);
System.out.println(prompt);
String userSearch = keyboard.nextLine();
keyboard.close();
return userSearch;
}

Я надеюсь, вы видите, как она стала более многоразовые.

Структуры данных

Мы хотели бы уметь отделять поиск и отображение части searchAndDisplay() (потому что однажды мы захотим поиска и обновления, или найти и удалить). Что мешает на данный момент, потому что каждая запись разбросаны по двум спискам (и у нас есть слабости, что два списка должны быть выровнены друг с другом).

Вместо этого, он будет проще работать с единым списком записей. Давайте определим Record структуру, которая выглядит примерно так:

public class Record
{
String name;
String phone;
}

Теперь, если у нас есть список Recordмы можем иметь search() функция, которая возвращает Record и display() функция, которая принимает запись и печатает его. Я позволю тебе заполнить остальную часть Record - вы хотите, по крайней мере, конструктор, и, возможно, методы доступа и bool matches(String substring).

Сравнение строк

Сравнение строк с помощью преобразования в нижний регистр как правило, работает на английские имена, но меньше и в других языках. Например, это позволит предотвратить AMELIE из сопоставления Amélie во Франции (где акценты обычно не держали на верхний регистр слов), и его будет не хватать Groß при поиске GROSS. Есть несколько переполнения стека ответы на эти (и, вероятно, лучше, чем мой ржавый знаний Java):

Помните, что есть довольно много плохие ответы на те вопросы, в основном рекомендуя toLower() или toUpper() как у вас сейчас.

Вы, вероятно, хотите что-то вроде

    Pattern search_re = Pattern.compile(userSearch, Pattern.CASE_INSENSITIVE | Pattern.LITERAL | Pattern.UNICODE_CASE);
for (int i = 0; i < names.length; i++) {
if (p.matcher(name).find()) {
System.out.println(names[i] + ": " + phone[i]);
}
}

(где Pattern это java.util.regex.Pattern - вы хотите, чтобы import что).

Очевидно, вам потребуется адаптировать что немного после того, как вы хранение Record объектов, а не разделенные имена и телефоны.

4
ответ дан 20 февраля 2018 в 09:02 Источник Поделиться

Вы можете заменить традиционные петли с IntStream и Predicate используя лямбда-выражения. Это до вас, если вы найдете это более читаемым и лучше понять (для меня: да ^_^)

Optional hasValue = IntStream.range(0, names.length).filter(i -> names[i].equalsIgnoreCase(userName)).findFirst();
if (hasValue.isPresent()){
System.out.println(names[hasValue.get()] + ": " + phone[hasValue.get()]);
}

Примечание: это решение позволяет найти первого матча, дальше матчи не показали (но может быть показано, с небольшой модификацией).


Нечто совершенно иное:

Вы не используете какие-либо объектно-ориентированный подход, но процедурный подход. Может быть, вы хотите какие-то намеки об этом.


  • использовать класс для ввода обработчик, может быть InputHandler

  • обеспечить способ для InputHandler читать из командной строки, как InputHandler.readFromCommandLine

  • использовать класс для Ваш адрес, может PhoneBook

  • определить метод для PhoneBook что позволяет вам находить записи


    • по имени PhoneBook.findByName(String name)

    • по количеству PhoneBook.findByNumber(String number)


  • создать класс для адреса, где вы можете поместить все данные Address

  • использовать интерфейсы...

Ваш код может выглядеть примерно так:

public static void main(String[] args) {
final PhoneBook phoneBook = new PhoneBook();
InputHandler inputHandler = new CommandLineInputHandler();
String searchTerm = inputHandler.readFromCommandLine("Enter a name or characters to search for:");
Address address = phoneBook.findByName(searchTerm);
System.out.println(address);
}

2
ответ дан 20 февраля 2018 в 06:02 Источник Поделиться

Единственный совет, который я имею, вы могли бы просто установить userSearch термин toLowerCase() раз так вы не должны делать это на каждом сравнении.

  String userSearchTerm = userSearch.toLowerCase();
if(names[i].toLowerCase().contains(userSearchTerm)) {
System.out.println(names[i] + ": " + phone[i]);
}

0
ответ дан 20 февраля 2018 в 07:02 Источник Поделиться