摘要:集合框架重點(diǎn)理解用于存儲(chǔ)數(shù)據(jù)的容器。集合容器在不斷向上抽取過(guò)程中。出現(xiàn)了集合體系。,刪除將集合中的元素全刪除,清空集合。刪除集合中指定的對(duì)象。注意刪除成功,集合的長(zhǎng)度會(huì)改變。作用用于取集合中的元素。是集合特有的迭代器。是單列集合是雙列集合
集合框架(重點(diǎn)理解):
用于存儲(chǔ)數(shù)據(jù)的容器。
特點(diǎn):
1:對(duì)象封裝數(shù)據(jù),對(duì)象多了也需要存儲(chǔ)。集合用于存儲(chǔ)對(duì)象。
2:對(duì)象的個(gè)數(shù)確定可以使用數(shù)組,但是不確定怎么辦?可以用集合。因?yàn)榧鲜强勺冮L(zhǎng)度的。
集合和數(shù)組的區(qū)別:
1:數(shù)組是固定長(zhǎng)度的;集合可變長(zhǎng)度的。
2:數(shù)組可以存儲(chǔ)基本數(shù)據(jù)類型,也可以存儲(chǔ)引用數(shù)據(jù)類型;集合只能存儲(chǔ)引用數(shù)據(jù)類型。
3:數(shù)組存儲(chǔ)的元素必須是同一個(gè)數(shù)據(jù)類型;集合存儲(chǔ)的對(duì)象可以是不同數(shù)據(jù)類型。
數(shù)據(jù)結(jié)構(gòu):就是容器中存儲(chǔ)數(shù)據(jù)的方式。
對(duì)于集合容器,有很多種。因?yàn)槊恳粋€(gè)容器的自身特點(diǎn)不同,其實(shí)原理在于每個(gè)容器的內(nèi)部數(shù)據(jù)結(jié)構(gòu)不同。
集合容器在不斷向上抽取過(guò)程中。出現(xiàn)了集合體系。
在使用一個(gè)體系時(shí),原則:參閱頂層內(nèi)容。建立底層對(duì)象。
--< java.util >-- Collection接口:
Collection:
|--List:有序(元素存入集合的順序和取出的順序一致),元素都有索引。元素可以重復(fù)。
|--Set:無(wú)序(存入和取出順序有可能不一致),不可以存儲(chǔ)重復(fù)元素。必須保證元素唯一性。
1,添加:
add(object):添加一個(gè)元素
addAll(Collection) :添加一個(gè)集合中的所有元素。
2,刪除:
clear():將集合中的元素全刪除,清空集合。
remove(obj) :刪除集合中指定的對(duì)象。注意:刪除成功,集合的長(zhǎng)度會(huì)改變。
removeAll(collection) :刪除部分元素。部分元素和傳入Collection一致。
3,判斷:
boolean contains(obj) :集合中是否包含指定元素 。
boolean containsAll(Collection) :集合中是否包含指定的多個(gè)元素。
boolean isEmpty():集合中是否有元素。
4,獲?。?br>int size():集合中有幾個(gè)元素。
5,取交集:
boolean retainAll(Collection) :對(duì)當(dāng)前集合中保留和指定集合中的相同的元素。如果兩個(gè)集合元素相同,返回flase;如果retainAll修改了當(dāng)前集合,返回true。
6,獲取集合中所有元素:
Iterator iterator():迭代器
7,將集合變成數(shù)組:
--< java.util >-- Iterator接口:
迭代器:是一個(gè)接口。作用:用于取集合中的元素。
boolean hasNext()??如果仍有元素可以迭代,則返回?true。
?E next()???返回迭代的下一個(gè)元素。
void remove()??從迭代器指向的?collection?中移除迭代器返回的最后一個(gè)元素(可選操作)。
每一個(gè)集合都有自己的數(shù)據(jù)結(jié)構(gòu),都有特定的取出自己內(nèi)部元素的方式。為了便于操作所有的容器,取出元素。將容器內(nèi)部的取出方式按照一個(gè)統(tǒng)一的規(guī)則向外提供,這個(gè)規(guī)則就是Iterator接口。
也就說(shuō),只要通過(guò)該接口就可以取出Collection集合中的元素,至于每一個(gè)具體的容器依據(jù)自己的數(shù)據(jù)結(jié)構(gòu),如何實(shí)現(xiàn)的具體取出細(xì)節(jié),這個(gè)不用關(guān)心,這樣就降低了取出元素和具體集合的耦合性。
public static void main(String[] args) {
Collection coll = new ArrayList();
coll.add("abc0");
coll.add("abc1");
coll.add("abc2");
//--------------方式1----------------------
Iterator it = coll.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//---------------方式2用此種----------------------
for(Iterator it = coll.iterator();it.hasNext(); ){
System.out.println(it.next());
}
--< java.util >-- List接口:
List本身是Collection接口的子接口,具備了Collection的所有方法?,F(xiàn)在學(xué)習(xí)List體系特有的共性方法,查閱方法發(fā)現(xiàn)List的特有方法都有索引,這是該集合最大的特點(diǎn)。
List:有序(元素存入集合的順序和取出的順序一致),元素都有索引。元素可以重復(fù)。
|--ArrayList:底層的數(shù)據(jù)結(jié)構(gòu)是數(shù)組,線程不同步,ArrayList替代了Vector,查詢?cè)氐乃俣确浅?臁?br>|--LinkedList:底層的數(shù)據(jù)結(jié)構(gòu)是鏈表,線程不同步,增刪元素的速度非常快。
|--Vector:底層的數(shù)據(jù)結(jié)構(gòu)就是數(shù)組,線程同步的,Vector無(wú)論查詢和增刪都巨慢。
1,添加:
add(index,element) :在指定的索引位插入元素。
addAll(index,collection) :在指定的索引位插入一堆元素。
2,刪除:
remove(index) :刪除指定索引位的元素。 返回被刪的元素。
3,獲取:
Object get(index) :通過(guò)索引獲取指定元素。
int indexOf(obj) :獲取指定元素第一次出現(xiàn)的索引位,如果該元素不存在返回-1;
所以,通過(guò)-1,可以判斷一個(gè)元素是否存在。
int lastIndexOf(Object o) :反向索引指定元素的位置。
List subList(start,end) :獲取子列表。
4,修改:
Object set(index,element) :對(duì)指定索引位進(jìn)行元素的修改。
5,獲取所有元素:
ListIterator listIterator():list集合特有的迭代器。
List集合支持對(duì)元素的增、刪、改、查。
List集合因?yàn)榻菢?biāo)有了自己的獲取元素的方式: 遍歷。
for(int x=0; x
}
在進(jìn)行l(wèi)ist列表元素迭代的時(shí)候,如果想要在迭代過(guò)程中,想要對(duì)元素進(jìn)行操作的時(shí)候,比如滿足條件添加新元素。會(huì)發(fā)生.ConcurrentModificationException并發(fā)修改異常。
導(dǎo)致的原因是:
集合引用和迭代器引用在同時(shí)操作元素,通過(guò)集合獲取到對(duì)應(yīng)的迭代器后,在迭代中,進(jìn)行集合引用的元素添加,迭代器并不知道,所以會(huì)出現(xiàn)異常情況。
如何解決呢?
既然是在迭代中對(duì)元素進(jìn)行操作,找迭代器的方法最為合適.可是Iterator中只有hasNext,next,remove方法.通過(guò)查閱的它的子接口,ListIterator,發(fā)現(xiàn)該列表迭代器接口具備了對(duì)元素的增、刪、改、查的動(dòng)作。
ListIterator是List集合特有的迭代器。
ListIterator it = list.listIterator;//取代Iterator it = list.iterator;
方法摘要
void add(E?e)?將指定的元素插入列表(可選操作)。
boolean hasNext()?以正向遍歷列表時(shí),如果列表迭代器有多個(gè)元素,則返回?true(換句話說(shuō),如果?next?返回一個(gè)元素而不是拋出異常,則返回?true)。
boolean hasPrevious()?如果以逆向遍歷列表,列表迭代器有多個(gè)元素,則返回?true。
?E next()?返回列表中的下一個(gè)元素。
int nextIndex()?返回對(duì)?next?的后續(xù)調(diào)用所返回元素的索引。
?E previous()?返回列表中的前一個(gè)元素。
int previousIndex()?返回對(duì)?previous?的后續(xù)調(diào)用所返回元素的索引。
void remove()?從列表中移除由?next?或?previous?返回的最后一個(gè)元素(可選操作)。
void set(E?e)?用指定元素替換?next?或?previous?返回的最后一個(gè)元素(可選操作)。
可變長(zhǎng)度數(shù)組的原理:
當(dāng)元素超出數(shù)組長(zhǎng)度,會(huì)產(chǎn)生一個(gè)新數(shù)組,將原數(shù)組的數(shù)據(jù)復(fù)制到新數(shù)組中,再將新的元素添加到新數(shù)組中。
ArrayList:是按照原數(shù)組的50%延長(zhǎng)。構(gòu)造一個(gè)初始容量為 10 的空列表。
Vector:是按照原數(shù)組的100%延長(zhǎng)。
注意:對(duì)于list集合,底層判斷元素是否相同,其實(shí)用的是元素自身的equals方法完成的。所以建議元素都要復(fù)寫equals方法,建立元素對(duì)象自己的比較相同的條件依據(jù)。
LinkedList:的特有方法。
addFirst();
addLast();
在jdk1.6以后。
offerFirst();
offerLast();
getFirst():獲取鏈表中的第一個(gè)元素。如果鏈表為空,拋出NoSuchElementException;
getLast();
在jdk1.6以后。
peekFirst();獲取鏈表中的第一個(gè)元素。如果鏈表為空,返回null。
peekLast();
removeFirst():獲取鏈表中的第一個(gè)元素,但是會(huì)刪除鏈表中的第一個(gè)元素。如果鏈表為空,拋出NoSuchElementException
removeLast();
在jdk1.6以后。
pollFirst();獲取鏈表中的第一個(gè)元素,但是會(huì)刪除鏈表中的第一個(gè)元素。如果鏈表為空,返回null。
--< java.util >-- Set接口:
Set接口中的方法和Collection中方法一致的。Set接口取出方式只有一種,迭代器。
|--HashSet:底層數(shù)據(jù)結(jié)構(gòu)是哈希表,線程是不同步的。無(wú)序,高效;
HashSet集合保證元素唯一性:通過(guò)元素的hashCode方法,和equals方法完成的。
當(dāng)元素的hashCode值相同時(shí),才繼續(xù)判斷元素的equals是否為true。
如果為true,那么視為相同元素,不存。如果為false,那么存儲(chǔ)。
如果hashCode值不同,那么不判斷equals,從而提高對(duì)象比較的速度。
|--LinkedHashSet:有序,hashset的子類。
|--TreeSet:對(duì)Set集合中的元素的進(jìn)行指定順序的排序。不同步。TreeSet底層的數(shù)據(jù)結(jié)構(gòu)就是二叉樹。
哈希表的原理:
1,對(duì)對(duì)象元素中的關(guān)鍵字(對(duì)象中的特有數(shù)據(jù)),進(jìn)行哈希算法的運(yùn)算,并得出一個(gè)具體的算法值,這個(gè)值 稱為哈希值。
2,哈希值就是這個(gè)元素的位置。
3,如果哈希值出現(xiàn)沖突,再次判斷這個(gè)關(guān)鍵字對(duì)應(yīng)的對(duì)象是否相同。如果對(duì)象相同,就不存儲(chǔ),因?yàn)樵刂貜?fù)。如果對(duì)象不同,就存儲(chǔ),在原來(lái)對(duì)象的哈希值基礎(chǔ) +1順延。
4,存儲(chǔ)哈希值的結(jié)構(gòu),我們稱為哈希表。
5,既然哈希表是根據(jù)哈希值存儲(chǔ)的,為了提高效率,最好保證對(duì)象的關(guān)鍵字是唯一的。
這樣可以盡量少的判斷關(guān)鍵字對(duì)應(yīng)的對(duì)象是否相同,提高了哈希表的操作效率。
對(duì)于ArrayList集合,判斷元素是否存在,或者刪元素底層依據(jù)都是equals方法。
對(duì)于HashSet集合,判斷元素是否存在,或者刪除元素,底層依據(jù)的是hashCode方法和equals方法。
TreeSet:
用于對(duì)Set集合進(jìn)行元素的指定順序排序,排序需要依據(jù)元素自身具備的比較性。
如果元素不具備比較性,在運(yùn)行時(shí)會(huì)發(fā)生ClassCastException異常。
所以需要元素實(shí)現(xiàn)Comparable接口,強(qiáng)制讓元素具備比較性,復(fù)寫compareTo方法。
依據(jù)compareTo方法的返回值,確定元素在TreeSet數(shù)據(jù)結(jié)構(gòu)中的位置。
TreeSet方法保證元素唯一性的方式:就是參考比較方法的結(jié)果是否為0,如果return 0,視為兩個(gè)對(duì)象重復(fù),不存。
注意:在進(jìn)行比較時(shí),如果判斷元素不唯一,比如,同姓名,同年齡,才視為同一個(gè)人。
在判斷時(shí),需要分主要條件和次要條件,當(dāng)主要條件相同時(shí),再判斷次要條件,按照次要條件排序。
TreeSet集合排序有兩種方式,Comparable和Comparator區(qū)別:
1:讓元素自身具備比較性,需要元素對(duì)象實(shí)現(xiàn)Comparable接口,覆蓋compareTo方法。
2:讓集合自身具備比較性,需要定義一個(gè)實(shí)現(xiàn)了Comparator接口的比較器,并覆蓋compare方法,并將該類對(duì)象作為實(shí)際參數(shù)傳遞給TreeSet集合的構(gòu)造函數(shù)。
第二種方式較為靈活。
Map集合:
|--Hashtable:底層是哈希表數(shù)據(jù)結(jié)構(gòu),是線程同步的。不可以存儲(chǔ)null鍵,null值。
|--HashMap:底層是哈希表數(shù)據(jù)結(jié)構(gòu),是線程不同步的??梢源鎯?chǔ)null鍵,null值。替代了Hashtable.
|--TreeMap:底層是二叉樹結(jié)構(gòu),可以對(duì)map集合中的鍵進(jìn)行指定順序的排序。
Map集合存儲(chǔ)和Collection有著很大不同:
Collection一次存一個(gè)元素;Map一次存一對(duì)元素。
Collection是單列集合;Map是雙列集合。
Map中的存儲(chǔ)的一對(duì)元素:一個(gè)是鍵,一個(gè)是值,鍵與值之間有對(duì)應(yīng)(映射)關(guān)系。
特點(diǎn):要保證map集合中鍵的唯一性。
1,添加。
put(key,value):當(dāng)存儲(chǔ)的鍵相同時(shí),新的值會(huì)替換老的值,并將老值返回。如果鍵沒(méi)有重復(fù),返回null。
void putAll(Map);
2,刪除。
void clear():清空
value remove(key) :刪除指定鍵。
3,判斷。
boolean isEmpty():
boolean containsKey(key):是否包含key
boolean containsValue(value) :是否包含value
4,取出。
int size():返回長(zhǎng)度
value get(key) :通過(guò)指定鍵獲取對(duì)應(yīng)的值。如果返回null,可以判斷該鍵不存在。當(dāng)然有特殊情況,就是在hashmap集合中,是可以存儲(chǔ)null鍵null值的。
Collection values():獲取map集合中的所有的值。
5,想要獲取map中的所有元素:
原理:map中是沒(méi)有迭代器的,collection具備迭代器,只要將map集合轉(zhuǎn)成Set集合,可以使用迭代器了。之所以轉(zhuǎn)成set,是因?yàn)閙ap集合具備著鍵的唯一性,其實(shí)set集合就來(lái)自于map,set集合底層其實(shí)用的就是map的方法。
★ 把map集合轉(zhuǎn)成set的方法:
Set keySet();
Set entrySet();//取的是鍵和值的映射關(guān)系。
Entry就是Map接口中的內(nèi)部接口;
取出map集合中所有元素的方式一:keySet()方法。
可以將map集合中的鍵都取出存放到set集合中。對(duì)set集合進(jìn)行迭代。迭代完成,再通過(guò)get方法對(duì)獲取到的鍵進(jìn)行值的獲取。
Set keySet = map.keySet();
Iterator it = keySet.iterator();
while(it.hasNext()) {
Object key = it.next();
Object value = map.get(key);
System.out.println(key+":"+value);
取出map集合中所有元素的方式二:entrySet()方法。
Set entrySet = map.entrySet();
Iterator it = entrySet.iterator();
while(it.hasNext()) {
Map.Entry me = (Map.Entry)it.next();
System.out.println(me.getKey()+"::::"+me.getValue());
使用集合的技巧:
看到Array就是數(shù)組結(jié)構(gòu),有角標(biāo),查詢速度很快。
看到link就是鏈表結(jié)構(gòu):增刪速度快,而且有特有方法。addFirst; addLast; removeFirst(); removeLast(); getFirst();getLast();
看到hash就是哈希表,就要想要哈希值,就要想到唯一性,就要想到存入到該結(jié)構(gòu)的中的元素必須覆蓋hashCode,equals方法。
看到tree就是二叉樹,就要想到排序,就想要用到比較。
比較的兩種方式:
一個(gè)是Comparable:覆蓋compareTo方法;
一個(gè)是Comparator:覆蓋compare方法。
LinkedHashSet,LinkedHashMap:這兩個(gè)集合可以保證哈希表有存入順序和取出順序一致,保證哈希表有序。
集合什么時(shí)候用?
當(dāng)存儲(chǔ)的是一個(gè)元素時(shí),就用Collection。當(dāng)存儲(chǔ)對(duì)象之間存在著映射關(guān)系時(shí),就使用Map集合。
Collections:它的出現(xiàn)給集合操作提供了更多的功能。這個(gè)類不需要?jiǎng)?chuàng)建對(duì)象,內(nèi)部提供的都是靜態(tài)方法。
靜態(tài)方法:
Collections.sort(list);//list集合進(jìn)行元素的自然順序排序。
Collections.sort(list,new ComparatorByLen());//按指定的比較器方法排序。
class ComparatorByLen implements Comparator
public int compare(String s1,String s2){
int temp = s1.length()-s2.length();
return temp==0?s1.compareTo(s2):temp;
}
}
Collections.max(list); //返回list中字典順序最大的元素。
int index = Collections.binarySearch(list,"zz");//二分查找,返回角標(biāo)。
Collections.reverseOrder();//逆向反轉(zhuǎn)排序。
Collections.shuffle(list);//隨機(jī)對(duì)list中的元素進(jìn)行位置的置換。
將非同步集合轉(zhuǎn)成同步集合的方法:Collections中的 XXX synchronizedXXX(XXX);
List synchronizedList(list);
Map synchronizedMap(map);
原理:定義一個(gè)類,將集合所有的方法加同一把鎖后返回。
Collection 和 Collections的區(qū)別:
Collections是個(gè)java.util下的類,是針對(duì)集合類的一個(gè)工具類,提供一系列靜態(tài)方法,實(shí)現(xiàn)對(duì)集合的查找、排序、替換、線程安全化(將非同步的集合轉(zhuǎn)換成同步的)等操作。
Arrays:
用于操作數(shù)組對(duì)象的工具類,里面都是靜態(tài)方法。
asList方法:將數(shù)組轉(zhuǎn)換成list集合。
String[] arr = {"abc","kk","qq"};
List
將數(shù)組轉(zhuǎn)換成集合,有什么好處呢?用aslist方法,將數(shù)組變成集合;
可以通過(guò)list集合中的方法來(lái)操作數(shù)組中的元素:isEmpty()、contains、indexOf、set;
注意(局限性):數(shù)組是固定長(zhǎng)度,不可以使用集合對(duì)象增加或者刪除等,會(huì)改變數(shù)組長(zhǎng)度的功能方法。比如add、remove、clear。(會(huì)報(bào)不支持操作異常UnsupportedOperationException);
如果數(shù)組中存儲(chǔ)的引用數(shù)據(jù)類型,直接作為集合的元素可以直接用集合方法操作。
如果數(shù)組中存儲(chǔ)的是基本數(shù)據(jù)類型,asList會(huì)將數(shù)組實(shí)體作為集合元素存在。
集合變數(shù)組:用的是Collection接口中的方法:toArray();
如果給toArray傳遞的指定類型的數(shù)據(jù)長(zhǎng)度小于了集合的size,那么toArray方法,會(huì)自定再創(chuàng)建一個(gè)該類型的數(shù)據(jù),長(zhǎng)度為集合的size。
如果傳遞的指定的類型的數(shù)組的長(zhǎng)度大于了集合的size,那么toArray方法,就不會(huì)創(chuàng)建新數(shù)組,直接使用該數(shù)組即可,并將集合中的元素存儲(chǔ)到數(shù)組中,其他為存儲(chǔ)元素的位置默認(rèn)值null。
所以,在傳遞指定類型數(shù)組時(shí),最好的方式就是指定的長(zhǎng)度和size相等的數(shù)組。
Jdk5.0新特性:
Collection在jdk1.5以后,有了一個(gè)父接口Iterable,這個(gè)接口的出現(xiàn)的將iterator方法進(jìn)行抽取,提高了擴(kuò)展性。增強(qiáng)for循環(huán):foreach語(yǔ)句,foreach簡(jiǎn)化了迭代器。
格式:// 增強(qiáng)for循環(huán)括號(hào)里寫兩個(gè)參數(shù),第一個(gè)是聲明一個(gè)變量,第二個(gè)就是需要迭代的容器
for( 元素類型 變量名 : Collection集合 & 數(shù)組 ) {
…
}
高級(jí)for循環(huán)和傳統(tǒng)for循環(huán)的區(qū)別:
高級(jí)for循環(huán)在使用時(shí),必須要明確被遍歷的目標(biāo)。這個(gè)目標(biāo),可以是Collection集合或者數(shù)組,如果遍歷Collection集合,在遍歷過(guò)程中還需要對(duì)元素進(jìn)行操作,比如刪除,需要使用迭代器。
如果遍歷數(shù)組,還需要對(duì)數(shù)組元素進(jìn)行操作,建議用傳統(tǒng)for循環(huán)因?yàn)榭梢远x角標(biāo)通過(guò)角標(biāo)操作元素。如果只為遍歷獲取,可以簡(jiǎn)化成高級(jí)for循環(huán),它的出現(xiàn)為了簡(jiǎn)化書寫。
高級(jí)for循環(huán)可以遍歷map集合嗎?不可以。但是可以將map轉(zhuǎn)成set后再使用foreach語(yǔ)句。
1)、作用:對(duì)存儲(chǔ)對(duì)象的容器進(jìn)行迭代: 數(shù)組 collection map
2)、增強(qiáng)for循環(huán)迭代數(shù)組:
String [] arr = {"a", "b", "c"};//數(shù)組的靜態(tài)定義方式,只試用于數(shù)組首次定義的時(shí)候
for(String s : arr) {
System.out.println(s);
}
3)、單列集合 Collection:
List list = new ArrayList();
list.add("aaa");
// 增強(qiáng)for循環(huán), 沒(méi)有使用泛型的集合能不能使用增強(qiáng)for循環(huán)迭代?能
for(Object obj : list) {
String s = (String) obj;
System.out.println(s);
}
4)、雙列集合 Map:
Map map = new HashMap();
map.put("a", "aaa");
// 傳統(tǒng)方式:必須掌握這種方式
Set entrys = map.entrySet(); // 1.獲得所有的鍵值對(duì)Entry對(duì)象
iter = entrys.iterator(); // 2.迭代出所有的entry
while(iter.hasNext()) {
Map.Entry entry = (Entry) iter.next();
String key = (String) entry.getKey(); // 分別獲得key和value
String value = (String) entry.getValue();
System.out.println(key + "=" + value);
}
// 增強(qiáng)for循環(huán)迭代:原則上map集合是無(wú)法使用增強(qiáng)for循環(huán)來(lái)迭代的,因?yàn)樵鰪?qiáng)for循環(huán)只能針對(duì)實(shí)現(xiàn)了Iterable接口的集合進(jìn)行迭代;Iterable是jdk5中新定義的接口,就一個(gè)方法iterator方法,只有實(shí)現(xiàn)了Iterable接口的類,才能保證一定有iterator方法,java有這樣的限定是因?yàn)樵鰪?qiáng)for循環(huán)內(nèi)部還是用迭代器實(shí)現(xiàn)的,而實(shí)際上,我們可以通過(guò)某種方式來(lái)使用增強(qiáng)for循環(huán)。
for(Object obj : map.entrySet()) {
Map.Entry entry = (Entry) obj; // obj 依次表示Entry
System.out.println(entry.getKey() + "=" + entry.getValue());
}
5)、集合迭代注意問(wèn)題:在迭代集合的過(guò)程中,不能對(duì)集合進(jìn)行增刪操作(會(huì)報(bào)并發(fā)訪問(wèn)異常);可以用迭代器的方法進(jìn)行操作(子類listIterator:有增刪的方法)。
6)、增強(qiáng)for循環(huán)注意問(wèn)題:在使用增強(qiáng)for循環(huán)時(shí),不能對(duì)元素進(jìn)行賦值;
int[] arr = {1,2,3};
for(int num : arr) {
num = 0; //不能改變數(shù)組的值
}
可變參數(shù)(...):用到函數(shù)的參數(shù)上,當(dāng)要操作的同一個(gè)類型元素個(gè)數(shù)不確定的時(shí)候,可是用這個(gè)方式,這個(gè)參數(shù)可以接受任意個(gè)數(shù)的同一類型的數(shù)據(jù)。
和以前接收數(shù)組不一樣的是:
以前定義數(shù)組類型,需要先創(chuàng)建一個(gè)數(shù)組對(duì)象,再將這個(gè)數(shù)組對(duì)象作為參數(shù)傳遞給函數(shù)?,F(xiàn)在,直接將數(shù)組中的元素作為參數(shù)傳遞即可。底層其實(shí)是將這些元素進(jìn)行數(shù)組的封裝,而這個(gè)封裝動(dòng)作,是在底層完成的,被隱藏了。所以簡(jiǎn)化了用戶的書寫,少了調(diào)用者定義數(shù)組的動(dòng)作。
如果在參數(shù)列表中使用了可變參數(shù),可變參數(shù)必須定義在參數(shù)列表結(jié)尾(也就是必須是最后一個(gè)參數(shù),否則編譯會(huì)失敗。)。
靜態(tài)導(dǎo)入:導(dǎo)入了類中的所有靜態(tài)成員,簡(jiǎn)化靜態(tài)成員的書寫。
import static java.util.Collections.*; //導(dǎo)入了Collections類中的所有靜態(tài)成員枚舉:關(guān)鍵字 enum
問(wèn)題:對(duì)象的某個(gè)屬性的值不能是任意的,必須為固定的一組取值其中的某一個(gè);
解決辦法:
1)、在setGrade方法中做判斷,不符合格式要求就拋出異常;
2)、直接限定用戶的選擇,通過(guò)自定義類模擬枚舉的方式來(lái)限定用戶的輸入,寫一個(gè)Grade類,私有構(gòu)造函數(shù),對(duì)外提供5個(gè)靜態(tài)的常量表示類的實(shí)例;
3)、jdk5中新定義了枚舉類型,專門用于解決此類問(wèn)題;
自動(dòng)拆裝箱:java中數(shù)據(jù)類型分為兩種 : 基本數(shù)據(jù)類型 引用數(shù)據(jù)類型(對(duì)象)
在 java程序中所有的數(shù)據(jù)都需要當(dāng)做對(duì)象來(lái)處理,針對(duì)8種基本數(shù)據(jù)類型提供了包裝類,如下:
int --> Integer
byte --> Byte
short --> Short
long --> Long
char --> Character
double --> Double
float --> Float
boolean --> Boolean
jdk5以前基本數(shù)據(jù)類型和包裝類之間需要互轉(zhuǎn):
基本---引用 Integer x = new Integer(x);
引用---基本 int num = x.intValue();
1)、Integer x = 1; x = x + 1; 經(jīng)歷了什么過(guò)程?裝箱 à 拆箱 à 裝箱;
2)、為了優(yōu)化,虛擬機(jī)為包裝類提供了緩沖池,Integer池的大小 -128~127 一個(gè)字節(jié)的大小;
泛型:jdk1.5版本以后出現(xiàn)的一個(gè)安全機(jī)制。表現(xiàn)格式:< >
好處:
1:將運(yùn)行時(shí)期的問(wèn)題ClassCastException問(wèn)題轉(zhuǎn)換成了編譯失敗,體現(xiàn)在編譯時(shí)期,程序員就可以解決問(wèn)題。
2:避免了強(qiáng)制轉(zhuǎn)換的麻煩。
只要帶有<>的類或者接口,都屬于帶有類型參數(shù)的類或者接口,在使用這些類或者接口時(shí),必須給<>中傳遞一個(gè)具體的引用數(shù)據(jù)類型。
泛型技術(shù):其實(shí)應(yīng)用在編譯時(shí)期,是給編譯器使用的技術(shù),到了運(yùn)行時(shí)期,泛型就不存在了。
為什么? 因?yàn)榉盒偷牟脸阂簿褪钦f(shuō),編輯器檢查了泛型的類型正確后,在生成的類文件中是沒(méi)有泛型的。
在運(yùn)行時(shí),如何知道獲取的元素類型而不用強(qiáng)轉(zhuǎn)呢?
泛型的補(bǔ)償:因?yàn)榇鎯?chǔ)的時(shí)候,類型已經(jīng)確定了是同一個(gè)類型的元素,所以在運(yùn)行時(shí),只要獲取到該元素的類型,在內(nèi)部進(jìn)行一次轉(zhuǎn)換即可,所以使用者不用再做轉(zhuǎn)換動(dòng)作了。
什么時(shí)候用泛型類呢?
當(dāng)類中的操作的引用數(shù)據(jù)類型不確定的時(shí)候,以前用的Object來(lái)進(jìn)行擴(kuò)展的,現(xiàn)在可以用泛型來(lái)表示。這樣可以避免強(qiáng)轉(zhuǎn)的麻煩,而且將運(yùn)行問(wèn)題轉(zhuǎn)移到的編譯時(shí)期。泛型在程序定義上的體現(xiàn):
//泛型類:將泛型定義在類上。
class Tool {
private Q obj;
public void setObject(Q obj) {
this.obj = obj;
}
public Q getObject() {
return obj;
}
}
//當(dāng)方法操作的引用數(shù)據(jù)類型不確定的時(shí)候,可以將泛型定義在方法上。
public
System.out.println("method:"+w);
}
//靜態(tài)方法上的泛型:靜態(tài)方法無(wú)法訪問(wèn)類上定義的泛型。如果靜態(tài)方法操作的引用數(shù)據(jù)類型不確定的時(shí)候,必須要將泛型定義在方法上。
public static void function(Q t) {
System.out.println("function:"+t);
}
//泛型接口.
interface Inter
void show(T t);
}
class InterImpl
public void show(R r) {
System.out.println("show:"+r);
}
泛型中的通配符:可以解決當(dāng)具體類型不確定的時(shí)候,這個(gè)通配符就是 ? ;當(dāng)操作類型時(shí),不需要使用類型的具體功能時(shí),只使用Object類中的功能。那么可以用 ? 通配符來(lái)表未知類型。
泛型限定:
上限:?extends E:可以接收E類型或者E的子類型對(duì)象。
下限:?super E:可以接收E類型或者E的父類型對(duì)象。
上限什么時(shí)候用:往集合中添加元素時(shí),既可以添加E類型對(duì)象,又可以添加E的子類型對(duì)象。為什么?因?yàn)槿〉臅r(shí)候,E類型既可以接收E類對(duì)象,又可以接收E的子類型對(duì)象。
下限什么時(shí)候用:當(dāng)從集合中獲取元素進(jìn)行操作的時(shí)候,可以用當(dāng)前元素的類型接收,也可以用當(dāng)前元素的父類型接收。
泛型的細(xì)節(jié):
1)、泛型到底代表什么類型取決于調(diào)用者傳入的類型,如果沒(méi)傳,默認(rèn)是Object類型;
2)、使用帶泛型的類創(chuàng)建對(duì)象時(shí),等式兩邊指定的泛型必須一致;
原因:編譯器檢查對(duì)象調(diào)用方法時(shí)只看變量,然而程序運(yùn)行期間調(diào)用方法時(shí)就要考慮對(duì)象具體類型了;
3)、等式兩邊可以在任意一邊使用泛型,在另一邊不使用(考慮向后兼容);
ArrayList
API--- java.lang.System: 屬性和行為都是靜態(tài)的。
long currentTimeMillis(); // 返回當(dāng)前時(shí)間毫秒值
exit(); // 退出虛擬機(jī)
Properties getProperties() ; // 獲取當(dāng)前系統(tǒng)的屬性信息
Properties prop = System.getProperties(); //獲取系統(tǒng)的屬性信息,并將這些信息存儲(chǔ)到Properties集合中。
System.setProperty("myname","畢老師"); //給系統(tǒng)屬性信息集添加具體的屬性信息
//臨時(shí)設(shè)置方式:運(yùn)行jvm時(shí),可以通過(guò)jvm的參數(shù)進(jìn)行系統(tǒng)屬性的臨時(shí)設(shè)置,可以在java命令的后面加入 –D
String name = System.getProperty("os.name");//獲取指定屬性的信息
//想要知道該系統(tǒng)是否是該軟件所支持的系統(tǒng)中的一個(gè)。
Set
hs.add("Windows XP");
hs.add("Windows 7");
if(hs.contains(name))
System.out.println("可以支持");
else
API--- java.lang.Runtime: 類中沒(méi)有構(gòu)造方法,不能創(chuàng)建對(duì)象。
但是有非靜態(tài)方法。說(shuō)明該類中應(yīng)該定義好了對(duì)象,并可以通過(guò)一個(gè)static方法獲取這個(gè)對(duì)象。用這個(gè)對(duì)象來(lái)調(diào)用非靜態(tài)方法。這個(gè)方法就是 static Runtime getRuntime();
這個(gè)Runtime其實(shí)使用單例設(shè)計(jì)模式進(jìn)行設(shè)計(jì)。
class RuntimeDemo {
public static void main(String[] args) throws Exception {
Runtime r = Runtime.getRuntime();
Process p = r.exec("notepad.exe SystemDemo.java");//運(yùn)行指定的程序
Thread.sleep(4000);
p.destroy(); //殺掉進(jìn)程
}
API--- java.util.Math: 用于數(shù)學(xué)運(yùn)算的工具類,屬性和行為都是靜態(tài)的。該類是final不允許繼承。
static double ceil(double a) ; //返回大于指定數(shù)值的最小整數(shù)
static double floor(double a) ; //返回小于指定數(shù)值的最大整數(shù)
static long round(double a) ; //四舍五入成整數(shù)
static double pow(double a, double b) ; //a的b次冪
static double random(); //返回0~1的偽隨機(jī)數(shù)
public static void main(String[] args) {
Random r = new Random();
for(int x=0; x<10; x++) {
//double d = Math.floor(Math.random()*10+1);
//int d = (int)(Math.random()*10+1);
int d = r.nextInt(10)+1;
System.out.println(d);
}
API--- java.util.Date:日期類,月份從0-11;
/*
日期對(duì)象和毫秒值之間的轉(zhuǎn)換。
1,日期對(duì)象轉(zhuǎn)成毫秒值。Date類中的getTime方法。
2,如何將獲取到的毫秒值轉(zhuǎn)成具體的日期呢?
Date類中的setTime方法。也可以通過(guò)構(gòu)造函數(shù)。
*/
//日期對(duì)象轉(zhuǎn)成毫秒值
Date d = new Date();
long time1 = d.getTime();
long time2 = System.currentTimeMillis(); / /毫秒值。
//毫秒值轉(zhuǎn)成具體的日期
long time = 1322709921312l;
Date d = new Date();
d.setTime(time);
/*
將日期字符串轉(zhuǎn)換成日期對(duì)象:使用的就是DateFormat方法中的 Date parse(String source) ;
*/
public static void method() throws Exception {
String str_time = "2011/10/25";
DateFormat df = new SimpleDateFormat("yyyy/MM/dd"); //SimpleDateFormat作為可以指定用戶自定義的格式來(lái)完成格式化。
Date d = df.parse(str_time);
}
/*
如果不需要使用特定的格式化風(fēng)格,完全可以使用DateFormat類中的靜態(tài)工廠方法獲取具體的已經(jīng)封裝好風(fēng)格的對(duì)象。getDateInstance();getDateTimeInstance();
*/
Date d = new Date();
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG);
df = DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG);
String str_time = df.format(d);
//將日期對(duì)象轉(zhuǎn)換成字符串的方式:DateFormat類中的format方法。
//創(chuàng)建日期格式對(duì)象。
DateFormat df = new SimpleDateFormat(); //該對(duì)象的建立內(nèi)部會(huì)封裝一個(gè)默認(rèn)的日期格式。11-12-1 下午1:48
//如果想要自定義日期格式的話。可使用SimpleDateFormat的構(gòu)造函數(shù)。將具體的格式作為參數(shù)傳入到構(gòu)造函數(shù)中。如何表示日期中年的部分呢?可以必須要參與格式對(duì)象文檔。
df = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
//調(diào)用DateFormat中的format方法。對(duì)已有的日期對(duì)象進(jìn)行格式化。
API--- java.util. Calendar:日歷類
public static void method(){
Calendar c = Calendar.getInstance();
System.out.println(c.get(Calendar.YEAR)+"年"+(c.get(Calendar.MONTH)+1)+"月"
+getNum(c.get(Calendar.DAY_OF_MONTH))+"日"
+"星期"+getWeek(c.get(Calendar.DAY_OF_WEEK)));
}
public static String getNum(int num){
return num>9 ? num+"" : "0"+num;
}
public static String getWeek(int index){
/*
查表法:建立數(shù)據(jù)的對(duì)應(yīng)關(guān)系.
最好:數(shù)據(jù)個(gè)數(shù)是確定的,而且有對(duì)應(yīng)關(guān)系。如果對(duì)應(yīng)關(guān)系的一方,是數(shù)字,而且可以作為角標(biāo),那么可以通過(guò)數(shù)組來(lái)作為表。
*/
String[] weeks = {"","日","一","二","三","四","五","六"};
return weeks[index];
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/73212.html
摘要:不和在同級(jí)目錄,因?yàn)槲臋n有說(shuō)明,該配置文件不需要被掃描到。添加訪問(wèn)層自定義控制器。添加電影微服務(wù)啟動(dòng)類電影微服務(wù)使用定制化在客戶端進(jìn)行負(fù)載均衡調(diào)度并為配置帳號(hào)密碼登錄認(rèn)證。注解表示該電影微服務(wù)已經(jīng)接入模塊。 SpringCloud(第 013 篇)電影微服務(wù)使用定制化 Feign 在客戶端進(jìn)行負(fù)載均衡調(diào)度并為 Feign 配置帳號(hào)密碼登錄認(rèn)證 Eureka - 一、大致介紹 1、定制 ...
摘要:?jiǎn)?dòng)使用或這兩個(gè)參數(shù)可以創(chuàng)建基本的日志,使用可以創(chuàng)建更加詳細(xì)的日志。我們可以設(shè)置日志的文件大小和數(shù)量上面設(shè)置只輸出個(gè)文件,每個(gè)文件,文件的基本名字是,使用啟動(dòng)的時(shí)間和進(jìn)程來(lái)分割日志。 構(gòu)建一個(gè) jar 包程序 使用 Spring Boot 構(gòu)建一個(gè)簡(jiǎn)單的 web 程序,可以直接使用 java -jar 來(lái)啟動(dòng)。 @RestController @RequestMapping(/root...
摘要:簡(jiǎn)介參考指南參考指南中文全文搜索引擎顧名思義,是做收索用的,因?yàn)槠胀ǖ乃阉髟跀?shù)據(jù)量小的時(shí)候,能應(yīng)對(duì)自如,但是當(dāng)數(shù)據(jù)量上千萬(wàn),或者上億的時(shí)候。 sphinx簡(jiǎn)介參考指南參考指南sphinx API中文 sphinx 全文搜索引擎:顧名思義,是做收索用的,因?yàn)槠胀ǖ乃阉髟跀?shù)據(jù)量小的時(shí)候,能應(yīng)對(duì)自如,但是當(dāng)數(shù)據(jù)量上千萬(wàn),或者上億的時(shí)候。純粹的sql搜索顯得緩慢,無(wú)力。因而為了提高用戶體驗(yàn),增...
摘要:將羅馬字母的字符串轉(zhuǎn)換為代表的整數(shù)這題不難,用一個(gè)存羅馬數(shù)字和具體數(shù)字的對(duì)應(yīng)關(guān)系,然后遍歷前后兩兩比較,該加加,該減減時(shí)間復(fù)雜度這里是自己寫的一個(gè)方法,里面用一個(gè),相當(dāng)于存對(duì)應(yīng)當(dāng)時(shí)一直想著用一個(gè)來(lái)存減的值,所以沒(méi)法用就用了指針,但其實(shí)就 Easy 013 Roman to Integer Description: 將羅馬字母的字符串轉(zhuǎn)換為代表的整數(shù)Roman numerals are ...
閱讀 2940·2023-04-26 02:22
閱讀 2295·2021-11-17 09:33
閱讀 3147·2021-09-22 16:06
閱讀 1087·2021-09-22 15:54
閱讀 3541·2019-08-29 13:44
閱讀 1923·2019-08-29 12:37
閱讀 1328·2019-08-26 14:04
閱讀 1924·2019-08-26 11:57