Я только что узнал об арайлистах и получил задание создать приложение для мобильного телефона со списком контактов, в котором можно добавлять удалять изменять искать контакты.
Если вы думаете, что я должен добавить что-то в код, не стесняйтесь сказать мне 🙂
MobilePhone класс
public class MobilePhone{
private String phoneNumber;
public ArrayList<Contact> myContacts = new ArrayList<Contact>();
public MobilePhone(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public void printContactList() {
if (!myContacts.isEmpty()) {
for (int i = 0; i < myContacts.size(); i++) {
System.out.println(i + 1 + ". " + "Name: " + myContacts.get(i).getName() + " || Phone number: " + myContacts.get(i).getPhoneNumber());
}
} else {
System.out.println("Your contact list is empty!");
}
}
public void addContact(String name, String phoneNumber) {
if (searchContactByPhoneNumber(phoneNumber) == -1) {
Contact contact = new Contact(name, phoneNumber);
myContacts.add(contact);
System.out.println("Contact " + name + " with phone number " + phoneNumber + " just added!");
} else {
System.out.println("This contact is already on your list.");
}
}
public void removeContact(String phoneNumber) {
int index = searchContactByPhoneNumber(phoneNumber);
if (index >= 0) {
System.out.println("You have removed " + myContacts.get(index).getName());
myContacts.remove(index);
}
}
public int searchContactByPhoneNumber(String phoneNumber) {
for (int i = 0; i < myContacts.size(); i++) {
if (phoneNumber.equals(myContacts.get(i).getPhoneNumber())) {
System.out.println(myContacts.get(i).getName() + " Found!");
return i;
}
}
return -1;
}
public int searchContactByName(String name){
for(int i =0; i<myContacts.size(); i++){
if(name.equals(myContacts.get(i).getName())) {
return i;
}
}
return -1;
}
public void changeContact(String oldName, String newName) {
int index = searchContactByName(oldName);
if(index >=0){
Contact updatedContact = new Contact(newName,myContacts.get(index).getPhoneNumber());
myContacts.set(index,updatedContact);
System.out.println("You have changed contact " +oldName + " to " + newName + "n" +
"Phone number: " +myContacts.get(index).getPhoneNumber());
} else {
System.out.println("No contact named " + oldName + " on your contact list");
}
}
}
Контактный класс
public class Contact {
private String name;
private String phoneNumber;
public Contact(String name, String phoneNumber) {
this.name = name;
this.phoneNumber = phoneNumber;
}
public String getName() {
return this.name;
}
public String getPhoneNumber(){
return this.phoneNumber;
}
}
PrintService класс
public class PrintService {
public static void printMenu() {
System.out.println("Press:" + "n" +
"r" + "1. Show contact list" + "n" +
"r" + "2. Add an contact" + "n" +
"r" + "3. Remove an contact" +"n" +
"r" + "4. Search for an contact" + "n" +
"r" + "5. Change info about some contact" +"n"+
"r" + "6. Exit.");
}
}
Основной класс
public class Main {
private static final Scanner sc = new Scanner(System.in);
private static final MobilePhone mobilePhone = new MobilePhone("123456789");
public static void main(String[] args){
boolean exitRequested = false;
while(!exitRequested) {
PrintService.printMenu();
int options = Integer.parseInt(sc.nextLine());
switch (options) {
case 1:
mobilePhone.printContactList();
break;
case 2:
addContact();
break;
case 3:
removeContact();
break;
case 4:
searchContact();
break;
case 5:
changeContact();
break;
case 6:
exitRequested = true;
break;
}
}
}
private static void addContact() {
System.out.println("Name?");
String name = sc.nextLine();
System.out.println("Phone number:");
String phoneNumber = sc.nextLine();
if (phoneNumber.length() != 10) {
System.out.println("Wrong input!");
} else {
mobilePhone.addContact(name, phoneNumber);
}
}
private static void removeContact(){
System.out.println("Which contact would you like to remove?" +"n" +
"Please type phone number.");
String phoneNumber = sc.nextLine();
mobilePhone.removeContact(phoneNumber);
}
private static void searchContact(){
System.out.println("Please enter phone number ");
String phoneNumber = sc.nextLine();
if(mobilePhone.searchContactByPhoneNumber(phoneNumber) == -1) {
System.out.println("No contact found with phone number " + phoneNumber);
} else {
mobilePhone.searchContactByPhoneNumber(phoneNumber);
}
}
private static void changeContact(){
System.out.println("Which contact would you like to modify?");
String currentName = sc.nextLine();
System.out.println("Enter your modify");
String updatedName = sc.nextLine();
mobilePhone.changeContact(currentName,updatedName);
}
}
Большое спасибо вам!
2 ответа
Что я люблю
Вы следуете соглашениям об именах Java, и имена, которые вы выбираете для своих идентификаторов, довольно хороши.
Что мне не нравится
Излишняя изменчивость
Переменная-член phoneNumber
в вашем классе MobilePhone
не меняется в течение срока службы объекта, поэтому его следует декларировать final
. То же самое относится к name
и phoneNumber
в вашем классе Contact
.
Неподходящая видимость
Переменная-член myContacts
в вашем классе MobilePhone
объявляет public
. Это означает, что его содержимое может быть изменено из любого места за пределами класса. MobilePhone
. Это нарушает инкапсуляция / скрытие информации принцип, одно из важнейших понятий объектно-ориентированное программирование.
Использование индексов вместо объектов
Ваш search*
методы возвращают индексы вместо реальных объектов. Поэтому вызывающий эти методы должен снова получить доступ к списку, если он хочет что-то сделать с данными этого конкретного контакта (что почти всегда так …). Так что лучше сам объект контакта верните.
Встроенная сигнализация об ошибках
Если ваш search*
метод ничего не находит, вы возвращаете особая ценность. В Java у нас есть концепция Исключения справиться с подобными проблемами.
Да, есть правило, что вы не должны пропускать использование Исключений в качестве поток управления. Но они предназначены именно для этой цели, избегая этого. внутриполосная сигнализация из особый случай при возврате результата обработки.
В вашем небольшом проекте Исключения в основном заменит if/else
заявления с try/catch
блоки, что совсем не похоже на выгоду. Но в более крупных проектах весьма вероятно, что случай ошибки не может быть обработан методом прямого вызова, а может быть обработан каким-либо другим методом наверху в стеке вызовов. Тогда только код, способный справиться с этой проблемой, должен знать, что это может произойти. Без использования исключений любой метод, находящийся ниже в стеке вызовов, нуждается в этом if
заявления.
Другой способ обойти это — использование Optional
как возвращаемое значение. Но это всего лишь еще один особая ценность по моему мнению.
Именование
Как я изначально писал, ваше именование довольно хорошее, за одним незначительным исключением. В вашей main
метод локальной переменной options
всегда будет содержать не замужем выбор пользователя. Следовательно, в нем не должно быть множественного числа s.
Написав это, имя option
может быть не так уж и хороша, скорее должна быть selectedOption
или просто choice
…
Ответить на комментарий
Я пробовал раньше использовать все методы (контактный контакт), но на самом деле я сильно застрял. — עמית שוקרון
Это должно быть довольно легко.
public class MissingContact extends RuntimeException{
public MissingContact(String message){
super(message);
}
}
public Contact searchContactByPhoneNumber(String phoneNumber) {
for (contact: myContacts) {
if (phoneNumber.equals(contact.getPhoneNumber())) {
System.out.println(contact.getName() + " Found!");
return contact;
}
}
throw new MissingContact("No contact with number "+phoneNumber);
} // search by name similar
Чтобы избежать обработки исключений, вы должны применить проверить, затем действовать шаблон, добавив соответствующие методы проверки:
public boolean hasContactWithPhoneNumber(String phoneNumber) {
for (contact: myContacts) {
if (phoneNumber.equals(contact.getPhoneNumber())) {
System.out.println(contact.getName() + " Found!");
return true;
}
}
return false;
} // searchByName similar
Я думаю, что Тимоти Тракл проделал здесь много хорошего.
Однако я бы не согласился с идеей создания непроверенного исключения, когда записи не могут быть найдены.
Это упражнение имеет характеристики, очень похожие на интерфейс java.util.Map (фактически, если бы OP не уделял особого внимания изучению ArrayLists, Map была бы лучшей структурой для реализации списка контактов).
Следуя примеру Map, если записи не могут быть найдены, просто верните null.
Я был бы склонен сделать класс Contact вложенным классом в MobilePhone, поскольку я не считаю, что он нужен где-то еще, и я думаю, что для этого нужен хороший метод toString ().
Меня беспокоит операция changeContact () — метод MobilePhone.addContact () применяет только уникальные номера телефонов, но changeContact выполняет поиск по имени, поэтому я не думаю, что вы гарантированно измените имя для контакта, который у вас может быть предназначена.
Я не пытался решить эту проблему в приведенном ниже коде (который не тестировался, поэтому рассматривайте его как набросок того, как я бы это сделал, если бы был вынужден использовать для этой цели ArrayList).
import java.util.ArrayList;
public class MobilePhone {
private static class Contact {
private String name;
private String phoneNumber;
public Contact(String name, String phoneNumber) {
this.name = name;
this.phoneNumber = phoneNumber;
}
@Override
public String toString() {
return String.format("Name: %s , || Phone number: %s", name, phoneNumber);
}
}
@SuppressWarnings("unused")
private final String myPhoneNumber; // Different name to the contact phone number, for clarity
private final List<Contact> myContacts = new ArrayList<Contact>(); // use Interface as the field type...
public MobilePhone(String phoneNumber) {
myPhoneNumber = phoneNumber;
}
public void printContactList() {
if (!myContacts.isEmpty()) {
for (Contact contact : myContacts) {
System.out.println(contact);
}
}
else {
System.err.println("Your contact list is empty!");
}
}
public void addContact(String name, String phoneNumber) {
Contact existingContact = searchContactByPhoneNumber(phoneNumber);
if (existingContact == null) {
Contact contact = new Contact(name, phoneNumber);
myContacts.add(contact);
System.out.format("Contact %s added%n", contact);
}
else {
System.err.format("This phone number is already on your list - %s%n", existingContact);
}
}
public void removeContact(String phoneNumber) {
Contact existingContact = searchContactByPhoneNumber(phoneNumber);
if (existingContact != null) {
myContacts.remove(existingContact); // we're ignoring the boolean result in this case
System.out.format("You have removed contact - %s%n" + existingContact);
}
}
public Contact searchContactByPhoneNumber(String phoneNumber) {
for (Contact contact : myContacts) {
if (phoneNumber.equals(contact.phoneNumber)) {
return contact;
}
}
return null;
}
public Contact searchContactByName(String name) {
for (Contact contact : myContacts) {
if (name.equals(contact.name)) {
return contact;
}
}
return null;
}
public void changeContact(String oldName, String newName) {
Contact existingContact = searchContactByName(oldName);
if (existingContact != null) {
existingContact.name = newName;
System.out.format("You have changed contact %s to %s%nPhone number: %s%n", oldName, newName, existingContact.phoneNumber);
}
else {
System.err.format("No contact named %s on your contact list%n", oldName);
}
}
}
Привет ! Спасибо за ваш ответ! Я пробовал раньше использовать все методы (контактный контакт), но на самом деле я сильно застрял. Я не могу сделать это в одиночку .. надеюсь, что кто-нибудь подскажет мне это;)
Амит Шукрон
@ יתשוקרון: посмотрите обновление, это поможет?
— Тимоти Тракл
Большое спасибо, сэр, мне это очень помогло!
Амит Шукрон
Привет еще раз! надеюсь, вы это увидите, мне следует изменить только метод поиска или мне нужно изменить каждый метод, чтобы получить параметр контакта контакта?
Амит Шукрон
@ עמיתשוקרון Ваш API должен быть последовательный поэтому любой метод, который в настоящее время возвращает индекс, должен возвращать
Contact
объект вместо этого.— Тимоти Тракл
Шоу 2 больше комментариев