文章加密

;

2020年11月10日 星期二

Java Udemy學習筆記

  •  Jshell (裝了java jdk就有了)
    指令:
    /imports 會列出jshell default import
    /methods 會列出所有已宣告的方法
    /save  backup.txt: 會把這次jshell行為裡已宣告的方法存入backup.txt這支檔案裡
    /edit nameOfTheMethod  進入編輯器,修改後按accept即可修改
    /list nameOfTheMethod  列出該method的完整code
    /list nameOfTheClass  列出該class的完整code

    快捷鍵:
    按右鍵是貼上
    想知道object可用的methods可在其名稱後+dot+tab
    ctrl+a 可以快速到line的頭
    ctrl+e 可以快速到line的尾
    ctrl+r 並打入欲搜尋的內容,會出現輸入歷史中的相符結果,要在切換下一個可在按ctrl+r
  • JAVA JDK(Java development kit)
  • 5.0/2 結果是2.5 (就算在js也一樣) => 在做運算時,operand的型別決定結果型!
  • modulus operator 是 %
  • precedence * / %  優先於 + -
  • System.out.println(3*4) 
    "println" is a shortcut of "print line".
    System is a class in Java
    out is one of System's variables
    println is one of out's variables
  • semicolon 分號, hyphen等同minus等同 - ,decimal 小數
  • 5*2 唸作5 into 2
  • formatter, modifier  (ex: %d for integer number, %s for string, %f for floating number) 
  • declaration 定義 ex: int count = 1,assignment指派 count = 2
  • System.out.printf(" %d + %d + %d = %d", a, b, c. a+b+c)  <= a, b, c需先定義  
  • Primitive data types 原始型別

    定義數字根據範圍有不同的型別 (整數篇)
    byte b = 5;   //  8 bits, range from -128 to 127
    short s = 128; // 16 bits, -32,768 to 32767  (2 bytes)
    int i = 4000; // 32 bits, -2,147,483,648 to 2,147,483,647 (4 bytes)
    long l =222222222;  // 64 bits, -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807  (8 bytes)


    float f = 4.0f;  // 32 bits, NOT VERY PRECISE - don't use for financials  (4 bytes) 
    double d = 67.0;  // 64 bits, NOT VERY PRECISE - don't use for financials  
    (8 bytes) 
    ( 所有浮點數都會在編譯時被默認為double型別,如果不想,則要在value後加上f )
    (5.2 的type是 double,不是float)
    ( double消耗記憶體是float的兩倍,double的運算速度比float慢得多 )

    char c = 'A'; // 16 bits '\u0000' to '\uffff'
    // 必須用單引號,不能是雙引號
    // character data type has two bypes

    ( 范围:0到65535。它不过对应的是unicode的编码值,即全球语言统一编码。)
    ( https://zhidao.baidu.com/question/67903571 )

    char ch='\u00F7';  //  '÷'
    char ch = 65;  //  'A'
    ++ch; //  'B'
    ch+5; // 71,char 和 int 的運算結果會是int,因為int佔4 bytes > char 佔 2bytes。也就是說,所有可以在int上做的運算都可以在char上做!
    接著在印出ch會仍是'B',因為上一行並沒有賦值
    (int) ch; // 66
    char ch='\n';  // 可以存新的一行
    char ch='\t';  // 可以存tab
    unicode對照表: https://en.wikipedia.org/wiki/List_of_Unicode_characters

    boolean isTrue = false; // true or false
    (case sensitive)


  • unicode values: 它對世界上大部分的文字系統進行了整理、編碼,使得電腦可以用更為簡單的方式來呈現和處理文字,即全球语言统一编码。也被稱為 ASCII  values,American Standard Code for Information Interchange
  • punctuation: noun 標點符號
  • exclamation mark: noun 驚嘆號
  • lossy: adj 損耗電子能量的
  • concatenation: noun  一連串有關聯的事件、想法或事物
  • compound: noun 複合詞
  • shortcut key 快捷鍵
  • alphabet 字母
  • at hand: (時間上)臨近;在附近
  • inbuilt: adj 內建的,原本就建立的(原本就有的)
  • predefined: adj 預先設定的
  • mandatory: adj 強制的
  • incompatible: adj 不相容的
  • backup: noun
    1.備份
    2.後備、後援、支援  I’ll talk to Jane about my plan tonight, and hopefully she’ll back me up.
    3.巴庫、退後  I can’t get my car out. Could you please back up your car a little?
                             You’re standing too close to me. Please back up.
  • back up: verb ph 1.備份 2.支持
  • if ()沒有用{}時,只會執行一行程式。這一行以分號做區分!
  • 列出前十個平方數為偶數的值:
    for( i = 2; i <= 20; i = i + 2 ){
       System.out.printf("%d",  i * i ).println();
    }

    列出前十個平方數為奇數的值:
    for( i = 1; i <= 20; i = i + 2 ){
       System.out.printf("%d",  i * i ).println();
    }
  • empty statement
     
    int i = 1;
    for( ; i < 10 ; i++ );  // no error
    System.out.println(i);  // 10
    // 對於for condition裡面必須的就是兩個分號,其他都可以不用,只是可能會跑成無窮迴圈
  • for ( ; ; );  is an infinite loop
    it never returns back. Because the condition is empty, that means it's true always and it keeps executing.
  • int i, int j;
    for(i=1, j=2; i<10; i++, j++);
    System.out.println(i);  // 10
    System.out.println(j);  // 11
    // j 初始為 2,之後++次數和i相同。當i<10不成立時,即終止迴圈!
  • as far as sb is concerned 依照sb的想法
    as far as sth is concerned 根據sth
  • method的寫法:
    returnType nameOfTheMethod(type argumentName) {
       // ...
    }

    void sayHelloWorld(int noOfTimes) {      //  當沒有回傳時用 void 
       // ...
    }
  • Class name 第一個letter會大寫 ex: System, Math
    Method name 第一個letter會小寫  ex: sayHelloWorldTwice, max
  • Arguments ( Values Passed ) v.s. Parameters ( Method Definition )
  • Method overloading: java沒有給parameter預設參數的行為,所以要建立兩個很像的method
    void print(int i){
       System.out.println(i);
    }

    void print(){
        System.out.println(5);
    }

"from bytecode to instruction and run the program" is excecute

platform independence is archieved in Java through bytecode and JVM.


  • JDK: JRE + Compilers + Debuggers // 開發與執行java programs需要的,application developer 使用
    JRE: JVM + Libraries + Other Components // 執行java programs需要的,application user 使用
  • JVM: Java Virtual Machine, convert the bytecode into executable instructions on that specific operating system. 
    情境題:
      如果我有java檔,要用它必須有JDK,因為需先compile
      如果我有class檔,只要有JRE,因為需要JVM
  • compiler: noun 編譯器
  • debugger: noun 除錯工具
  • basic construction: All computers understand are 0, 1, and they are called basic instructions.
    assembly language: It's written by basic instructions. and then it convert to instruction.
    instruction: 指令,  it's basically what operating systems understand.
    intermediate representation: Java brings it in. It's on top of operating systems, and it's common across all of it. That is "bytecode", a format which is common irrespective of the operating system.
  • irrespective: adj 不考慮
  • format: the way in which information is arranged and stored on a computer
  • Data types are divided into two groups:
    1. Primitive data types - includes byte, short, int, long, float, double, boolean and char (即原本就已經定義的型別)
    2. Non-primitive data types - such as String, Arrays and Classes (非原本就定義的型別)
  • class Country {   // 先定義class (型別),Class names always start with a capital letter.
       void revolve() {
       }
    }

    Country india = new Country();  // 設定該型別的變數  此處被稱為object, it's an instance of class.
  • 重新定義class會導致之前建立過的instance reset to null
  • static method:  means that the method belongs to the MyClass class and not an object of the MyClass class. 
    non-static method
  • compile:
    1. 將class code存成java檔,檔名要跟className相同,大小寫也要一致
    2. cmd: javac className.java  // 會生出className.class,這個class就是bytecode。這個行為就是compile
  • execute:
    1. cmd: java className  // 這個行為就是execute。這行為就是再利用JVM把bytecode轉成instruction
        要execute成功必須class裡有main method,其中寫入想執行的code
         

    class Planet {
        void revolve() {
            System.out.println("revolve");
        }
        public static void main(String[] args) {
            Planet earth = new Planet();
            earth.revolve();
        }
    }
    
  • IDE: 集成开发环境,Integrated Development Environment
  • 在eclipse做專案,所有的java檔都必須放在project裡
    1. Window > Preferences > Java > Installed JREs  加入自己下載的jdk位置,並使用它  // 這動作是因為最新的運作起來似乎有些問題跟老師教的不一樣
    2. create a java project with JRE version 11
  • eclipse的快捷鍵
    ctrl+N: 建立一個新XXX的檔案
    ctrl+shift+R: 搜尋檔案
    ctrl+D: remove that line
    ctrl+1:會出現suggestion,就跟滑鼠移上去是一樣的 (是數字1)
    rightClick > Source > Generate Getters and Setters...   // 可自動生成所有data的getter and setter methods
    選擇想要拉出去放在另一個func的程式碼>rightClick>Refactor>Extract Method  // 把該程式碼拉出成另一個func
    8 Eclipse Keyboard Shortcuts Essential for Beginners
  • for loop enhanced  // 一種for迴圈的簡易寫法
  • Organize imports  // 自動分析import的檔案,並轉呈必要的檔案
  • adhere to 堅持
  • Procedural / Structured Programming, 就是指寫成用func或methods的形式編程
  • field 是data的意思
  • encapsulation: 封包的概念,配合private使用,class裡的data只能被它的method修改,向vuex的概念
    封包的好處: 可以對data做一些其他動作,prevent bad code from other class。例如將int 設為負數(但實際上不想要),可以在method裡阻止
  • Abstraction 還不懂怎麼用
  • constructor: a special method to set the inital data, which do not need retrunType and theNameOfMethod is the same as theNameOfClass

    class MotorBike {
      int speed;
      MotorBike( int speed ) {
          this.speed=speed;
      }
    }

    上方的程式執行 MotorBike honda = new MotorBike();  會錯誤,因為沒有設置constructor進去。可以在class裡多加
    MotorBike() {  // it's called no-argument constructor
     }
    就可正確執行。

    而如果在上方例子中想設置默認值為5時:
    方法一
    MotorBike() {
     this.speed = 5;
     }

    方法二
    MotorBike() {
      this(5);  // 這個this()指向MotorBike方法
     }

  • 又還記得我們稱 MotorBike honda = new MotorBike(); 的honda為constructor
    這是因為其實每個class裡都默認有個同名的method,不過內容為空
    所以當我們執行下方程式

    class MotorBike {
      MotorBike( ) {
          System.out.println("Hi");
      }
    }

    MoterBike honda = new MotorBike();  // 會印出Hi
  • Wrapper class: The eight primitive data types byte, short, int, long, float, double, char and boolean are not objects, Wrapper classes are used for converting primitive data types into objects.
    然後他們會有自己的object key屬性:
    例如~
    Byte {
      SIZE: 8,  // bit
      BYTES: 1,  // 表示byte has a size of one byte. (這個其實有點廢話)
      MAX_VALUE: 127,
      MIN_VALUE: -128
    }
    ※注意這些key都要大寫
    其他的則為Short, Integer, Long, 須注意int的wrapper class要寫全名
    Ingeter.BYTES=4;  但不存在Integer.SHORTS=2;
  • byte b = 5;   //  8 bits, range from -128 to 127
    short s = 128; // 16 bits, -32,768 to 32767  (2 bytes)
    int i = 4000; // 32 bits, -2,147,483,648 to 2,147,483,647 (4 bytes)
    long l =2222222222;  // 64 bits, -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807  (8 bytes)

    放上資料是前面提過的primitive data 介紹,但其實其中
    long l =2222222222;會發生錯誤,要寫成long l =2222222222l;  // 一般的數字會默認為int,即使數值很大也是,而且也會因為數值太大存不進int型別。
  • 前置作業一下~ long z=2222222222l;
    Explicit casting(顯示的型態轉換): int a = (int) z;  //把大的type存進小的
    Implicit casting(隱示的型態轉換): z=a;  //把小的type存進大的  (這本來就可行)
  • Octal number:
      1. 八進位的數字,0開頭,如:080
      2. "0-7"
      3. init eight = 010;
          init eight = 08;     // error
    Hexadecimal number:
      1. 十六進制的數字,0x開頭(x大小寫都可),如:0x10
      2. "0 - 9 , A, B, C, D, E, F",其中A表示10、B表示11、...、F表示15。(字母大小寫都可)
      3. int sixteen = 0x10;
          int fifteen = 0xF;
    另外還有 Binary number, Decimal number
    Decimal外的通常只在學術研究等等上出現,平時不輕易使用
  • int i = 10;
    int j = i++;
    //  結果 j=10, i=11

    int i = 10;
    int j= ++i;
    //  結果 j=11, i=11
  • Boolean literal is case sensitive.
    boolean h = true;
    boolean h = True;    //  error
    boolean h = TRUE;   //  error
  • relational operator: 大於、小於、等於...
  • &&, ||, ^
    其中^表示兩個條件需一個為true另一個為false,如此才會印出true,如果兩個同為true或同為false,那結果都會是false,念作XOR operator
  • short-circuit operator: &&, ||
    normal operator: &, |
    兩者的差異是...
    i
    nt i = 10;
    int j = 15;
    i > 10 && j++ >5   // 第一個條件已經可判斷出結果,不會再執行後面程式
    // i = 10, j=15;

    i > 10 & j++ >5   // 不論第一個條件是否已經可判斷出結果,都會繼續把整個code執行完
    // i = 10, j=16;
  • float abc = 3.542f;  // 3.542
    int i = (int)abc;  // 3,小數會被去掉
    float b = i;  // 3.0,it's called widening conversion 
  • 關於float和double型別的不精準案例:34.56789876 + 34.2234  //  68.79129875999999
    用 BigDecimal 解決:
    BigDecimal num1 = new BigDecimal("34.56789876");  
    BigDecimal num2 = new BigDecimal("34.2234");
    num1.add(num2);  //   68.79129876,The operator / is undefined for the argument type(s) BigDecimal,他不能用operator計算,他有methods可以用
    // BigDecimal 是immutable class,一旦建立object,該object就不可變
    // 注意parameter必須傳入字串,否則會又被存成double
    因為如此,所以推薦所有有小數的儲存都用BigDecimal型別

    int i = 5;
    num1.add(i)  // error, because 型別不同不能計算
    num1.add(new BigDecimal(i)) // 39.56789876

    注意在使用BigDecimal之前都要先 import java.math.BigDecimal;
    if you want to use any class in Java, you would need to do a import. 
    有個例外: There's a package called java.languages imported by default. So anything insides Java.lang, you don't really need to import.
    這也是因為BigDecimal不是primitive data type,而是個class
  • subtract: verb 減去
  • hard code: 寫死,指在軟體實作上,將輸出或輸入的相關參數(例如:路徑、輸出的形式或格式)直接以常數的方式撰寫在原始碼中
  • principal: noun 本金
  • static method // 直接裝在class上,和object沒關係。 You can directly call them from main method
  • System.in   //  可以取得what User types in
  • addition: noun 加法
  • switch 傳入的參數只能是int, string或enum
    不能是long, double, float, boolean
    可以是char, short, byte, int, string, enum
  • reinforce: verb 加強
  • ternary operator: 三元運算子
  • prime number: 質數
  • exclude: verb 排除
  • 判斷是否是質數:確認除以 2 to n-1的餘數沒有等於零的(這個程式要跑很多次,不是個好解法)
public boolean isPrime() {
for (int i = 2; i < this.num; i++) {
if (this.num % i == 0) {
return false;
}
}
return true;
}
  • Iteration: noun 疊代,有時會指for loop中的一輪
  • alt+/ 會把shortcut轉出template,像是sysout, main, ...  (可能版本不同,老師的是ctrl+space,這可以在window>peference>java>advanced 看見)
//  initial outside;
while(condition){  //  limit,條件成立時繼續迴圈,條件不成立時停止
    //  update
}

public void printSquaresUptoLimit() {
int i = 0;
while (this.num > i * i) {  
System.out.print(i * i + " ");
i++;
}
}


//  initial outside;
do {
  //  update
}while(condition)

while... v.s  do..while  差別在:即使條件不成立,do仍會先執行一次
所以當希望程式至少執行一次時選擇用do...while

※適合用do...while..的題目:


private static void printcuteUntilNegative() {
Scanner scanner = new Scanner(System.in);
int i = 0;
do {
System.out.println("Cude is: " + i * i * i);
System.out.print("Print a number: ");
i = scanner.nextInt();   //  最初會停在這裡等待輸入,輸入後會往下執行。
} while (i >= 0);
System.out.print("Thx");
                scanner.close();  // 最後要close否則可能造成resource leakage, 也就是memory leaks
}

※for v.s. while v.s. do...while使用時機:
   (一個可以寫,其他兩個必然可以寫,只是看好不好閱讀)
  1. for: 知道要執行的圈數
  2. while: 不知道圈數,但是知道停止的條件。例如:User輸入為負數時停止。
  3. do...while: 和while就相差在這個至少會執行一次。

  • reference types:  (相較primitive types)所有不是原始型別的變數都是reference variables.
  • memory(記憶體)裡有兩種儲存:
    1. stack: 存primitive types的變數名稱和值、reference types的變數名稱和位置 的關係
    2. heap: 存reference types的位置跟值 的關係

陷阱題
class Animal {
int i;

Animal(int i) {
this.i = i;
}
}

Animal dog = new Animal(5);
Animal cat = dog;
System.out.printf("%d, %d", dog.i, cat.i).println();
cat.i = 7;
System.out.printf("%d, %d", dog.i, cat.i).println();
int num1 = 1;
int num2 = num1; // 這個只是把值存進去,不會去記憶位置,不會之後跟著改!
System.out.printf("%d, %d", num1, num2).println();
num2 = 7; // num1會不跟著變,因為他不是reference type,別掉陷阱了!
System.out.printf("%d, %d", num1, num2).println();
                
  • String is a special class. And it's immutable.
    String str="Text";
    we can also defined as: String str = new String("Text");  , but 沒必要,這完全和上一行是一樣的結果。
    str.length(); // 4 這邊稍微注意跟array不一樣,str需要加上()
    str.charAt(2);  // x
    str.equalsIgnoreCase(str2);  // 比較兩個字串(不考慮大小寫問題)
    str.startswith(str2);  // 判斷是否str字串從開頭是否為
    str2
    str.toUpperCase();  //  把str轉大寫
    str.replace("str1","str2");

    String.join(",", "A", "B", "C");  // A, B, C,第一個參數是分割的字串,之後的都是被分割的字串。join這個方法是掛在class上,所以寫成String.join
  • static method: In Java, a static method is a method that belongs to a class rather than an instance of a class. The method is accessible to every instance of a class, but methods defined in an instance are only able to be accessed by that member of a class.
  • concatenation operator: 就是指字串跟數字做運算時的運算符,像:+
    "1"+2+3 // 123
    1+2+"3"  // 33,這是因為會從左算到右,一次算兩個。

    ※上面生成33這個例子,一共建了5個instructor,分別為:1, 2, "3", 3, "33"。
        當有200個字串要相+時,會建太多instructor。
        To avoid that, Java create other class to create strings.
        StringBuffer sb = new StringBuffer("Text");  // StringBuffer is mutable. And it's a synchronised class,  如果想要thread-safe, use this.
        str.append("456");
        str.setCharAt(1,'f'); // 第一個參數index,第二個參數要替換成的char,須注意char必用單引號
    Whenever you do a lot of concatenations, it's preferred that you'd use a StringBuffer.
    StringBuilder sb = new StringBuilder("Text");  //不想擔心多執行緒單執行緒的問題的話,用StringBuilder
        
  • costly: adj 昂貴的
  • 2 Ways to Create Wrapper class:
    1. Integer i = new Integer(5);   //  constructor way
    2. Integer i2 = Integer.valueOf(5);   // static method way
        可以簡單寫Integer i2 = 5;  // 因為Java auto boxing, 它會自動在背後轉成valueOf的程式,這樣的程式又被稱為syntactic sugar 語法糖
       當然傳入的值可以用字串,畢竟Wrapper class就是要來轉換不同型別的
    兩種方法的差別在1一定會見一個新的memory, 2是如果值相同,他會reuse之前創建的memory
    推薦每次create wrapper class 都用valueOf 的方式,which would reuse existing objects that are present in the heap.
  • All wrapper classes are immutable.
  • constant: noun 指class 本身的屬性(就像js裡array本身有length的屬性)
  • Joda Time Framework
  • import java.time.LocalDate;  // or import java.time.*;
    LocalDate now = LocalDate.now();  // immutable

    now.isLeapYear()
    now.lengthOfYear()
    now.lengthOfMonth()
    now.plusDays(5)
    now.plusMonths(5)
    now.plusYears(5)
    now.minusYears(5)
    now.withDayOfYear(32)  // 從這年的第一天開始算的第32天,結果會是XXXX-2-01
    now.withDayOfMonth(n)  //  改day,不是withDay,從這個月開始算的第n天
    now.withYear(2016)
    now.withMonth(6)


    LocalDate yesterday = LocalDate.of(2020,11,20);  //  yesterday=2020-11-20
    now.isBefore(yesterday)  // false
    now.isAfter(yesterday)

  • leap year: 閏年
  • ctrl+shift+T: 在input打入想要了解的class類型,可以打開內建class的檔案。再在class檔案裡ctrl+O可以創建這個class的in-built方法跟屬性,並且會附上註解說明與創建的例子。

    或是

    在想要了解的class上ctrl+左鍵click,他也會跑到跟上面的解釋同個位置

    或是上網查,感覺這個最方便懂
    https://docs.oracle.com/javase/7/docs/api/java/lang/Boolean.html
  • Array
                char[] vowel = { 'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U' };
for (char element : vowel) {
if (element == this.ch) {
return true;
}
}

                或是另一種寫法(不推,因為麻煩沒結果一樣):
                char[] vowel = new char[5];  // char[5] { '\000', '\000', '\000', '\000', '\000' },那個5指的是陣列長度
                vowel [0] = 'a';  // char[5] { 'a', '\000', '\000', '\000', '\000' }
                Arrays.fill(vowel, 'b') //  { 'b', 'b', 'b', 'b', 'b' }

                char[] g={'g','a'}
                Arrays.equals(vowel,g)  //false,注意必須要一樣型別才能比較,否則error
                Arrays.sort(g)  // { 'a', 'g' }
  • class 也可以創建成陣列
    class P{};
    P[] gg = new P[5]   // P[5] { null, null, null, null, null }  ,沒設定時是null
    p[] vv={new P(), new P()}  // P[2]{P@dsfsd, P@fhdg} ,就是兩個object的memory位置(後面那串亂打的),也就是hashCode
  • 要正確印出陣列
    Arrays.toString(vowel )  // ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']
  • in bulk 大批
  • 注意定義string變數時,第一個S要大寫,如:String str。
    和 int i; 不同!
  • format specifier
    FORMAT SPECIFIERCONVERSION APPLIED
    %%Inserts a % sign
    %x %XInteger hexadecimal
    %t %TTime and Date
    %s %SString
    %nInserts a newline character
    %oOctal integer
    %fDecimal floating-point
    %e %EScientific notation
    %gCauses Formatter to use either %f or %e, whichever is shorter
    %h %HHash code of the argument
    %dDecimal integer
    %cCharacter
    %b %BBoolean
    %a %AFloating-point hexadecimal
  • BigDecimal除法常見錯誤:
    java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
    是由於沒有設定小數的計算位數與方法,需寫成:
    new BigDecimal(5).divide(new BigDecimal(4), 2, RoundingMode.HALF_UP);  
    //  divide(BigDecimal divisor, precision, RoundingMode ) ;
    //  precision: 精確值,即小數計算位數
  • RoundingMode 還有很多種:https://docs.oracle.com/javase/7/docs/api/java/math/RoundingMode.html
  • generation: noun 生成器
  • 注意其實除了constructor裡設定時要用this去指定外,其他method裡都不需要用this,不論是想取data或method  (和vue不一樣)


spring boot: https://spring.io/projects/spring-boot

老師推薦書:
1. Art of Computer Programming
2. Effective Java
3. Clean Code

重要的章節57, 

練習題網站:
1. https://codingbat.com/
2. https://www.zhihu.com/question/265662120

還不清楚的部分static, public, private, 執行緒

沒有留言:

張貼留言