學習軌道
/
Java
Java
/
練習
/
Karl 的語言
Karl 的語言

Karl 的語言

學習練習

簡介

泛型

泛型是一種依型別參數化的泛型類別或介面。這讓編譯器能對該類別或介面強制執行型別安全。

來看看這個非泛型的Container介面:

class Container {
    private Object object;

    public void set(Object object) { this.object = object; }
    public Object get() { return object; }
}

由於它接受並回傳 Object 型別,因此可以搭配任何非基本型別使用。然而,這麼做是有代價的:有些程式碼呼叫get時預期得到Integer,其他程式碼卻呼叫set加入String,最後在執行時期拋出例外。

泛型類別與泛型介面的格式如下:

class ClassName<T1, T2, ..., Tn> { ... }
interface InterfaceName<T1, T2, ..., Tn> { ... }

接在類別或介面名稱之後、以尖括號(<>)包住的那一段是型別參數區段,用來指定型別參數(也稱為型別變數)T1、T2、……、Tn。這些型別參數可以在類別或介面的主體內使用,以獲得泛型的型別安全。

以下是Container的泛型版本:

class Container<E> {
    private E object;

    public void set(E object) { this.object = object; }
    public E get() { return object; }
}

建立時,我們得宣告它要裝哪種型別,編譯器就會強制執行這項限制:

// empty <> can infer from context
Container<String> stringContainer = new Container<>();
// compiler knows this is a String, so it is allowed
stringContainer.set("Some string");
// no cast needed, compiler knows it is a String
String result = stringContainer.get();
// this causes a compiler error:
stringContainer.set(42);

清單

清單是 Java 中的有序序列集合。與陣列不同,List 可以增長大小,容納任意數量的項目。其中一個標準實作是ArrayList,底層是可重新調整大小的陣列。另一個標準實作是LinkedList類別,底層是雙向鏈結串列。

List可以是空的,也可以存放任意數量的項目(包括重複的項目)。List是一種泛型介面,會標示它可以包含哪種型別的物件。例如:

List<String> emptyListOfStrings = List.of();
List<Integer> singleInteger = List.of(1);
List<Boolean> threeBooleans = List.of(true, false, true);
List<Object> listWithMultipleTypes = List.of("hello", 1, true);

List提供了許多實用的方法,可以新增、移除、取得元素,以及檢查某個元素是否存在:

List<Character> vowels = new ArrayList<>(List.of('a', 'e', 'i', 'o', 'i', 'e', 'a'));
int startingSize = vowels.size(); // 7
vowels.add('u'); // vowels is now ['a', 'e', 'i', 'o', 'i', 'e', 'a', 'u']
char a = vowels.get(0); // 'a'
boolean hadI = vowels.remove('i'); // true and vowels is now ['a', 'e', 'o', 'i', 'e', 'a', 'u']
boolean hasI = vowels.contains('i'); // true (still have one more left)

說明

Karl 想在 Exercism 網站上記錄他想學習的語言陣列。 Karl 需要能夠新增語言、移除舊語言,以及檢查某些語言是否在陣列中。 要是 Karl 想學 Java 或 Kotlin,那會非常令人興奮喔!

1. 定義一個函式來檢查語言陣列是否為空

Karl 需要知道他的語言陣列是否會變成空的,這樣他才能去找更多語言來學! 定義一個叫做isEmpty的方法,如果陣列中沒有語言,就回傳true。

if (languageList.isEmpty()) {
    findMoreLanguagesToLearn();
}

2. 定義一個函式來把語言加入陣列

Karl 很期待學習 Kotlin 和 Python! 定義一個叫做addLanguage的方法,它會接收他想學習的語言並把它加入陣列,來幫 Karl 踏出第一步。

languageList.addLanguage("Kotlin");
languageList.addLanguage("Python");

3. 定義一個函式來從陣列中移除語言

Karl 決定他現在不想學 Scala 了。 定義一個叫做removeLanguage的方法,它會接收他正在移除的語言並把它從陣列中移除,來幫 Karl 把它拿掉。

languageList.removeLanguage("Scala");

4. 定義一個函式來回傳陣列中的第一個項目

Karl 想記住他加入陣列的第一個語言(而且還留在陣列裡的那個)。 定義一個叫做firstLanguage的方法,它會回傳陣列中的第一個語言。

String kotlin = languageList.firstLanguage(); // "Kotlin"

5. 定義一個函式來回傳陣列中有多少個語言

Karl 需要知道他總共想學多少個語言。 定義一個叫做count的方法,它會回傳陣列中的語言數量,來幫 Karl 找出答案。

int two = languageList.count(); // 2

6. 定義一個函式來判斷某個語言是否在陣列中

Karl 正在努力回想他到底想不想學 Python 或 Ruby。 定義一個叫做containsLanguage的方法,它會接收他詢問的語言,這樣 Karl 就能查個明白!

boolean learningPython = languageList.containsLanguage("Python"); // true
boolean learningRuby = languageList.containsLanguage("Ruby"); // false

7. 定義一個函式來判斷這個陣列是否令人興奮

如果 Karl 想學 Java 或 Kotlin,那就非常令人興奮! 定義一個叫做isExciting的方法,如果 Karl 想學 Java 或 Kotlin 就回傳 true。

javaLanguageList.isExciting() // true
neitherKotlinNorJavaLanguageList.isExciting() // false
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
Java Exercism

準備好開始 Karl 的語言 了嗎?

註冊 Exercism,透過 26 個概念158 個練習 和真人引導來學習並精通 Java,全部免費。