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