2020年高處安裝、維護、拆除報名考試及高處安裝、維護、拆除答案解析
-
Collection介面
Collection 介面是在整個 Java 類集中儲存單值的最大操作父介面,裡面每次操作的時候都只能儲存一個物件的資料。
部分方法
方法名稱 | 描述 |
public boolean add(E e) | 向集合中插入一個元素 |
public Iterator<E> iterator() | 為Iterator介面例項化 |
public int size() | 求出集合中元素的個數 |
子介面:List、Set
-
LIst介面
List 是 Collection 的子介面,裡面的所有內容都是允許重複的。
部分方法
方法名稱 | 描述 |
public void add(intindex,Eelement) | 在指定位置處增加元素 |
boolean addAll(intindex,Collection<?extendsE>c) | 在指定位置處增加一組元素 |
public E get(intindex) | 根據索引位置取出每一個元素 |
public int indexOf(Objecto) | 根據物件查詢指定的位置,找不到返回-1 |
public int lastIndexOf(Objecto) | 從後面向前查詢位置,找不到返回-1 |
public ListIterator<E> listIterator() | 返回 ListIterator 介面的例項 |
public ListIterator<E> listIterator(intindex) | 返回從指定位置的 ListIterator 介面的例項 |
public E remove(intindex) | 刪除指定位置的內容 |
public E set(intindex,Eelement) | 修改指定位置的內容 |
List<E> subList(intfromIndex,inttoIndex) | 返回子集合 |
實現類有如下幾個: ArrayList、Vector、LinkedList
-
ArrayList
ArraryList繼承了 AbstractList 類。AbstractList 是 List 介面的子類。AbstractList 是個抽象類,介面卡設計模式。
ArraryList有3個構造方法
ArraryList() | 構造一個初始容量為10的空列表。 |
ArraryList(int initialCapacity) | 構造具有指定初始容量的空列表。 |
ArraryList(Collection<? extends E> c) | 按照集合的迭代器返回的順序構造一個包含指定集合元素的列表。 |
原始碼中的內容
成員變數原始碼
1 /** 2 * Default initial capacity. 3 */ 4 private static final int DEFAULT_CAPACITY = 10; 5 6 /** 7 * Shared empty array instance used for empty instances. 8 */ 9 private static final Object[] EMPTY_ELEMENTDATA = {}; 10 11 /** 12 * Shared empty array instance used for default sized empty instances. We 13 * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when 14 * first element is added. 15 */ 16 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; 17 18 /** 19 * The array buffer into which the elements of the ArrayList are stored. 20 * The capacity of the ArrayList is the length of this array buffer. Any 21 * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA 22 * will be expanded to DEFAULT_CAPACITY when the first element is added. 23 */ 24 transient Object[] elementData; // non-private to simplify nested class access 25 26 /** 27 * The size of the ArrayList (the number of elements it contains). 28 * 29 * @serial 30 */ 31 private int size;
建構函式原始碼
1 /** 2 * Constructs an empty list with the specified initial capacity. 3 * 4 * @param initialCapacity the initial capacity of the list 5 * @throws IllegalArgumentException if the specified initial capacity 6 * is negative 7 */ 8 public ArrayList(int initialCapacity) { 9 if (initialCapacity > 0) { 10 this.elementData = new Object[initialCapacity]; 11 } else if (initialCapacity == 0) { 12 this.elementData = EMPTY_ELEMENTDATA; 13 } else { 14 throw new IllegalArgumentException("Illegal Capacity: "+ 15 initialCapacity); 16 } 17 } 18 19 /** 20 * Constructs an empty list with an initial capacity of ten. 21 */ 22 public ArrayList() { 23 this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; 24 } 25 26 /** 27 * Constructs a list containing the elements of the specified 28 * collection, in the order they are returned by the collection's 29 * iterator. 30 * 31 * @param c the collection whose elements are to be placed into this list 32 * @throws NullPointerException if the specified collection is null 33 */ 34 public ArrayList(Collection<? extends E> c) { 35 elementData = c.toArray(); 36 if ((size = elementData.length) != 0) { 37 // defend against c.toArray (incorrectly) not returning Object[] 38 // (see e.g. https://bugs.openjdk.java.net/browse/JDK-6260652) 39 if (elementData.getClass() != Object[].class) 40 elementData = Arrays.copyOf(elementData, size, Object[].class); 41 } else { 42 // replace with empty array. 43 this.elementData = EMPTY_ELEMENTDATA; 44 } 45 }
從原始碼中可以看出,無論是用哪一個構造方法,ArraryList中的資料都是存放在elementData陣列中的。
在無參建構函式中,elementData被賦值為DEFAULTCAPACITY_EMPTY_ELEMENTDATA(長度為0的空陣列)。
在引數為int initialCapacity的建構函式中,若引數大於0,則將elementData賦值為指定長度陣列,當引數為0時,elementData被賦值為EMPTY_ELEMENTDATA(長度為0的空陣列)。
且慢,在api中,ArraryList的無參建構函式是構造一個長度為10的空列表,為什麼原始碼中的無參建構函式是構造一個長度為0的列表呢?
我們先來看看ArraryList的add方法:
1 /** 2 * This helper method split out from add(E) to keep method 3 * bytecode size under 35 (the -XX:MaxInlineSize default value), 4 * which helps when add(E) is called in a C1-compiled loop. 5 */ 6 private void add(E e, Object[] elementData, int s) { 7 if (s == elementData.length) 8 elementData = grow(); 9 elementData[s] = e; 10 size = s + 1; 11 } 12 13 /** 14 * Appends the specified element to the end of this list. 15 * 16 * @param e element to be appended to this list 17 * @return {@code true} (as specified by {@link Collection#add}) 18 */ 19 public boolean add(E e) { 20 modCount++; 21 add(e, elementData, size); 22 return true; 23 }
我們使用的add方法是第19行的add方法,這個方法的返回值只有true,並且在這個方法中會呼叫第6行的add方法。19行的add方法會把我們需要add的物件還有this.elementData、this.size傳給第6行的add方法。
第6行的add方法會先判斷當前size是否等於當前elementData的長度,如果是則在第8行使用grow()方法對elementData進行陣列擴容。
我們再來看看grow()方法:
1 /** 2 * Increases the capacity to ensure that it can hold at least the 3 * number of elements specified by the minimum capacity argument. 4 * 5 * @param minCapacity the desired minimum capacity 6 * @throws OutOfMemoryError if minCapacity is less than zero 7 */ 8 private Object[] grow(int minCapacity) { 9 return elementData = Arrays.copyOf(elementData, 10 newCapacity(minCapacity)); 11 } 12 13 private Object[] grow() { 14 return grow(size + 1); 15 } 16 17 /** 18 * Returns a capacity at least as large as the given minimum capacity. 19 * Returns the current capacity increased by 50% if that suffices. 20 * Will not return a capacity greater than MAX_ARRAY_SIZE unless 21 * the given minimum capacity is greater than MAX_ARRAY_SIZE. 22 * 23 * @param minCapacity the desired minimum capacity 24 * @throws OutOfMemoryError if minCapacity is less than zero 25 */ 26 private int newCapacity(int minCapacity) { 27 // overflow-conscious code 28 int oldCapacity = elementData.length; 29 int newCapacity = oldCapacity + (oldCapacity >> 1); 30 if (newCapacity - minCapacity <= 0) { 31 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) 32 return Math.max(DEFAULT_CAPACITY, minCapacity); 33 if (minCapacity < 0) // overflow 34 throw new OutOfMemoryError(); 35 return minCapacity; 36 } 37 return (newCapacity - MAX_ARRAY_SIZE <= 0) 38 ? newCapacity 39 : hugeCapacity(minCapacity); 40 }
我們在add中呼叫的grow()方法是第13行的grow()方法,該方法會呼叫第8行的grow方法,並把this.size+1(擴容後的長度)傳遞給它。
第8行的grow方法會使用Arrays.copyOf(需要操作的陣列,新陣列的長度)進行擴容操作,其中第二個引數由第26行的newCapacity方法得出。
在26行的newCapacity可以看到,引數名為minCapacity(我們需要的長度),有兩個內部變數oldCapacity和newCapacity。oldCapacity為elementData的長度,而newCapacity為oldCapacity的1.5倍。
如果我們使用無參建構函式new物件,則進入第31行if語句,此時會比較DEFAULT_CAPACITY與minCapacity,找出最大值,由於DEFAULT_CAPACITY=10,minCapacity=1,此時minCapacity則會return DEFAULT_CAPACITY。
在newCapacity方法returnDEFAULT_CAPACITY後,Arrays.copyOf的第二個引數則為10,陣列被擴容到長度為10。
也就是說,當我們使用無參建構函式new一個ArraryList物件,在第一次使用add方法的時候,該ArraryList的長度會由0變為10。
-
Vector
Vector與ArraryList一樣,屬於List介面的子類。在增刪操作上與ArraryList無區別。
-
Vector與ArraryList的區別
區別點 | ArraryList | Vector |
時間 | JDK1.2之後推出 | JKD1.0推出 |
效能 | 效能較高,採用非同步處理 | 效能較低,採用同步處理 |
輸出 |
支援 Iterator、ListIterator 輸出 |
除了支援 Iterator、ListIterator 輸出,還支援 Enumeration 輸出 |
-
LinkedList
方法名稱 | 描述 |
public booleanadd(Ee) |
增加元素,如果有容量限制,並且已滿,則丟擲異 |
public Eelement() |
取得,但是不刪除當前元素,如果對列為空則丟擲 |
boolean offer(E e) |
新增,如果有容量限制,並且已滿,只是無法新增, 但不丟擲異常,返回 false |
E peek() | 取得頭元素,但是不刪除,如果佇列為空,則返回 null |
E poll() | 取得頭元素,但是刪除, 如果佇列為空,則返回 null |
E remove() | 刪除當前元素, 如果對列為空則丟擲異常 |
-
Set 介面
Set 介面也是 Collection 的子介面,與 List 介面最大的不同在於,Set 接口裡面的內容是不允許重複的。
在此介面中有兩個常用的子類:HashSet、TreeSet
-
雜湊存放:HashSet
java.util.HashSet 是 Set 介面的一個實現類,它所儲存的元素是不可重複的,並且元素都是無序的 (即存取順序不一致)。
HashSet 是根據物件的雜湊值來確定元素在集合中的儲存位置,因此具有良好的存取和查詢效能。保證 元素唯一性的方式依賴於: hashCode 與 equals 方法。
構造方法
HashSet() | 構造一個新的空集; 支援HashMap 例項具有預設初始容量(16)和載入因子(0.75)。 |
HashSet(intinitialCapacity) |
構造一個新的空集; 支援HashMap 例項具有指定的初始容量和預設載入因子(0.75)。
|
HashSet(intinitialCapacity, floatloadFactor) |
構造一個新的空集; 支援HashMap 例項具有指定的初始容量和指定的載入因子。
|
HashSet(intinitialCapacity, floatloadFactor) | 構造一個包含指定集合中元素的新集合。 |
原始碼
1 static final long serialVersionUID = -5024744406713321676L; 2 3 private transient HashMap<E,Object> map; 4 5 // Dummy value to associate with an Object in the backing Map 6 private static final Object PRESENT = new Object(); 7 8 /** 9 * Constructs a new, empty set; the backing {@code HashMap} instance has 10 * default initial capacity (16) and load factor (0.75). 11 */ 12 public HashSet() { 13 map = new HashMap<>(); 14 } 15 16 /** 17 * Constructs a new set containing the elements in the specified 18 * collection. The {@code HashMap} is created with default load factor 19 * (0.75) and an initial capacity sufficient to contain the elements in 20 * the specified collection. 21 * 22 * @param c the collection whose elements are to be placed into this set 23 * @throws NullPointerException if the specified collection is null 24 */ 25 public HashSet(Collection<? extends E> c) { 26 map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); 27 addAll(c); 28 } 29 30 /** 31 * Constructs a new, empty set; the backing {@code HashMap} instance has 32 * the specified initial capacity and the specified load factor. 33 * 34 * @param initialCapacity the initial capacity of the hash map 35 * @param loadFactor the load factor of the hash map 36 * @throws IllegalArgumentException if the initial capacity is less 37 * than zero, or if the load factor is nonpositive 38 */ 39 public HashSet(int initialCapacity, float loadFactor) { 40 map = new HashMap<>(initialCapacity, loadFactor); 41 } 42 43 /** 44 * Constructs a new, empty set; the backing {@code HashMap} instance has 45 * the specified initial capacity and default load factor (0.75). 46 * 47 * @param initialCapacity the initial capacity of the hash table 48 * @throws IllegalArgumentException if the initial capacity is less 49 * than zero 50 */ 51 public HashSet(int initialCapacity) { 52 map = new HashMap<>(initialCapacity); 53 }
由原始碼和構造方法可以看出HashSet是利用HashMap實現的。
-
排序的子類:TreeSet
與 HashSet 不同的是,TreeSet 本身屬於排序的子類。
雖然在增加元素的時候屬於無序的操作,但是增加之後卻可以為使用者進行排序功能的實現。
-
排序的說明
既然 Set 介面的 TreeSet 類本身是允許排序,但自定義類需要實現Comparable<T>介面,通過compareTo(Object o)實現排序操作。
-
Map 介面
以上的 Collection 中,每次操作的都是一個物件,如果現在假設要操作一對物件,則就必須使用 Map 了,類似於以 下一種情況:
張三 | 1班 |
李四 | 1班 |
王五 | 2班 |
那麼儲存以上資訊的時候使用 Collection 就不那麼方便,所以要使用 Map 介面。裡面的所有內容都按照 key->value 的形式儲存,也稱為二元偶物件
常用方法
方法名稱 | 描述 |
void clear() | 清空 Map 集合中的內容 |
boolean containsKey(Objectkey) | 判斷集合中是否存在指定的 key |
boolean containsValue(Objectvalue) | 判斷集合中是否存在指定的 value |
Set<Map.Entry<K,V>> entrySet() | 將 Map 介面變為 Set 集合 |
V get(Objectkey) | 根據 key 找到其對應的 value |
boolean isEmpty() | 判斷是否為空 |
Set<K> keySet() | 將全部的 key 變為 Set 集合 |
Collection<V> values() | 將全部的 value 變為 Collection 集合 |
V put(Kkey,Vvalue) | 向集合中增加內容 |
void putAll(Map<?extendsK,?extendsV>m) | 增加一組集合 |
V remove(Objectkey) | 根據 key 刪除內容 |
Map 本身是一個介面,所以一般會使用以下的幾個子類:HashMap、TreeMap、Hashtable
-
HashMap
HashMap是Map的一個具體體現類,是以雜湊表實現的對映集合,內部由一個儲存Entry型別元素的陣列組成。HashMap的資料是無序存放的。
構造方法
HashMap() |
使用預設初始容量(16)和預設載入因子(0.75)構造一個空 HashMap 。
|
HashMap(int initialCapacity) | 使用指定的初始容量和預設載入因子(0.75)構造一個空 HashMap 。 |
HashMap(intinitialCapacity, floatloadFactor) |
使用指定的初始容量和載入因子構造一個空 HashMap 。
|
HashMap(Map<? extends K,? extends V>m) |
構造一個新的 HashMap ,其對映與指定的 Map 相同。
|
HashMap是陣列+連結串列+紅黑樹(JDK1.8增加了紅黑樹部分)實現的
當連結串列節點大於等於8時,連結串列轉化為紅黑樹
當紅黑樹節點小於等於6時,紅黑樹轉化為連結串列
-
Hashtable
Hashtable 是一個最早的 key->value 的操作類,本身是在 JDK1.0的時候推出的。其基本操作與 HashMap 是類似的。Hashtable 中是不能向集合中插入 null 值的。
-
HashMap 與 Hashtable 的區別
區別點 | HashMap | Hashtable |
推出時間 | JKD1.2之後推出 | JDK1.0時推出 |
效能 | 非同步處理,效能較高 | 同步處理,效能較低 |
null | 允許設定為null | 不允許設定,否則將會丟擲空指標異常 |