- 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: &, |
兩者的差異是...
int 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使用時機:
(一個可以寫,其他兩個必然可以寫,只是看好不好閱讀)
- for: 知道要執行的圈數
- while: 不知道圈數,但是知道停止的條件。例如:User輸入為負數時停止。
- 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 SPECIFIER | CONVERSION APPLIED |
---|
%% | Inserts a % sign |
%x %X | Integer hexadecimal |
%t %T | Time and Date |
%s %S | String |
%n | Inserts a newline character |
%o | Octal integer |
%f | Decimal floating-point |
%e %E | Scientific notation |
%g | Causes Formatter to use either %f or %e, whichever is shorter |
%h %H | Hash code of the argument |
%d | Decimal integer |
%c | Character |
%b %B | Boolean |
%a %A | Floating-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, 執行緒