1.如何定義Collection?java
Collection是一個集合體系的頂層接口,此接口中的方法都是:public abstract。 能夠進行增刪改查的操做: 增長: -->> boolean add(Object o) 一次添加一個元素,元素能夠是Object 的子類,返回true boolean addAll(Collection c) 一次添加一批元素,參數是Collection類型的 刪除: -->> void clear() 清空集合 boolean remove(Object o) 一次刪除一個元素,成功刪除,返回true boolean removeAll(Collection c) 一次刪除一批,成功,返回true 查找: -->> boolean contains(Obejct o) 判斷集合中是否包含指定元素 boolean containsAll(Collection c) 是否包含一批 boolean isEmpty() 判斷集合是否爲空 int size() 獲取集合中的個數 修改: -->> clear() 清空集合中的全部元素 獲取: -->> int size() 返回集合容器的大小 集合轉換爲數組: Object[] toArray(); 該方法將集合轉爲數組,集合中的每個元素,做爲了數組一個的元素
【注意:集合中存儲的是對象的引用,而不是對象自己】
【注意:接口與接口之間屬於:繼承關係】編程
二、錄入用戶在控制檯輸入的信息,可使用Scanner類數組
Scanner sc = new Scanner();
三、List接口: ---->> public interface List extends Collection安全
List是一個繼承了Collection接口的接口,具有了比Collection多的功能。 特色: ---->> 有序、有角標、可重複。 此接口的用戶能夠對List接口中每一個元素的插入位置進行精確地控制。(經過角標獲取集合中的元素) 增: void add(int index,Object element) 指定元素添加的角標,增長一個元素 boolean addAll(int index,Collection c) 指定位置,增長一批 刪: Element remove(int index) 刪除指定位置的元素,而且返回該元素 改: Element set(int index,Object element) 替換指定位置的元素,須要肯定該元素的位置和新元素,返回就元素。 List<E> subList(int fromIndex,int toIndex) 截取子結合,返回一個List,包含頭,不包含尾。 查: Object get(int index) 獲取List結合指定位置的元素 int indexOf(Object o) 返回此列表中第一次出現的指定元素的索引 int lastIndexOf(Object o) 倒序查找指定元素的位置 【注意角標越界:IndexOutOfBoundException // 找不到返回:-1】 【Object set = new list.get(list.size()-1);】 【List集合特有的增刪改查方法都跟角標有關係!!!!】
【問:如何取出List集合中的元素?】網絡
經過for循環,並使用size()和set()方法可取出List集合中的每個元素。
四、ArrayList -->> 是一個List接口的實現類數據結構
具有List集合的特色:有序、有角標、可重複。 該類內部,維護了一個數組, 數組的元素是Object 類. 在ArrayList 類的構造函數中初始化的該數組, 若是沒有顯示的指定數組的長度,【默認長度是10】 也就是說: 使用無參數構造,new ArraList(), 自動建立的數組長度是60%. ArrayList 在添加元素時,都會檢測數組是否已滿,若是滿了,自動擴容(建立一個新數組), 【新數組長度的是老數組的1.6倍】 而且將老數組中的元素拷貝到了新數組,使用新數組繼續增長元素.
五、ArrayList使用什麼實現的?其優缺點是什麼?多線程
ArrayList是使用數組實現的。 優勢:內存地址連續,查找快; 缺點:增長和刪除元素,須要設計數組的擴容或者拷貝,效率很低。 ---->> 總結: 數組實現,查找快,增刪慢。 ArrayList中的方法: boolean contains(Object o) 判斷集合是否包含指定的元素,涉及了元素的比較(對象的比較) 內部使用了元素的equals()方法。 String類 重寫了equals()方法
六、LinkedList ---->> List接口的實現類,具有:有序、有角標、元素可重複的特色。【和ArrayList相似】函數
LinkedList是一個雙向鏈表,該集合提供了方便操做集合頭和集合尾的方法。 【若是集合中沒有元素能夠獲取或者刪除,則拋:NoSuchElementException】 LinkedList特有的方法: 增長: void addFirst(Element e) void addLast(Element e) 刪除: Object getFirst() Object getLast() 查找: Object removeFirst() 移除並返回此列表的第一個元素 Object removeLast() 移除並返回此列表的最後一個元素 數據結構: 堆棧: void push(Element e) 將元素推入此列表所表示的堆棧 Element pop() 今後列表所表示的堆棧處彈出一個元素 【壓棧和彈棧:先進後出,後進先出】 隊列: boolean offer(Element e) 將指定元素添加到此列表的末尾(最後一個元素) Element poll() 獲取並移除此列表的頭(第一個元素) Element peek() 獲取但不移除列表的頭(第一個元素) 【隊列的數據結構:先進先出】 返回逆序的迭代器對象: descendingIterator() 返回逆序的迭代器對象
七、LinkedList的實現原理是什麼?其優缺點?性能
LinkedList的實現原理是:鏈表實現,其內存地址是不連續的。 優勢:相對於數組,增長元素快; 缺點;因爲內存地址不連續,查找性能低。
八、集合與數組有什麼區別?測試
相同點:數組和集合都是容器 數組和集合中存放的都是【對象的引用】而非對象自己 不一樣點:數組存儲【基本數據類型】,是單一的。並且一旦聲明好長度後,長度不可變; 集合【只能】儲存【對象】,可是能夠是任意類型的對象,其長度可變。
【集合的分類】
----|Iterable:接口 Iterator iterator() ----|Collection:單列集合 ----|List: 有序存儲順序,可重複 ----|ArrayList: 數組實現,查找快、增刪慢 因爲是數組實現,在增和刪的時候會牽扯到數組增容,以及拷貝元素,因此慢; 數組是能夠直接按索引查找的,因此查找時比較快。 ----|LinkedList: 鏈表實現,增刪快、查找慢 因爲鏈表實現,增長時只要讓前一個元素記住本身就能夠了,刪除時讓前一個元 素記住後一個元素,後一個元素記住前一個元素,這樣的增刪效率高; 但查詢時須要一個一個的遍歷,因此效率比較低。 ----|Vector: 多線程安全、效率略低 【ArrayList單線程效率高,可是多線程要使用Vector】 ----|set: 無序存儲,不可重複 ----|HashSet 線程不安全,存取速度快 底層是以hash表實現的 ----|TreeSet 紅-黑樹的數據結構,默認對元素進行天然排序(String) 【TreeSet自身具有排序功能】 ----|Comparable ----|compareTo(Object o) 元素自身具有比較性 ----|Comparator ----|compare(Object o1,Object o2) 給容器傳入比較器 若是在比較的時候兩個對象返回值是【0】,那麼這兩個元素【重複】 【當Comparable和Comparator比較方式同時存在時,以Comparator比較方式爲主】 ----|LinkedHashSet 會保存插入的順序 ----|Map: 將鍵映射到值的對象。一個映射不能包含重複的鍵,每一個鍵最多隻能映射一個值。 interface Map<K,V> ----|TreeMap 底層是二叉樹數據結構,能夠對map集合中的鍵進行排序 須要使用Comparable或者Comparator進行比較排序。 【return 0 判斷鍵的惟一性】 ----|HashTable 底層是哈希表數據結構,線程是【同步】的 -->> 不能夠存入null鍵、null值 效率較低,故被【HashMap】替代 ----|HashMap 採用哈希表實現 -->> 【無序】 底層是哈希表數據結構,線程是【不一樣步】的 -->> 能夠存入null鍵、null值 【要保證鍵的惟一性,須要覆蓋hashCode()方法和equals()方法】 ----|LinkedHashMap 【經常使用方法:】 添加: V put(K key,V value) 能夠是相同的key值,可是添加的value值會覆蓋前面的 putAll(Map<? extends K , ? extends V> m) 從指定映射中將全部映射關係複製到此映射中(可選操做) 刪除: remove(Object key) 刪除關聯對象,指定key對象 clear() 清空集合對象 獲取: value get(Object key) 能夠用於判斷鍵是否存在的狀況。 判斷: boolean isEmpty() 若是此映射不包含鍵-值映射關係【即長度爲0】,則返回true,不然返回false boolean containsKey(Object key) 判斷集合中是否包含指定的key boolean containsValue(Object value) 判斷集合中是否包含指定的value 當指定的鍵不存在的時候,返回的是null 長度: int size() 返回此映射中的鍵-值映射關係數
九、在何時該使用什麼樣的集合?
Collection 當咱們須要保存若干個對象的時候使用集合 -->> List 若是須要保留存儲順序、而且重複元素時,使用List -->> 若是查詢較多,使用ArrayList; 若是存取較多,使用LinkedList; 若是須要線程安全,使用Vector。 -->> Set 若是不須要保留存儲順序,而且要去掉重複元素時,使用Set -->> 若是須要將元素排序,使用TreeSet; 若是不須要排序,使用HashSet 【HashSet比TreeSet效率高】 若是須要保留存儲順序,同時要過濾重複元素,使用LinkedHashSet。
十、自定義對象時爲何要重寫toString()和equals()方法?
由於Object是自定義類的父類,Object類中的toString()方法返回的是哈希值; Object類中的equals()方法比較的是對象的地址值。
【去除集合中重複的元素】
代碼以下: public class Demo{ public static void main(String[] args){ ArrayList arr = new ArrayList(); Person p1 = new Person("jack",20); Person p2 = new Person("rose",18); Person p3 = new Person("rose",18); arr.add(p1); arr.add(p2); arr.add(p3); System.out.println(arr); ArrayList arr2 = new ArrayList(); for(int i=0;i<arr.size();i++){ Object obj = arr.get(i); Person p = (Person)obj; if(!arr2.contains(p)){ arr2.add(p); } } System.out.println(arr2); } } class Person{ private String name; private int age; public Person(){ } public Person(String name,int age){ this.name = name; this.age = age; } public String getName(){ return name; } public void setName(String name){ this.name = name; } public int getAge(){ return age; } public void setAge(int age){ this.age = age; } public int hashcode(){ return this.name.hashCode() + age*37; } public boolean equals(Object obj){ if(!(obj instanceof Person)){ return false; } Person p = (Person)obj; return this.name.equals(p.name) && this.age = p.age; } public String toString(){ return "name:" + this.name + "age:" + this.age; } }
十一、Vector: 多線程安全、可是效率低 ---->> 描述的是一個線程安全的ArrayList。
特有的方法: void addElement(E obj) 在集合末尾添加元素 E elementAt(int index) 返回指定角標的元素 Enumeration element() 返回集合中的全部元素,封裝到Enumeration對象中 Enumeration接口: boolean hasMoreElements() 測試此枚舉是否包含更多的元素 E nextElement() 若是此枚舉對象至少還有一個可提供的元素,則返回此枚舉的下一個元素 【代碼以下:】 public static void main(String[] args){ Vector v = new Vector(); v.addElement("aaa"); v.addElement("bbb"); v.addElement("ccc"); // System.out.println(v.elementAt(2)); Enumeration ens = v.elements(); while(ens.hasMorreElements()){ System.out.println(ens.nextElement()); } }
十二、Iterable: 是Collection的父接口,實現Iterable的類能夠進行迭代,而且支持加強for循環
該接口只有一個方法,用於返回集合迭代器對象! 【獲取迭代器的方法iterator()】 piblic interface Iterable<T> Iterator<T> iterator():該類主要用於遍歷集合對象,並描述了遍歷集合的常見方法 boolean hasNext() 判斷集合中是否有元素,若是有元素能夠迭代,就返回true。 E next() 返回迭代的下一個元素。 若是沒有下一個元素,調用next()會拋出 -->> NoSuchElementException void remove() 從迭代器指向的集合中移除迭代器返回的最後一個元素
【Iterator的for循環、清空】
public class Demo{ ArrayList list = new ArrayList(); // 增長:add() 將指定對象存儲到容器中 list.add("計算機網絡"); list.add("現代操做系統"); list.add("java編程思想"); list.add("java核心技術"); list.add("java語言程序設計"); System.out.println(list); for(Iterator it = list.iterator();it.hasNext();){ // 迭代器的next()方法返回值類型是Object,全部要記得【類型強轉】 String next = (String)it.next(); System.out.println(next); it.remove(); } }
【細節一:若是迭代器的指針已經指向了集合的末尾,那麼若是再調用next()會返回NoSuchElementException異常】
【細節二:若是調用remove()以前沒有調用next()方法是不合法的,會拋出IllegalStateException異常】
【細節三:當一個集合在循環中即便用引用變量操做集合,又使用迭代器操做集合對象,會拋出ConcurrentModificationException異常】
1三、爲何next()方法的返回值類型是Object呢?
爲了能夠接收任意類型的對象 若是返回的時候不知道是什麼類型的,就定義爲object
1四、Iterator和ListIterator有什麼關係?
ListIterator是Iterator的子接口,是List集合特有的迭代器。 Iterator在迭代時,只能對元素進行獲取【next()】和刪除【remove()】的操做; ListIterator在迭代list集合時,還能夠對元素進行添加【add(obj)】和修改【set(obj)】的操做。
1五、List集合特有的迭代器ListIterator
---->> public interface ListIterator extends Iterator ListIterator<E> listIteraotr() ----| Iterator hasNext() next() remove() ----| ListIterator add(E e) 將指定的元素插入列表(可選操做)。 該元素直接插入到next()返回的下一個元素的前面(若是有) void set(E o) 用指定的元素替換next()或previous()返回的 【最後】 一個元素 hasPrevious() 逆向遍歷列表,列表迭代器有多個元素,則返回true previous() 返回列表中的前一個元素
1六、HashSet是如何判斷兩個元素重複的?
經過hashCode()方法和equals()方法來保證元素的惟一性,add()方法返回的是boolean類型 【調用原理:HashSet集合在判斷元素是否相同,先判斷hashCode()方法,相同纔會判斷equals()方法;不相同不會調用equals()】
1七、HashSet和ArrayList集合在判斷元素時是否有相同的方法?
有:boolean contains(Object o) HashSet使用hashCode()和equals()方法,ArrayList使用eqauls()方法。
1八、給TreeSet指定排序規則:
方式一:【元素自身】具有比較性 元素自身具有比較性,須要元素實現【Comparable接口】,重寫【compareTo方法】, 也就是讓元素自身具有比較性,這種方式叫作元素的【天然排序】也叫作【默認排序】。 方式二:【容器】具有比較性 當元素自身不具有比較性,或者自身具有的比較性不是所須要的。 那麼此時可讓容器自身具有。須要定義一個類實現【Comparator接口】,重寫【compare方法】, 並將該接口的子類實例對象做爲參數傳遞給【TreeSet集合】的【構造方法】。 注意:當Comparable比較方式和Comparator比較方式同時存在時,以【Comparator】的比較方式爲主; 注意:在重寫compareTo或者compare方法時,必需要明確比較的主要條件相等時要比較次要條件。 經過return 0 來判斷惟一性。
1九、爲何使用TreeSet存入字符串,字符串默認輸出是按升序排列的?
由於字符串實現了一個接口,叫作【Comparable接口】,字符串重寫了該接口的【compareTo()方法】, 因此String對象具有了比較性。 【自定義的元素(好比Person類、Book類)想要存入TreeSet集合,就必須實現Comparable接口,也就是要讓自定義對象具有比較性】 【存入TreeSet集合的元素都要具有比較性:要實現Comparable接口、並重寫該接口的compareTo()方法】
20、總結:
看到array,就要想到角標。 看到link, 就要想到first,last。 看到hash, 就要想到hashCode,equals. 看到tree, 就要想到兩個接口。Comparable,Comparator。
2一、TreeSet是如何保證元素的惟一性的?
經過【compareTo】或者【compare】方法來保證元素的惟一性。 當Comparable接口中的compareTo()函數返回值爲【0】時,說明兩個對象相等,此時該對象不會被添加進來。
2二、使用TreeSet集合將字符串 String str = "8 10 15 5 2 7"; 的數值進行排序。
public class Demo{ public static void main(String[] args){ String str = "8 10 15 5 2 7"; String strs = str.split(" "); TreeSet ts = new TreeSet(); for(int x= 0;x<strs.length();x++){ int y = Integer.parseInt(strs[x]); ts.add(y); } System.out.println(ts); } }
2三、遍歷Map集合的方式有哪些?
方式一:使用keySet 將Map轉成Set集合【keySet()】,經過Set的迭代器【Iterator】取出Set集合中的每個元素, 即Map集合中全部的鍵,再經過get()方法獲取鍵對應的值 Set<Integer> ks = map.keySet(); Iterator<Integer> it = ks.iterator(); while(it.hasNext()){ Integer key = it.next(); String value = map.get(key); } 方式二:經過values獲取全部值,可是不能獲取到key對象 Collection<String> vs = map.values(); Iterator<String> it = vs.iterator(); while(it.hasNext()){ String value = it.next(); } 方式三:Map.Entry -->> public static interface Map.Entry<K,V> 經過Map中的entrySet()方法獲取存放Map.Entry<K,V>對象的Set集合 -->> Set<Map.Entry<K,V>> entrySet() Set<Map.Entry<Integer,String>> entrySet = map.entrySet(); Iterator<Map.Entry<Integer,String>> it = entrySet.iterator(); while(it.hasNext()){ Map.Entry<Integer,String> en = it.next(); } Integer key = en.getKey(); String value = en.getValue();