今天學習 ArrayList

import java.util.Scanner;
public class ListAndArrayList {
    private static Scanner scan = new Scanner(System.in);
    private static int[] baseData = new int[3];
    public static void main(String[] args) {
        System.out.println("Enter 3 integers: ");
        getInput();
        printArray(baseData);
        resizeArray();
//        System.out.println("Enter 5 integers: ");
//        getInput();
        baseData[3] = 77;
        baseData[4] = 78;
        printArray(baseData);
    }
    private static void getInput() {
        for (int i = 0; i < baseData.length; i++) {
            baseData[i] = scan.nextInt();
        }
    }
    private static void printArray(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }
    private static void resizeArray() {
        int[] original = baseData;
        baseData = new int[5];
        for (int i = 0; i < original.length; i++) {
            baseData[i] = original[i];
        }
    }
}

Array 如果要改裡面的數量時

就會像上面代碼一樣 弄得很麻煩

main.java

import java.util.ArrayList;
import java.util.Scanner;
public class Main {
    private static Scanner scanner = new Scanner(System.in);
    private static GroceryList groceryList = new GroceryList();
    public static void main(String[] args) {
        boolean quit = false;
        printInstructions();
        while (!quit) {
            System.out.println("Enter your choice: ");
            int choice = scanner.nextInt();
            scanner.nextLine();
            switch (choice) {
                case 0:
                    printInstructions();
                    break;
                case 1:
                    groceryList.printGroceryList();
                    break;
                case 2:
                    addItem();
                    break;
                case 3:
                    modifyItem();
                    break;
                case 4:
                    removeItem();
                    break;
                case 5:
                    searchItem();
                    break;
                case 6:
                    processArrayList();
                case 7:
                    quit = true;
                    System.out.println("Good bye!");
                    break;
            }
        }
    }
    public static void printInstructions() {
        System.out.println("\nPress ");
        System.out.println("\t 0 - To print choice options.");
        System.out.println("\t 1 - To print the list of grocery items.");
        System.out.println("\t 2 - To add an item to the list.");
        System.out.println("\t 3 - To modify an item in the list.");
        System.out.println("\t 4 - To remove an item from the list.");
        System.out.println("\t 5 - To search for an item in the list.");
        System.out.println("\t 6 - To quit the application.");
    }
    private static void addItem() {
        System.out.println("This is add item function.");
        System.out.println("Please enter item name to add: ");
        String item = scanner.nextLine();
        groceryList.addGroceryItem(item);
    }
    private static void modifyItem() {
        System.out.println("This is modify item function.");
        System.out.println("Enter current item name: ");
        String item = scanner.nextLine();
        if (groceryList.onFile(item)) {
            System.out.println("Enter replacement item to modify: ");
            String newItem = scanner.nextLine();
            groceryList.modifyGroceryItem(item, newItem);
        } else {
            System.out.println(item + " is not in grocery list");
        }
    }
    private static void removeItem() {
        System.out.println("This is remove item function.");
        groceryList.printGroceryList();
        System.out.println("Enter item name to remove: ");
        String item = scanner.nextLine();
        groceryList.removeGroceryItem(item);
    }
    private static void searchItem() {
        System.out.println("This is search item function.");
        System.out.println("Enter Item to search: ");
        String searchItem = scanner.nextLine();
        if (groceryList.onFile(searchItem)) {
            System.out.println("found item: " + searchItem);
        } else {
            System.out.println("Not found: " + searchItem);
        }
    }
    public static void processArrayList() {
        ArrayList<String> newArray = new ArrayList<String>();
        newArray.addAll(groceryList.getGroceryList());
        // same as line 101~102
        ArrayList<String> newArray2 = new ArrayList<String>(groceryList.getGroceryList());
        // ArrayList convert to normal array
        String[] myArray = new String[groceryList.getGroceryList().size()];
        myArray = groceryList.getGroceryList().toArray(myArray);
    }

}

Список продуктов.java

import java.util.ArrayList;
public class GroceryList {
    private ArrayList<String> groceryList = new ArrayList();

    public ArrayList<String> getGroceryList() {
        return groceryList;
    }
    public void addGroceryItem(String item) {
        groceryList.add(item);
        System.out.println("You had add - " + item + " - to grocery list");
    }
    public void printGroceryList() {
        System.out.println("You have " + groceryList.size() + " items in your grocery list.");
        for (int i = 0; i < groceryList.size(); i++) {
            System.out.println((i + 1) + ". " + groceryList.get(i));
        }
    }
    public void modifyGroceryItem(String currentItem, String newItem) {
        int position = findItem(currentItem);
        if (position >= 0) {
            modifyGroceryItem(position, newItem);
        }
    }
    private void modifyGroceryItem(int position, String item) {
        groceryList.set(position, item);
        System.out.println("Grocery Item " + (position + 1) + " has been modified.");
    }
    public void removeGroceryItem(String item) {
        int position = findItem(item);
        if (position >= 0) {
            removeGroceryItem(position);
        } else {
            System.out.println("This item is not in grocery list.");
        }
    }
    private void removeGroceryItem(int position) {
        String theItem = groceryList.get(position);
        groceryList.remove(position);
        System.out.println("item: " + theItem + " had been removed.");
    }
    private int findItem(String searchItem) {
        return groceryList.indexOf(searchItem);
    }
    public boolean onFile(String searchItem) {
        int position = findItem(searchItem);
        return position >= 0;
    }
}

創了一個購物清單的功能

使用這種 ArrayList 就不用像使用 Array 添加跟刪除元素時都要重新創立一次

內部自動幫你完成操作

在 GroceryList.java 中

有些方法有重寫是因為 (例如:modifyGroceryItem)

要讓調用者 可用最直覺的方式去使用

一開始寫的是兩個參數

調用者還要知道位置參數是多少才能調用

顯然是非常不方便

所以重寫一個 只需輸入一個參數的

那就大大增加方便性啦

甚至還把重寫的 метод 改成 закрытый

這樣就只提供我們允許的 метод 給調用者做使用

也實現了 Инкапсуляция

不用回到調用的地方全部一起修改

Вимал 同學問:

Почему мы делаем повторяющиеся функции?

Горан 助教回答:

то, что вы предлагаете, не является хорошим дизайном. Есть хорошо известный принцип единой ответственности. Короче говоря, это означает, что 1 класс отвечает за 1 проблему. В этом случае класс GroceryList отвечает за управление списком продуктов, ему не нужно знать, как элементы будут добавлены в список. Элементы могут быть добавлены с помощью сканера (через консоль), другим способом может быть какой-либо пользовательский интерфейс, другим способом может быть из базы данных, другим способом может быть веб-служба и т. д.

Идея состоит в том, что GroceryList не нужно знать, как вы будете добавлять товар, ему просто нужна функция добавления/удаления товаров и т. д., и ничего больше. Таким образом, ваш GroceryList можно использовать с каким-либо другим приложением. У меня был случай, когда был список товаров, содержащий продукты, но он использовался на сервере с веб-приложением и на рабочем столе с пользовательским интерфейсом, поэтому вместо написания двух классов, представляющих список продуктов, было проще использовать один и тот же класс.

Надеюсь, это поможет.

我簡單總結:

Мингю 同學問:

Привет, Тим. В лекции 57 я не увидел никаких изменений после того, как удалил все методы scan.nextLine(), это просто безопасный способ убедиться, что сканер правильно считывает предстоящий ввод, очищая свой буфер, но что это значит?

Тим 老師回答:

Если вы выполняете scan.nextInt(), вы должны выполнить и scan.nextLine(), чтобы очистить буфер.

Это потому, что метод nextInt() считывает только числа, а не символы конца строки.

Если вы читаете строку, вам не нужно выполнять дополнительный вызов .nextLine(), поскольку исходный вызов .nextLine() считывает всю строку и символы конца строки.

Суть в том, что если вы используете .nextInt(), вам нужен .nextLine(), прежде чем вы сможете сделать другой .nextInt() или .nextLine()

Калян 同學問:

1.Почему мы не используем ключевое слово static для списка массивов?

2.Поскольку мы не используем статическое ключевое слово, к нему нельзя обращаться другими методами? Но он доступен? Сканер — это тоже класс, но он доступен только по ключевому слову static?

J 同學回答:

Статика означает, что существует только одна версия того, что идет с ним, даже если у вас есть миллион различных объектов, все они имеют одну и ту же основу. Вы можете сделать список статическим. Но это было бы непрактично. Представьте, что вы пишете программу списка покупок. Он позволяет пользователям составлять список покупок, сохраняя каждый элемент как значение в списке ArrayList.

Теперь, если вы сделаете этот ArrayList статическим и у него будет только 1 пользователь, тогда проблем не будет.

Но что, если есть два пользователя, которым нужно делать покупки, и у них разные списки?

Как бы вы отличали один список от другого? Вы бы не стали.

Поэтому вам нужно создать экземпляр массива. Единственный способ сделать это сделать список не статичным (и не окончательным).

小挑戰:

Создайте программу, реализующую простой мобильный телефон со следующими возможностями.

Возможность хранить, изменять, удалять и запрашивать имена контактов.

Вы захотите создать отдельный класс для контактов (имя и номер телефона).

Создайте мастер-класс (мобильный телефон), который содержит список контактов ArrayList.

Класс MobilePhone имеет перечисленные выше функциональные возможности.

Добавьте меню доступных опций.

Варианты: выйти, распечатать список контактов, добавить новый контакт, обновить существующий контакт, удалить контакт.

и поиск/найти контакт.

При добавлении или обновлении обязательно проверьте, существует ли уже контакт (используйте имя)

Не раскрывайте внутреннюю работу Arraylist для MobilePhone.

например без целых чисел, без .get(i) и т.д.

MobilePhone должен делать все только с контактными объектами.

解答:

Контакты.java

public class Contact {
    private String name;
    private String phoneNumber;
    public Contact(String name, String phoneNumber) {
        this.name = name;
        this.phoneNumber = phoneNumber;
    }
    public static Contact createContacts(String name, String phoneNumber) {
        return new Contact(name, phoneNumber);
    }
    public String getName() {
        return name;
    }
    public String getPhoneNumber() {
        return phoneNumber;
    }
}

Мобильный телефон.java

import java.util.ArrayList;
public class MobilePhone {
    private String myNumber;
    private ArrayList<Contact> myContacts;
    public MobilePhone(String myNumber) {
        this.myNumber = myNumber;
        this.myContacts = new ArrayList<Contact>();
    }
    public boolean addNewContact(Contact contact) {
        if (findContact(contact.getName()) >= 0) {
            System.out.println("Contact is already on file.");
            return false;
        }
        myContacts.add(contact);
        return true;
    }
    private int findContact(Contact contact) {
        return this.myContacts.indexOf(contact);
    }
    private int findContact(String contactName) {
        for (int i = 0; i < this.myContacts.size(); i++) {
            Contact contact = this.myContacts.get(i);
            if (contact.getName().equals(contactName)) {
                return i;
            }
        }
        return -1;
    }
    public String queryContact(Contact contact) {
        if (findContact(contact) >= 0) {
            return contact.getName();
        }
        return null;
    }
    public Contact queryContact(String name) {
        int position = findContact(name);
        if (position >= 0) {
            return this.myContacts.get(position);
        }
        return null;
    }
    public boolean updateContact(Contact oldContact, Contact newContact) {
        int foundPosition = findContact(oldContact);
        if (foundPosition < 0) {
            System.out.println(oldContact.getName());
            return false;
        } else if (findContact(newContact.getName()) != -1) {
            System.out.println("Contact with name " + newContact.getName() +
                    " already exists.");
            return false;
        }
        this.myContacts.set(foundPosition, newContact);
        System.out.println(oldContact.getName() + " was not found.");
        return true;
    }
    public boolean removeContact(Contact contact) {
        int foundPosition = findContact(contact);
        if (foundPosition < 0) {
            System.out.println(contact.getName());
            return false;
        }
        this.myContacts.remove(foundPosition);
        System.out.println(contact.getName() + " was deleted.");
        return true;
    }
    public void printContacts() {
        System.out.println("Contact List");
        if (this.myContacts.size() == 0) {
            System.out.println("You don't have any contact now.");
            return;
        }
        for (int i = 0; i < this.myContacts.size(); i++) {
            System.out.println((i + 1) + ". " +
                    "Name: " + this.myContacts.get(i).getName() +
                    " ---> " +
                    "Number: " + this.myContacts.get(i).getPhoneNumber());
        }
    }
}

main.java

import java.util.Scanner;
public class Main {
    private static Scanner scanner = new Scanner(System.in);
    private static MobilePhone mobilePhone = new MobilePhone("0988-321-123");
    public static void main(String[] args) {
        boolean quit = false;
        startPhone();
        printActions();
        while (!quit) {
            System.out.println("Enter number to action: ");
            int choice = scanner.nextInt();
            scanner.nextLine();
            switch (choice) {
                case 0:
                    quit = true;
                    System.out.println("Good bye!");
                    break;
                case 1:
                    mobilePhone.printContacts();
                    break;
                case 2:
                    addNewContact();
                    break;
                case 3:
                    updateContact();
                    break;
                case 4:
                    removeContact();
                    break;
                case 5:
                    queryContact();
                    break;
                case 6:
                    printActions();
                    break;
            }
        }
    }
    public static void addNewContact() {
        System.out.println("This is addNewContact function.");
        System.out.println("Enter new contact name: ");
        String name = scanner.nextLine();
        System.out.println("Enter phone number: ");
        String phone = scanner.nextLine();
        Contact newContact = Contact.createContacts(name, phone);
        if (mobilePhone.addNewContact(newContact)) {
            System.out.println("New contact added: " + name + ", phone = " + phone);
        } else {
            System.out.println("Cannot add, " + name + " already phone...");
        }
    }
    private static void updateContact() {
        System.out.println("This is updateContact function.");
        System.out.println("Enter existing name to update: ");
        String name = scanner.nextLine();
        Contact existingContactRecord = mobilePhone.queryContact(name);
        if (existingContactRecord == null) {
            System.out.println("Contact not found.");
            return;
        }
        System.out.println("Enter new contact name");
        String newName = scanner.nextLine();
        System.out.println("Enter new contact phone number");
        String newNumber = scanner.nextLine();
        Contact newContact = Contact.createContacts(newName, newNumber);
        if (mobilePhone.updateContact(existingContactRecord, newContact)) {
            System.out.println("Successfully updated record.");
        } else {
            System.out.println("Error updated.");
        }
    }

    private static void removeContact() {
        System.out.println("This is removeContact function.");
        System.out.println("Enter existing name to remove: ");
        String name = scanner.nextLine();
        Contact existingContactRecord = mobilePhone.queryContact(name);
        if (existingContactRecord == null) {
            System.out.println("Contact not found.");
            return;
        }
        if (mobilePhone.removeContact(existingContactRecord)) {
            System.out.println("Successfully deleted");
        } else {
            System.out.println("Error deleting contact");
        }
    }
    private static void queryContact() {
        System.out.println("This is queryContact function.");
        System.out.println("Enter existing name to query: ");
        String name = scanner.nextLine();
        Contact existingContactRecord = mobilePhone.queryContact(name);
        if (existingContactRecord == null) {
            System.out.println("Contact not found.");
            return;
        }
        System.out.println("Name: " + existingContactRecord.getName() + " phone number is " + existingContactRecord.getPhoneNumber());
    }

    private static void startPhone() {
        System.out.println("Start phone ------");
    }
    private static void printActions() {
        System.out.println("\nAvailable actions:\nPress number of list.");
        System.out.println("0  - to shutdown\n" +
                "1  - to print contacts\n" +
                "2  - to add a new contact\n" +
                "3  - to update an existing contact\n" +
                "4  - to remove an existing contact\n" +
                "5  - query if an existing contact exists\n" +
                "6  - to print a list of available actions.");
    }

}

我的領悟:

原本 метод 的參數都是用 Имя строки、целое число 等

這次突然放了一個自己創的 class,剛開始搞不懂看了半天

去翻QA助教回答才理解

medthod(String name) 就只是用原本定義好的 class String

而我們這次用的就是自創的 класс

метод(имя класса)

這都是屬於 ООП 的範疇

突然有一種茅塞頓開的感覺

但這次的內容還是很難

為了搞懂前後看了3次

也只是看懂能修改

要我完全自己寫就無法

同學問:

Hi,

я экспериментировал с функцией поиска, чтобы найти базу контактов по имени,

Сначала я попытался использовать это:

if(mobile.getName() == name) {
    return i;
}

В котором он дает мне false, даже если я ввожу правильно (с учетом регистра)

Итак, я попробовал следующее:

if(mobile.getName().equals(name)) {
    return i;
}

и это работает...

Объясните, пожалуйста, в общих чертах, почему нижний работает, а верхний нет? это влияет только на объекты?

老師答:

== возвращает значение true, только если сравнивается один и тот же объект в памяти.

.equals(), с другой стороны, правильно проверяет, совпадают ли имена.

Если вы хотите проверить равенство объектов, используйте .equals() для примитивных типов

или если вы хотите проверить, идентичны ли экземпляры одного и того же объекта, используйте ==.

我簡單總結:

== 為同個物件的比較

.equals() 名稱的比較

同學問:

Привет, Тим.

Вы упомянули в начале статьи о деньгах при написании этого кода:
важно, чтобы он был статичным.
не могли бы вы объяснить это подробнее? я все еще пытаюсь полностью понять концепции STATIC и RETURN. я чувствую его кончиками пальцев, но все еще не понимаю его полностью. может быть, вы могли бы объяснить мне это лучше.
спасибо!

public static Contact createContact(String name, String phoneNumber) {
    return new Contact(name, phoneNumber);
}

同學答:

Эти две темы могут быть трудными для понимания, но давайте на пару минут отвлечемся от этих терминов и попробуем придумать аналог для них в реальном мире. Допустим, вы в банке, вы, клиент, стоите с одной стороны прилавка, а сотрудники стоят за прилавком. Вы хотите внести депозит, поэтому вы заполнили бланк депозита и получили деньги на руки. Вы передаете сотруднику свой депозитный ордер и деньги. Они работают в течение нескольких минут, затем распечатывают квитанцию ​​​​и вручают ее вам. Вы только что выполнили реальный эквивалент вызова метода. Депозитная квитанция и деньги, которые вы держите, являются вашими аргументами, которые вы передаете методу, они также являются параметрами, с которыми вы встречаетесь, чтобы выполнить транзакцию (запустить метод). Квитанция, которая распечатывается и возвращается вам, аналогична методу, возвращающему что-то обратно коду, который его вызвал.

Статический метод объяснить немного сложнее, потому что он ведет себя иначе, если применяется к методу или переменной (полю). Статическая переменная — это переменная, которая запоминает свое значение между использованиями. Она создается вне метода, и методы могут взаимодействовать с ней и изменять значение по своему усмотрению, но вместо того, чтобы уничтожаться после выполнения метода, переменная остается неизменной до тех пор, пока не появится следующий метод для ее изменения.

С другой стороны, статический метод — это метод, являющийся членом класса, но способный работать отдельно. Обычно при работе с объектами вам необходимо создать экземпляр объекта, чтобы вызвать содержащиеся в нем методы. Примером этого является Car car = new Car();. Он создает новый экземпляр типа класса Car и сохраняет его в переменной с именем car. Затем вы вызываете методы, принадлежащие этому классу, запустив car.methodName() Поскольку статические методы являются автономными, это означает, что вы можете вызывать их без создания нового экземпляра типа класса. Вы делаете это, указав класс, а затем имя метода. Car.methodName() Это запускает метод methodName внутри класса Car, но для этого не нужно создавать новый Car.

Код, который вы вставили выше, представляет собой «автономный» метод, который создает новый экземпляр объекта Contact и передает его коду, вызвавшему его. Это позволяет вам создать новый контакт без необходимости создания временного экземпляра класса, к которому принадлежит createContact() перед вызовом метода.

我簡單總結:

用 static 就不需另外創 объект 來調用 метод

本篇使用代碼