- variable argument: // 可變數量參數:參數數量不被限制,以陣列形式傳入。但必須注意variable argument必須為最後傳入的argument
void print(int... hi){
System.out.println(Arrays.toString(hi));
}
print(1,2) // [1,2]
print(1,2,5,8) // [1,2,5,8] - 陣列一旦生成,就不能修改陣列的長度,想增加只能create new Array,再把舊的複製到新的。但很麻煩,所以出現了ArrayList來處理( 它是collections的一部份 )
- ArrayList arrayList = new ArrayList();
ArrayList.add(value)
ArrayList.remove(value or index)
ArrayList<Integer> arrayList = new ArrayList<Integer>(); // 限制型別為Integer,必須為完整大寫 - System.out.println(objectName);
並在class裡添加
public String toString() { // 固定將它放在mehods的最後一個
return <classData>;
}
這樣就能印出classData - revise: verb 學習
- elaborate: verb, to add more information to or explain something that you have said
- zip code: 郵遞區號 (可以寫做Postal code)
- Object Composition: an object inside another object
- concanate: verb 把(兩件事)聯繫起來
- Inheritance: 繼承,欲使用它,必須確定兩者之間確有關係
public class Student extends Person {
}
從上面這個例子,Student( subclass ) 繼承所有Person( superclass )的data和method - ctrl+shift+R: 再輸入想要打開的fileName,就可以快速打開
- 如果class沒有繼承別的class,則會默認該class extends Object, which is a class that provides equals, toString, ... methods, is the root of the class hierarchy
- System.out.println( className ); // 事實上執行的是 System.out.println( className.toString() );
- Overriding: 在subclass寫入一個和superclass同名的method,最後執行時會執行subclass的
- #: 井字號唸做number sign, hash
- 在subclass裡想使用superclass的方法,可以用super.superClassMethod,想要取得data,則必需在superClass建立getData的method去取得
- constructor裡會自動在內容第一行加上super(),所以superclass的constructor必定會在subclass的之前執行。但如果要傳參數給super(para),則必不能省略。
- public class Student extends Person {
}
public class Employee extends Student {
}public class Employee extends Student, Person{ //wrong}
Student stu1 = new Employee(); // ok,stu1本質上是EmployeeEmployee stu2 = new Student ();// wrong, Type mismatch: cannot convert from Student to Employee
System.out.println(stu1 instanceof Employee); // true,可以判斷該object是不是該class的實例
// subclass 可以是superclass的實例
System.out.println(stu1 instanceof Person); // true
System.out.println(stu1 instanceof Student); // true - Abstract: to define the basic algorithm,經常被用於製作framework(框架),最後執行的是superclass的方法,因為這樣才會有共同的邏輯。
abstract class Animal {
abstract public void bark(); // abstract method沒有body,沒有definition, just declaration
}
class Dog extends Animal{ //欲繼承abstract必需implement method (實現抽象方法,填入body)
public void bark() { // 這是override
System.out.println("bow");
}
}Animal cat = new Animal();wrong, 抽象class不可以建立實例
public abstract class Animal {
public void execute() { // 最後執行這個
say();
doSth();
}
abstract void say();
abstract void doSth();
}
- concrete class: adj 實際的, 具體的 class
- Interface: 結構跟Abstract有像,但是它不是要定義邏輯(內部),而是定義它有的接口(外部),最後執行的還是各自class下的method。
Interface basically represents the common action s that can be performed.
It establishes the communication agreement, it establishes the contract between two classes.
一個是要有哪些方法
一個是要來執行上面這個class
有了interface,可以將決定好的interface給外包,讓外包去實現。例如有個interface是取的兩地間通行的時間,自己團隊在做利用飛機的通行時間,而把利用火車的通行時間包給別人
implement相同interface的表示他們有相同的action,但是他們之間可能沒有關係,例如鳥跟飛機--飛的動作 - outsource: verb 外包
- dummy:noun 假
- polymorphism: noun 多型,多個相同名稱的程式,傳入不同的參數,會執行不同的動作,ex: for loop
- Abstract 和 Interface都可以在裡面建立data和一般method,在interface裡的method要加上default,有了default就不用在implements該interface的class裡再寫override。
- Abstract class implement interface不必override method,當然最後真的寫concrete的class時還是需要
- Interface
1. interface彼此可以繼承
2. interface裡的data一定要給予初始值。
3. default method的用法: 使該method不用在implements該interface的class裡再寫override。default method一定要有body~ - Interface和abstract class的不同
1. Interface所有的data跟方法都是public,abstract class則可以有private
2. Interface's data value can't be changed
3. class可以implement多個interfaces,和extend abstract只能一個(但可以寫做多層的關係),這樣才不會有多個super() - practitioner: noun 執業者
- Collections:
there are 4 basic collection's interfaces: (下面四個都會有collection的方法跟屬性)
1. List:
有順序,index
可以有重複的值
2. Set
沒有順序,no-index
不可有重複的值
3. Queue
PriorityQueue is a collection optimized for finding the tail or head value quickly, using a partially ordered tree structure called heap (look it up on wikipedia). If you pop the elements, they will be ordered. If you want to iterate, use for example a SortedSet instead, which also stores the elements sorted.
如果沒有comparator,不要用Queue來排序!它適合用來建立排序,可有重複的值
4. Map
它沒有繼承collection!(但它是collection的一部份)
它用來儲存key-value pairs
ArrayList is a collection - 儲存資料的結構有幾種:Collection, LinkedList, Hashtable, Tree
- underlying: adj 深層的
- underneath: adv 在...之下
- List<String> words = List.of("Dog","Cat","Rat"); // [Dog, Cat, Rat],這是java 9 的新功能,在之前要建立這樣一個陣列必須先new ArrayList再add value進去
注意List不是class,是interface,interface和class都可以放在左邊變數之前定義該變數型態,右側才是真正要建立的東西
words.size() // 3, 和ArrayList一樣要用size,這是因為ArraList就是implement List
words.get(1) // Cat
words.contains("cow"); // false
words.indexOf("Cat") // 1
words.add("Cow") // error
List<String> wordsArrayList = new ArrayList<String>(words); // 傳入陣列 (阿...事實上右邊的<String>可以寫<>就好,因為左邊已經定義要Stirng type了
wordsArrayList.add("Cow"); // wordsArrayList = [Dog, Cat, Rat, Cow] - immutable: String class, BigDecimal, Wrapper class, and anything created from of, like List.of(), or Map.of()
mutable: ArrayList, LinkedList(連結List), Vector(向量) - ArrayList, Vector: 底層是Array,
優點:有index的觀念,可以快速取出想要的index資料
缺點:插入和刪除index資料事件消耗資源大的事情(ex: 如果我想刪除中間一個元素,我要把它後面的所有元素往前移動一格)
LinkedList: 底層是LinkedList
優點:插入和刪除只會影響前後兩個連結目標( Doubly Linked ),消耗小
缺點:用連結的方式取得資料,像git的儲存,取出資料比較慢 - Vector:
大部分method都有修飾符synchronized。如果想要thread-safe,則選擇用它。
ArrayList:
method沒有修飾符synchronized。如果不在意thread-safe、想要快速,則選擇用它。
synchronized: 同步,指在多執行續下,也只有一個執行續可以在synchronized method運作。這是想要的thread-safe一個基本作法。 - List 的方法有:
1. .add(index, value) // index is option
2. .addAll(index, anotherArray) // index is option
3. .set(index, editValue)
4. .remove(index or value)
5. .get(index)
6. .indexOf(value)
7. .lastIndexOf(value)
注意
List<String> wordsArrayList = new ArrayList<String>(words);
List<String> wordsArrayList2 = new LinkedList<String>(words);
wordsArrayList.addAll(wordsArrayList2); 可以成功執行,因為他們都是List型別 - iterator: noun 迭代器,是確使用戶可在容器物件(container,例如鏈表或陣列)上遍訪的對象,就像for迴圈。
Java Iterator(迭代器)不是一个集合,它是一种用于访问集合的方法,可用于迭代 ArrayList 和 HashSet 等集合。
它的method就只有next 、hasNext 和 remove,所以可以說它是為了remove Array item而存在。
调用 it.next() 会返回迭代器的下一个元素,并且更新迭代器的状态。所以連續執行 it.next() ,就會從陣列的item一個個輪過去。
Iterator wordsIterator = words.iterator();
while(wordsIterator.hasNext()){
System.out.println(wordsIterator.next());
}
這段的結果就跟用for loop印出陣列是一樣的 - 在for loop 期間,不能修改目標陣列,尤其刪除item,否則結果可能有誤。
例如下方例子:
for(String word:wordsArrayList){
if(word.endsWith("at")){
wordsArrayList.remove(word);
}
}
原本wordsArrayLis 是[Dog, Cat, Rat],執行後變成[Dog, Rat],這結果錯誤!
欲達成刪除at結尾的item,建議使用iterator:
Iterator<String> iterator = wordsArrayList.iterator();
while(iterator.hasNext()){
if(iterator.next().endsWith("at")){
iterator.remove();
}
}
結果wordsArrayList 是[Dog] - Generics 泛型: <T> ,T means type。class寫成泛型定義,之後真正使用時要在真的定義出型態。有時候會看到<E>,那些也都是泛型。
public class ExampleArrayList<T extends Number> { // 定義泛型並限制只能是Number型態的
ArrayList<T> array = new ArrayList<>();
public void addElement(T element) { //傳入泛型
this.array.add(element);
}
public void removeElement(T element) {
this.array.remove(element);
}
public T get(Integer index) { // 回傳泛型
return this.array.get(index);
}
@Override
public String toString() {
return String.format("ExampleArrayList [array=%s]", array);
}
}
- 在IDE反白想確認的型態,右鍵Quick Type Hierarchy 會出現該型態的層級
Byte, Double, Float, Integer, Long, Short are all subclasses of Number.
上面提到的是泛型class,下面來說一個泛型方法:
static <X extends List> X value(X value2){ // 限制為List的泛型
return value;
}
通配符wildcard字元'?'在使用上配合extends(配合class)或是implements(配合 interface)
可以用來控制輸入的類型(Upper Bounded Wildcards):
static double sum(List<? extends Number> numbers) { // upper bounded wildcard
double sum = 0.0;
for (Number num : numbers) {
sum += num.doubleValue();
}
return sum;
}
static void addCouplesOfValue(List<? super Number> numbers) { // lower bounded wildcard,會限制它的subclass
numbers.add(1.0);
numbers.add(5);
numbers.add(8.3f);
numbers.add(7l);
}
- In the List, we cannot store primitives. Every item gets autoBoxed.(自動變成wrapper class)
List array = List.of("gg",'s',5, 1.0); // [gg, s, 5, 1.0]
它們的型別分別是 String, Character, Integer, Double - 當有一個數字陣列,使用remove時,傳入的參數有兩種可能: 1.value的值 2. index的位置
如果想要確定為value的值,傳入Integer.valueOf(num)或new Integer(num),前者比較推薦,因為不會相同的值也建一個新的object
而直接傳入就是index的位置 - Collections.sort(mutable List);
(mutable List).sort(comparator); - class AscendingStudentComparator implements Comparator<Student> { // 這就是個簡單的comparator class
@Override
public int compare(Student student1, Student student2) {
return Integer.compare(student1.getId(), student2.getId());
}
}
而在public static void main(String[] args) {}裡就可以執行下面程式:
(mutable List).sort(new AscendingStudentComparator()); - ArrayList<Student> studentsAl = new ArrayList<>(students); // 建立自己的class type array
想要排列自己的class array: Collections.sort(studentsAl);
需要在自己的class上implements comparable<定義型別>: public class Student implements Comparable<Student>
並實現需要override的method:
public int compareTo(定義型別 that) { // 傳入的變數常稱為that
// sort的規則
} - ascending sorting: 上升排序,簡寫Asc
descending sorting: 下降排序,簡寫Desc - correction: noun 更正
- immutable: String class, BigDecimal, Wrapper class, and anything created from of, like Set.of()
mutable: HashSet, TreeSet (They are implementations of Set interface) - Set<String> set = Set.of("cat","cat1");
Set<String> hashset = new HashSet<>(set);
hashset.add("cat"); // 結果不會加入,因為Set interface不可以有重複的值
System.out.println(set) // 印出 [cat1, cat] ,他的順序已經亂了,沒順序可言,而且還是在immutable array上 - Data Structure: (關於如何儲存資料有三種)
1. Array
2. LinkedList
3. Hashing: 他試圖結合上面兩者的優點
4. Tree: 他會把根據資料內容有序的儲存資料。例如:儲存1-100,他的排列方式必定是中間50往左愈來愈小,往右越來越大。因此他要get, serted, delete data都可以輕鬆的處理,消耗不大。
- modulo: 簡寫mod,同餘。即%,取餘數。
被除數 a 和除數 n, a modulo n (縮寫為 a mod n) - Hash Table
bucket
hashing function : 這個func決定hash table的效率、速度
mod
它的運作舉例來說:有13個bucket作為fixed position來儲存數字資料,現在有個數字15要存入,該數字十五經過hashing function處理得到它該去position。hashing function最直覺的做法就是利用Modulus(mod)取餘數。以15為例,15/13餘2,在下圖它將存入position 2的bucket中。
所以他們有了位置,而一個個相同位置間的關係又像linkedList的關聯。
- hashCode(): 它就是上面提到的hashing function
- Set<Integer> numbers = new HashSet<>();
implements Set interface的有三種class:
HashSet: 無順序、不可重複
LinkedHashSet: 有順序、不可重複(順序是依照存入的順序)
TreeSet: 有順序、不可重複(順序是依照value 升序)
List<Character> list = List.of('A', 'E', 'C', 'A', 'H');
Set<Character> linkedHashSet = new LinkedHashSet<>(list);
System.out.println(linkedHashSet);
Set<Character> treeSet = new TreeSet<>();
treeSet.addAll(list);
System.out.println(treeSet);
- TreeSet 還implements了NavigableSet: (注意要用這個的方法,必須左邊型態是TreeSet,不能只是Set,因為這個功能是基於TreeSet的內容依照value升序排列)
所以它多了一些可用的method
1. treeSet.floor(比較的目標值) 取比目標值小的且最接近目標值的數,包含目標值
2. treeSet.lower() 取比目標值小的且最接近目標值的數,不包含目標值
3. treeSet.ceiling() 取比目標值大的且最接近目標值的數,包含目標值
4. treeSet.higher() 取比目標值大的且最接近目標值的數,不包含目標值
5. treeSet.subSet(區間起始值, 區間終止值) 取得區間範圍內的所有值 (這個值包含起始,但不含終止)
treeSet.subSet(區間起始值, true, 區間終止值, true) 這樣寫的話就兩邊都包含
6. treeSet.headSet(目標值) 取得在目標值之前的所有數,不包含目標值
7. treeSet.tailSet(目標值) 取得在目標值之後的所有數,包含目標值 - implementation of map interface的class 有:
1. HashMap
unsorted, unordered
allows store a key with null value
2. HashTable
unsorted, unordered
synchronized -- safe thread
not allows store a key with null value
3. LinkedHashMap
insertion order
iterator insert and delete more fast
4. TreeMap
Besides implements Map, it also implements NavigableMap interface.
sorted order
由於它是儲存key value的,在定義型別時也就要兩個型別:
Map<String, Integer> map = Map.of("E",5,"R",17,"A",10); // {A=10, R=17, E=5} - 最後來點記憶的技巧:
1. 當看見有hash詞的class時,記得她是unordered, unserted
2. 當看見linked詞的class時,代表它是背後是以前後相接的形式,所以ordered 適合iterator,使用hashCode()
3. 當看見tree詞的class時,它是sorted order,並且它會implement NavigableSet or NavigableMap - angular brackets: <>
沒有留言:
張貼留言