本文是系列文章「Java 初階篇」的第三章,開始認識基礎語法。

1. Variable, Assignment

  • 變數(Variable)、賦值(Assignment)是任何程式語言的基本概念。
int x; // 資料型態 變數名稱
x=5; // 將值指定給變數

int x = 5; // 可以寫成一行
  • 變數的值可改變,例如int x = 10
  • 在 Java 中=(等號)是賦值的意思,將等號右邊的值放到等號左邊,例如:
public class Main {
    public static void main(String[] args) {
        int x = 5;
        x = x + 1;
        System.out.println(x);
    }
}

輸出結果:

6
  • 語法糖:x = x + 1可縮寫成x += 1
  • 變數名稱不能是數字開頭、不能是 Java 關鍵字。
  • 常量(Constants):指定義不能改變的量。加入 final 就可以設定 Constants Variable,例如:
public class Main {
    public static void main(String[] args) {
        final double PI = 3.14;
    }
}

加入 final 後,PI 則不能被改變。

  • 命名習慣 1:Constants 全部用大寫英文字母表示。
  • 命名習慣 2:ClassMame 與 Variable 用 camelCase,例如numberOfMyAge
  • 命名習慣 3:Constants 過長,可用底線_分隔,例如MAX_VALUE

2. Data Type

對電腦而言,資料都只是 0 跟 1,為了方便程式設計師作業,Java 會事先定義好一些資料類型(Data Type),分為基本資料類型(Primitive type)、參考資料類型(Reference type)。

Java 常見的資料類型有:

  • var:用於任何資料類型。
  • int:Integer 整數,使用 32bits 儲存數據。(範圍值:2^31-1 ~ -2^31)
  • long:整數,使用 64bits 儲存數據。
  • float:有小數點的數,使用 32bits 儲存數據。
  • double:有小數點的數,使用 64bits 儲存數據。
  • char:Character,單一字母。
  • String:a sequence of characters,字串。
  • boolean:true or false。

Primitive 資料類型:

  • Primitive 由 Java 預先定義,並保留關鍵字命名。
  • Java 支持的八種原始數據類型:byte、short、int、long、float、double、boolean、char。
  • 除了八種原始數據類型之外,都是 Non-primitive。
  • 常見的 Non-primitive 資料類型:String、Array、Arraylist、Class。
  • Non-primitive 資料類型都是大寫英文字母開頭,Primitive 資料類型都是小寫英文字母開頭。

Reference 資料類型:

  • 只要是非 Primitive 的資料類型,都是屬於 Reference 資料類型。

數值範圍:

  • short:32767 ~ -32768
  • int:2147483647 ~ -2147483648
  • long:9223372036854775807 ~ -9223372036854775808
  • byte:127 ~ -128
  • float:3.402823e+38 ~ 1.401298e-45
  • double:1.797693e+308 ~ 4.900000e-324

2.1 Primitive type 與 Reference type 的差異

記憶體區間:

  • Global 全域:存放全域變數(Global variable)、靜態變數(Static variable)。
  • Stack 推疊區:存放可被預測的資料,如區域變數(Local variable)、方法的參數(Method parameter)、方法的回傳位址(Method return address)等。
  • Heap 堆積區:存放不可被預測的資料。

Primitive type:

int i ; // 宣告一個變數i,在stack區切一個int的空間,Java將其初始化為0。
i = 5; // 將整數5指定給變數i。

Reference type:

Human ken; // 宣告一個變數ken,在stack區切一個reference的空間,reference預定指向物件Human,Java將其初始化為null(無指向)。
tina = new Human(); // 「new」關鍵字利用建構子建構物件,將物件存放在Heap區,「=」指定運算子將Heap區的物件的地址指定給變數ken。

所以當你有了以上 Reference 的概念,就知道 Reference type 需要配合 new 關鍵字,而 Heap 區需要有物件實體,否則你會存取到 null 的物件變數。

3. String

字串(String)就是把字元串在一起,形成一種陣列,例如「ABCDEFG」。

【範例:將字串轉換為小寫】

public class Main {
    public static void main(String[] args) {
        String name = "Louis";
        System.out.println(name.toLowerCase());
    }
}

輸出結果:

louis

【範例:將字串轉換為大寫】

public class Main {
    public static void main(String[] args) {
        String name = "Louis";
        System.out.println(name.toUpperCase());
    }
}

輸出結果:

LOUIS

【範例:取字串的第一個字母】

public class Main {
    public static void main(String[] args) {
        String name = "Louis";
        System.out.println(name.charAt(0));
    }
}

輸出結果:

L

因為字母位置是 0、1、2、……、n - 1。

【範例:取字串最後一個字】

public class Main {
    public static void main(String[] args) {
        String name = "Louis";
        System.out.println(name.charAt(name.length() - 1));
    }
}

拿字串長度去減 1,得到最後一個字母的位置。 輸出結果:

s

【範例:取得字串中某字母的位置】

public class Main {
    public static void main(String[] args) {
        String name = "Louis";
        System.out.println(name.indexOf('s'));
    }
}

indexOf得到 s 的位置。 輸出結果:

4

【範例:將字串轉換為整數】

public class Main {
    public static void main(String[] args) {
        String age = "33";
        System.out.println(Integer.parseInt(age));
    }
}

輸出結果:

33

4. Relational, Conditional Operator

  • Relational(關係)的 Operator(運算子)包含:==(等於)、!=(不等於)、><>=<=
public class Main {
    public static void main(String[] args) {
        System.out.println(1 == 1);
        System.out.println(1 != 1);
        System.out.println(!(1 == 1));
        System.out.println(!true);
    }
}

輸出結果:

true
false
false
false
  • Conditional(條件)的 Operator(運算子)包含:&&(and)、||(or)。
public class Main {
    public static void main(String[] args) {
        System.out.println(true && true);
        System.out.println(true || false);
        System.out.println(false || false);
        System.out.println((6 > 4) && (3 < 1));
    }
}

輸出結果:

true
true
false
false
  • ==用在 primitive data type 之間的比較。
  • .equals()Non-primitive data type 之間的比較。
public class Main {
    public static void main(String[] args) {
        System.out.println("Louis".equals("Louis"));
    }
}

輸出結果:

true

5. Arithmetic Operator

算術運算子(Arithmetic Operator)主要用作數字運算,常見的運算有:

  • number + number:加法 addition。
  • string + string:串接 concatenation。
  • number + string:串接 concatenation。
  • number * number:乘法 multiplication。
  • number * string:not valid。
  • int / int:gives you only integer result。
  • float / int:gives you a floating result。
public class Main {
    public static void main(String[] args) {
        System.out.println(20 + 20);
        System.out.println("20" + "20");
        System.out.println(20 + "20");
        System.out.println((20 + "20").getClass().getName());
        System.out.println(20 + 20 + "20" + 20 + 20);
        System.out.println(20 * 20);
        System.out.println(5 / 10);
        System.out.println(9 / 10);
        System.out.println(9.0 / 10);
    }
}

輸出結果:

40
2020
2020
java.lang.String
40202020
400
0
0
0.9

6. if statement

  • if 語句用於決定是否執行某語句,若某條件為真,則執行語句,否則不執行。

【範例 1】

public class Main {
    public static void main(String[] args) {
        boolean a = false;

        if (a) {
            System.out.println("a is true");
        } else {
            System.out.println("a is false");
        }
    }
}

輸出結果:

a is false

【範例 2】

public class Main {
    public static void main(String[] args) {
        int age = 25;

        if (age >= 0 && age <= 17) {
            System.out.println("你是小屁孩");
        } else if (age >= 18 && age < 30) {
            System.out.println("你是小鮮肉");
        } else if (age >= 30 && age <= 65) {
            System.out.println("你老了,回家吃自己");
        } else {
            System.out.println("回家養孫子");
        }
    }

}

輸出結果:

你是小鮮肉

7. 小試身手:BMI 計算機

【範例】

public class Main {
    private static final DecimalFormat DF = new DecimalFormat("0.00");

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("輸入體重:");
        double weight = scanner.nextDouble();

        System.out.print("輸入身高:");
        double height = scanner.nextDouble() / 100;

        double bmi = Double.parseDouble(DF.format(weight / (height * height)));
        System.out.println("BMI:" + bmi);

        if (bmi < 18.5) {
            System.out.println("過輕");
        } else if (bmi < 24) {
            System.out.println("正常");
        } else if (bmi < 30) {
            System.out.println("微胖");
        } else {
            System.out.println("過胖");
        }
    }
}

輸出結果:

輸入體重65.5
輸入身高171
BMI22.4
正常

在這範例中有用到 Scanner 物件做標準輸入(就是利用鍵盤輸入文字的意思),只要是想要跟使用者互動,請使用者進行輸入,就可以用 Scanner 物件。

Scanner 類別放在 java.util 套件中,所以我們要先在 class 外面做 import:

import java.util.Scanner;

再來看 System 物件裡面有靜態欄位「in」,可用來初始化 Scanner 物件。例如有個叫「i」的 Scanner 物件,讓他幫我們從標準輸入中拿資料進來:

Scanner i = new Scanner(System.in);

8. 小試身手:疫苗種類查詢

【範例】

public class Main {

    public static void main(String[] args) {
        String vaccine = JOptionPane.showInputDialog("輸入動物名稱(Dog, Cat, Duck):");
        vaccine = vaccine.toLowerCase();

        if (vaccine.equals("dog")) {
            JOptionPane.showMessageDialog(null, "Dog\n出生國家:日本\n毛色:棕色\n個性:黏人\n可愛度:81%");
        } else  if (vaccine.equals("cat")) {
            JOptionPane.showMessageDialog(null, "Cat\n出生國家:德國\n毛色:橘色\n個性:兇巴巴\n可愛度:40%");
        } else  if (vaccine.equals("duck")) {
            JOptionPane.showMessageDialog(null, "Duck\n出生國家:美國\n毛色:白色\n個性:呆\n可愛度:79%");
        } else {
            JOptionPane.showMessageDialog(null, "無法辨別,請重新輸入");
        }
    }
}

9. Array and ArrayList

  • Array(陣列):在單個變量中儲存多個值。

【範例 1:取位置 0 的字串】

public class Main {
    public static void main(String[] args) {
        String[] dog = {"a", "b", "c", "d"};
        System.out.println(dog[0]);
    }
}

輸出結果:

a

【範例 2:取位置 0、1、2 的字串】

public class Main {
    public static void main(String[] args) {
        String[] dog = new String[5];
        dog[0] = "a";
        dog[1] = "b";
        System.out.println(dog[0]);
        System.out.println(dog[1]);
        System.out.println(dog[2]);
    }
}

輸出結果:

a
b
null
  • ArrayList(動態陣列):一個可調整大小的 Array。

【範例 1:取字串長度】

public class Main {
    public static void main(String[] args) {
        ArrayList<String> dog = new ArrayList<>();
        dog.add("a");
        dog.add("b");
        dog.add("c");
        System.out.println(dog.size());
    }
}

輸出結果:

3

【範例 2:取位置 0 的字串】

public class Main {
    public static void main(String[] args) {
        ArrayList<String> dog = new ArrayList<>();
        dog.add("a");
        dog.add("b");
        dog.add("c");
        System.out.println(dog.get(0));
    }
}

輸出結果:

a

【範例 3:將字串排序】

public class Main {
    public static void main(String[] args) {
        ArrayList<String> dog = new ArrayList<>();
        dog.add("a");
        dog.add("c");
        dog.add("b");
        Collections.sort(dog);
        System.out.println(dog);
    }
}

輸出結果:

[a, b, c]

【範例 4:將字串清空】

public class Main {
    public static void main(String[] args) {
        ArrayList<String> dog = new ArrayList<>();
        dog.add("a");
        dog.add("c");
        dog.add("b");
        dog.clear();
        System.out.println(dog.size());
    }
}

輸出結果:

0

10. 2D Array

【範例:大 Array 中放 4 個小 Array,每個小 Array 中放 3 個整數,輸出第 2 個小 Array 中的第 0 的整數】

public class Main {
    public static void main(String[] args) {
        int[][] dog = new int[4][3];
        dog[2][0] = 10;
        dog[0][2] = 3;
        System.out.println(dog[2][0]);
    }
}

輸出結果:

10

11. For Loop

  • for 迴圈是一種控制語句,重複執行 Java 程式中的某部分。
  • 語法糖:i = i + 1 => i += 1 => i++

【範例 1:若 i 小於 6,則輸出 i,然後 i + 1】

public class Main {
    public static void main(String[] args) {
        for (int i = 0; i < 6; i = i + 1) {
            System.out.println(i);
        }
    }
}

輸出結果:

0
1
2
3
4
5

【範例 2:運用 for 迴圈輸出 Array 中的字串】

public class Main {
    public static void main(String[] args) {
        String[] dog = {"a", "b", "c", "d"};

        for (int i = 0; i <= dog.length - 1; i++) {
            System.out.println(dog[i] + " is a dog.");
        }
    }
}

輸出結果:

a is a dog.
b is a dog.
c is a dog.
d is a dog.

【範例 3:運用 for 迴圈的常見語法輸出 Array 中的字串】

public class Main {
    public static void main(String[] args) {
        String[] dog = {"a", "b", "c", "d"};

        for (String animal : dog) {
            System.out.println(animal + " is a dog.");
        }
    }
}

輸出結果:

a is a dog.
b is a dog.
c is a dog.
d is a dog.

12. while loop

  • while 迴圈是一種控制流語句,根據 boolean 條件,重複執行 Java 程式中的某部分。
  • 使用時機:已知 loop 執行次數則用 for,不知 loop 執行次數則用 while。

【範例】

public class Main {
    public static void main(String[] args) {
        int i = 0;
        while (i < 10) {
            System.out.println("Hello World! x " + i);
            i++;
        }
    }
}

輸出結果:

Hello World! x 0
Hello World! x 1
Hello World! x 2
Hello World! x 3
Hello World! x 4
Hello World! x 5
Hello World! x 6
Hello World! x 7
Hello World! x 8
Hello World! x 9

13. Nested Loops

  • 巢狀迴圈(Nested Loop):一個迴圈內放另一個迴圈。

【範例】

public class Main {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            for (int j = 3; j > 0; j--) {
                System.out.println(i + ", " + j);
            }
        }
    }
}

輸出結果:

0, 3
0, 2
0, 1
1, 3
1, 2
1, 1
2, 3
2, 2
2, 1
3, 3
3, 2
3, 1
4, 3
4, 2
4, 1
5, 3
5, 2
5, 1
6, 3
6, 2
6, 1
7, 3
7, 2
7, 1
8, 3
8, 2
8, 1
9, 3
9, 2
9, 1

14. break, continue

  • break:中斷
  • continue:繼續

【範例:break】

public class Main {
    public static void main(String[] args) {
        int i = 0;
        while (true) {
            if (i == 5) {
                break;
            }
            System.out.println(i);
            i++;
        }
    }
}

輸出結果:

0
1
2
3
4

【範例:continue】

public class Main {
    public static void main(String[] args) {
        for (int i = 0; i < 15; i++) {
            if (i == 10) {
                continue;
            }
            System.out.println(i);
        }
    }
}

輸出結果:

0
1
2
3
4
5
6
7
8
9
11
12
13
14

15. 小試身手:終極密碼遊戲

【範例】

public class Main {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int min = 0;
        int max = 100;
        Random r = new Random();
        int secret = r.nextInt(max - min) + min;
        System.out.println("number is " + secret);

        while (true) {
            System.out.print(min + ", " + max + ": ");
            int guess = s.nextInt();

            if (guess < min || guess > max) {
                System.out.println("please make a valid guess.");
                continue;
            }

            if (guess == secret) {
                System.out.println("You win!: " + secret);
                break;
            } else if (guess < secret) {
                min = guess;
            } else {
                max = guess;
            }
        }
    }
}

輸出結果:

number is 21
0, 100: 70
0, 70: 40
0, 40: 30
0, 30: 20
20, 30: 25
20, 25: 23
20, 23: 22
20, 22: 21
You win!: 21

16. static

關鍵字 static(靜態)用來修飾成員(屬性、方法、子類別),將其成員變成靜態成員。有無 static 的差異在於載入記憶體的時機,只要一開始就存在於記憶體當中就稱為 static,而無 static 就是程式開始執行後才跟記憶體要求空間。

【無 static】

class Test{
  public static void main(String[] args){
    int i = 5;
    System.out.println(i);
  }
}

輸出結果:

5

【有 static】

class Test{
  static int i = 5;
  public static void main(String[] args){
    System.out.println(i);
  }
}

輸出結果:

5

17. Java GUI

【範例】

public class Main extends JPanel {

    @Override
    public  void paintComponent(Graphics g){
        g.drawString("ABC", 100, 100);
    }

    public static void main(String[] args) {
        JFrame window = new JFrame();
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setSize(300, 300);
        window.setContentPane(new Main());
        window.setVisible(true);
    }
}

18. drawLine, setColor, drawRect, fillRect

【範例:drawLine】

public class Main extends JPanel {

    @Override
    public  void paintComponent(Graphics g){
        g.drawLine(10,10,50,50);
    }

    public static void main(String[] args) {
        JFrame window = new JFrame();
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setSize(300, 300);
        window.setContentPane(new Main());
        window.setVisible(true);
    }
}

【範例:setColor】

public class Main extends JPanel {

    @Override
    public  void paintComponent(Graphics g){
        g.setColor(Color.RED);
        g.drawLine(10,10,50,50);
    }

    public static void main(String[] args) {
        JFrame window = new JFrame();
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setSize(300, 300);
        window.setContentPane(new Main());
        window.setVisible(true);
    }
}

【範例:drawRect】

public class Main extends JPanel {

    @Override
    public  void paintComponent(Graphics g){
        g.setColor(Color.RED);
        g.drawRect(100,100,50,70);
    }

    public static void main(String[] args) {
        JFrame window = new JFrame();
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setSize(300, 300);
        window.setContentPane(new Main());
        window.setVisible(true);
    }
}

【範例:fillRect】

public class Main extends JPanel {

    @Override
    public  void paintComponent(Graphics g){
        g.setColor(Color.RED);
        g.fillRect(100,100,50,70);
    }

    public static void main(String[] args) {
        JFrame window = new JFrame();
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setSize(300, 300);
        window.setContentPane(new Main());
        window.setVisible(true);
    }
}