更新時間:2018-11-26 來源:黑馬程序員 瀏覽量:
1、如何定義Collection?
Collection是一個集合體系的頂層接口,此接口中的方法都是:public abstract。
可以進行增刪改查的操作:
增加: -->> boolean add(Object o) 一次添加一個元素,元素可以是Object 的子類,返回true
boolean addAll(Collection c) 一次添加一批元素,參數(shù)是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() 獲取集合中的個數(shù)
修改: -->> clear() 清空集合中的所有元素
獲取: -->> int size() 返回集合容器的大小
集合轉換為數(shù)組:
Object[] toArray(); 該方法將集合轉為數(shù)組,集合中的每一個元素,作為了數(shù)組一個的元素
【注意:集合中存儲的是對象的引用,而不是對象本身】
【注意:接口與接口之間屬于:繼承關系】
2、錄入用戶在控制臺輸入的信息,可以使用Scanner類
Scanner sc = new Scanner();
3、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) 替換指定位置的元素,需要確定該元素的位置和新元素,返回就元素。
ListsubList(int fromIndex,int toIndex) 截取子結合,返回一個List,包含頭,不包含尾。
查:
Object get(int index) 獲取List結合指定位置的元素
int indexOf(Object o) 返回此列表中第一次出現(xiàn)的指定元素的索引
int lastIndexOf(Object o) 倒序查找指定元素的位置
【注意角標越界:IndexOutOfBoundException // 找不到返回:-1】
【Object set = new list.get(list.size()-1);】
【List集合特有的增刪改查方法都跟角標有關系!!!!】
【問:如何取出List集合中的元素?】
通過for循環(huán),并使用size()和set()方法可取出List集合中的每一個元素。
4、ArrayList -->> 是一個List接口的實現(xiàn)類
具備List集合的特點:有序、有角標、可重復。
該類內部,維護了一個數(shù)組, 數(shù)組的元素是Object 類.
在ArrayList 類的構造函數(shù)中初始化的該數(shù)組, 如果沒有顯示的指定數(shù)組的長度,【默認長度是10】
也就是說: 使用無參數(shù)構造,new ArraList(), 自動創(chuàng)建的數(shù)組長度是60%.
ArrayList 在添加元素時,都會檢測數(shù)組是否已滿,如果滿了,自動擴容(創(chuàng)建一個新數(shù)組),
【新數(shù)組長度的是老數(shù)組的1.6倍】
并且將老數(shù)組中的元素拷貝到了新數(shù)組,使用新數(shù)組繼續(xù)增加元素.
5、ArrayList使用什么實現(xiàn)的?其優(yōu)缺點是什么?
ArrayList是使用數(shù)組實現(xiàn)的。
優(yōu)點:內存地址連續(xù),查找快;
缺點:增加和刪除元素,需要設計數(shù)組的擴容或者拷貝,效率很低。
---->> 總結: 數(shù)組實現(xiàn),查找快,增刪慢。
ArrayList中的方法:
boolean contains(Object o) 判斷集合是否包含指定的元素,涉及了元素的比較(對象的比較)
內部使用了元素的equals()方法。
String類 重寫了equals()方法
6、LinkedList ---->> List接口的實現(xiàn)類,具備:有序、有角標、元素可重復的特點?!竞虯rrayList類似】
LinkedList是一個雙向鏈表,該集合提供了方便操作集合頭和集合尾的方法。
【如果集合中沒有元素可以獲取或者刪除,則拋:NoSuchElementException】
LinkedList特有的方法:
增加:
void addFirst(Element e)
void addLast(Element e)
刪除:
Object getFirst()
Object getLast()
查找:
Object removeFirst() 移除并返回此列表的第一個元素
Object removeLast() 移除并返回此列表的最后一個元素
數(shù)據(jù)結構:
堆棧:
void push(Element e) 將元素推入此列表所表示的堆棧
Element pop() 從此列表所表示的堆棧處彈出一個元素
【壓棧和彈棧:先進后出,后進先出】
隊列:
boolean offer(Element e) 將指定元素添加到此列表的末尾(最后一個元素)
Element poll() 獲取并移除此列表的頭(第一個元素)
Element peek() 獲取但不移除列表的頭(第一個元素)
【隊列的數(shù)據(jù)結構:先進先出】
返回逆序的迭代器對象:
descendingIterator() 返回逆序的迭代器對象
7、LinkedList的實現(xiàn)原理是什么?其優(yōu)缺點?
LinkedList的實現(xiàn)原理是:鏈表實現(xiàn),其內存地址是不連續(xù)的。
優(yōu)點:相對于數(shù)組,增加元素快;
缺點;由于內存地址不連續(xù),查找性能低。
8、集合與數(shù)組有什么區(qū)別?
相同點:數(shù)組和集合都是容器
數(shù)組和集合中存放的都是【對象的引用】而非對象本身
不同點:數(shù)組存儲【基本數(shù)據(jù)類型】,是單一的。而且一旦聲明好長度后,長度不可變;
集合【只能】儲存【對象】,但是可以是任意類型的對象,其長度可變。
【集合的分類】
----|Iterable:接口
Iterator iterator()
----|Collection:單列集合
----|List: 有序存儲順序,可重復
----|ArrayList: 數(shù)組實現(xiàn),查找快、增刪慢
由于是數(shù)組實現(xiàn),在增和刪的時候會牽扯到數(shù)組增容,以及拷貝元素,所以慢;
數(shù)組是可以直接按索引查找的,所以查找時比較快。
----|LinkedList: 鏈表實現(xiàn),增刪快、查找慢
由于鏈表實現(xiàn),增加時只要讓前一個元素記住自己就可以了,刪除時讓前一個元
素記住后一個元素,后一個元素記住前一個元素,這樣的增刪效率高;
但查詢時需要一個一個的遍歷,所以效率比較低。
----|Vector: 多線程安全、效率略低 【ArrayList單線程效率高,但是多線程要使用Vector】
----|set: 無序存儲,不可重復
----|HashSet 線程不安全,存取速度快
底層是以hash表實現(xiàn)的
----|TreeSet 紅-黑樹的數(shù)據(jù)結構,默認對元素進行自然排序(String)
【TreeSet自身具備排序功能】
----|Comparable
----|compareTo(Object o) 元素自身具備比較性
----|Comparator
----|compare(Object o1,Object o2) 給容器傳入比較器
如果在比較的時候兩個對象返回值是【0】,那么這兩個元素【重復】
【當Comparable和Comparator比較方式同時存在時,以Comparator比較方式為主】
----|LinkedHashSet 會保存插入的順序
----|Map: 將鍵映射到值的對象。一個映射不能包含重復的鍵,每個鍵最多只能映射一個值。
interface Map
----|TreeMap 底層是二叉樹數(shù)據(jù)結構,可以對map集合中的鍵進行排序
需要使用Comparable或者Comparator進行比較排序。
【return 0 判斷鍵的唯一性】
----|HashTable 底層是哈希表數(shù)據(jù)結構,線程是【同步】的 -->> 不可以存入null鍵、null值
效率較低,故被【HashMap】替代
----|HashMap 采用哈希表實現(xiàn) -->> 【無序】
底層是哈希表數(shù)據(jù)結構,線程是【不同步】的 -->> 可以存入null鍵、null值
【要保證鍵的唯一性,需要覆蓋hashCode()方法和equals()方法】
----|LinkedHashMap
【常用方法:】
添加: V put(K key,V value) 可以是相同的key值,但是添加的value值會覆蓋前面的
putAll(Map m)
從指定映射中將所有映射關系復制到此映射中(可選操作)
刪除: remove(Object key) 刪除關聯(lián)對象,指定key對象
clear() 清空集合對象
獲?。?value get(Object key) 可以用于判斷鍵是否存在的情況。
判斷: boolean isEmpty() 如果此映射不包含鍵-值映射關系【即長度為0】,則返回true,否則返回false
boolean containsKey(Object key)
判斷集合中是否包含指定的key
boolean containsValue(Object value)
判斷集合中是否包含指定的value
當指定的鍵不存在的時候,返回的是null
長度: int size() 返回此映射中的鍵-值映射關系數(shù)
9、在什么時候該使用什么樣的集合?
Collection 當我們需要保存若干個對象的時候使用集合
-->> List 如果需要保留存儲順序、并且重復元素時,使用List
-->> 如果查詢較多,使用ArrayList;
如果存取較多,使用LinkedList;
如果需要線程安全,使用Vector。
-->> Set 如果不需要保留存儲順序,并且要去掉重復元素時,使用Set
-->> 如果需要將元素排序,使用TreeSet;
如果不需要排序,使用HashSet 【HashSet比TreeSet效率高】
如果需要保留存儲順序,同時要過濾重復元素,使用LinkedHashSet。
10、自定義對象時為什么要重寫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++){< p="">
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;
}
}
11、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());
}
}
12、Iterable: 是Collection的父接口,實現(xiàn)Iterable的類可以進行迭代,并且支持增強for循環(huán)
該接口只有一個方法,用于返回集合迭代器對象! 【獲取迭代器的方法iterator()】
piblic interface Iterable
Iteratoriterator():該類主要用于遍歷集合對象,并描述了遍歷集合的常見方法
boolean hasNext() 判斷集合中是否有元素,如果有元素可以迭代,就返回true。
E next() 返回迭代的下一個元素。
如果沒有下一個元素,調用next()會拋出 -->> NoSuchElementException
void remove() 從迭代器指向的集合中移除迭代器返回的最后一個元素
【Iterator的for循環(huán)、清空】
public class Demo{
ArrayList list = new ArrayList();
// 增加:add() 將指定對象存儲到容器中
list.add("計算機網(wǎng)絡");
list.add("現(xiàn)代操作系統(tǒng)");
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();
}
}
【細節(jié)一:如果迭代器的指針已經指向了集合的末尾,那么如果再調用next()會返回NoSuchElementException異?!?/p>
【細節(jié)二:如果調用remove()之前沒有調用next()方法是不合法的,會拋出IllegalStateException異?!?/p>
【細節(jié)三:當一個集合在循環(huán)中即使用引用變量操作集合,又使用迭代器操作集合對象,會拋出ConcurrentModificationException異?!?/p>
13、為什么next()方法的返回值類型是Object呢?
為了可以接收任意類型的對象
如果返回的時候不知道是什么類型的,就定義為object
14、Iterator和ListIterator有什么關系?
ListIterator是Iterator的子接口,是List集合特有的迭代器。
Iterator在迭代時,只能對元素進行獲取【next()】和刪除【remove()】的操作;
ListIterator在迭代list集合時,還可以對元素進行添加【add(obj)】和修改【set(obj)】的操作。
15、List集合特有的迭代器ListIterator
---->> public interface ListIterator extends Iterator
ListIteratorlistIteraotr()
----| Iterator
hasNext()
next()
remove()
----| ListIterator
add(E e) 將指定的元素插入列表(可選操作)。
該元素直接插入到next()返回的下一個元素的前面(如果有)
void set(E o) 用指定的元素替換next()或previous()返回的 【最后】 一個元素
hasPrevious() 逆向遍歷列表,列表迭代器有多個元素,則返回true
previous() 返回列表中的前一個元素
16、HashSet是如何判斷兩個元素重復的?
通過hashCode()方法和equals()方法來保證元素的唯一性,add()方法返回的是boolean類型
【調用原理:HashSet集合在判斷元素是否相同,先判斷hashCode()方法,相同才會判斷equals()方法;不相同不會調用equals()】
17、HashSet和ArrayList集合在判斷元素時是否有相同的方法?
有:boolean contains(Object o)
HashSet使用hashCode()和equals()方法,ArrayList使用eqauls()方法。
18、給TreeSet指定排序規(guī)則:
方式一:【元素自身】具備比較性
元素自身具備比較性,需要元素實現(xiàn)【Comparable接口】,重寫【compareTo方法】,
也就是讓元素自身具備比較性,這種方式叫做元素的【自然排序】也叫做【默認排序】。
方式二:【容器】具備比較性
當元素自身不具備比較性,或者自身具備的比較性不是所需要的。
那么此時可以讓容器自身具備。需要定義一個類實現(xiàn)【Comparator接口】,重寫【compare方法】,
并將該接口的子類實例對象作為參數(shù)傳遞給【TreeSet集合】的【構造方法】。
注意:當Comparable比較方式和Comparator比較方式同時存在時,以【Comparator】的比較方式為主;
注意:在重寫compareTo或者compare方法時,必須要明確比較的主要條件相等時要比較次要條件。
通過return 0 來判斷唯一性。
19、為什么使用TreeSet存入字符串,字符串默認輸出是按升序排列的?
因為字符串實現(xiàn)了一個接口,叫做【Comparable接口】,字符串重寫了該接口的【compareTo()方法】,
所以String對象具備了比較性。
【自定義的元素(比如Person類、Book類)想要存入TreeSet集合,就必須實現(xiàn)Comparable接口,也就是要讓自定義對象具備比較性】
【存入TreeSet集合的元素都要具備比較性:要實現(xiàn)Comparable接口、并重寫該接口的compareTo()方法】
20、總結:
看到array,就要想到角標。
看到link, 就要想到first,last。
看到hash, 就要想到hashCode,equals.
看到tree, 就要想到兩個接口。Comparable,Comparator。
21、TreeSet是如何保證元素的唯一性的?
通過【compareTo】或者【compare】方法來保證元素的唯一性。
當Comparable接口中的compareTo()函數(shù)返回值為【0】時,說明兩個對象相等,此時該對象不會被添加進來。
22、使用TreeSet集合將字符串 String str = "8 10 15 5 2 7"; 的數(shù)值進行排序。
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++){< p="">
int y = Integer.parseInt(strs[x]);
ts.add(y);
}
System.out.println(ts);
}
}
23、遍歷Map集合的方式有哪些?
方式一:使用keySet
將Map轉成Set集合【keySet()】,通過Set的迭代器【Iterator】取出Set集合中的每一個元素,
即Map集合中所有的鍵,再通過get()方法獲取鍵對應的值
Setks = map.keySet();
Iteratorit = ks.iterator();
while(it.hasNext()){
Integer key = it.next();
String value = map.get(key);
}
方式二:通過values獲取所有值,但是不能獲取到key對象
Collectionvs = map.values();
Iteratorit = vs.iterator();
while(it.hasNext()){
String value = it.next();
}
方式三:Map.Entry -->> public static interface Map.Entry
通過Map中的entrySet()方法獲取存放Map.Entry對象的Set集合 -->> Set<map.entry> entrySet()
Set<map.entry> entrySet = map.entrySet();
Iterator<map.entry> it = entrySet.iterator();
while(it.hasNext()){
Map.Entryen = it.next();
}
Integer key = en.getKey();
String value = en.getValue();
首發(fā): http://java.itheima.com