Java課堂隨筆(二)

第十天

權(quán)限修飾符

public? protected? default? private

同一類? true true true true

同一包 true true true false

子父類(不同包) true true flase false

不同包 true false false false

1.修飾類中的成員(方法和變量)

2.修飾類:public:任何地方都可以訪問夺荒,在其他劇中使用需要導(dǎo)包!

default:只有在同一個包中訪問!

權(quán)限修飾符:設(shè)置成員類的訪問范圍涩僻!

創(chuàng)建 Object的對象:

Object是所有類的父類

1.toString():返回對象的地址憔恳,如果想換,就重寫 父類的方法

2.equals():比較兩個對象是否是同一個對象!掩蛤,比較對象的地址哮伟!

第十一天

==:比較的是地址(引用數(shù)據(jù)類型)

equals:比較的是 字符串的值

沒有new對象

字符串保存在字符串常量池(字符串常量區(qū))干花,當(dāng)你需要給一個字符串變量賦值時候妄帘,會先到字符串常量區(qū)中查找,如果沒有就創(chuàng)建一個池凄,在將所存的地址賦值給字符串變量抡驼!如果有就不在創(chuàng)建,直接將地址給變量肿仑。

new對象

字符串也是保存在字符串常量池(常量區(qū))婶恼,當(dāng)你需要給一個字符串變量賦值的時候,先到字符串常量池中查找柏副,如果沒有就在常量池中創(chuàng)建一個 勾邦,將值賦值到堆中的對象 ,如果有就不再創(chuàng)建割择,將值賦值到堆中的對象 眷篇。

截取字符串:String str = new String("字符數(shù)組char",截取的

開始的值荔泳,截取到哪里)

int length()? 獲取字符串的長度

char charAt(int index) 獲取特定位置的字符 (注意角標(biāo)越界)

int indexOf(String str) 獲取特定字符的位置(overload)

int lastIndexOf(int ch) 獲取最后一個字符的位置

類方法運行 String.valueof(轉(zhuǎn)化)將其他的類型轉(zhuǎn)換為字符串

char[] s= 字符串.toCharArray()將字符串轉(zhuǎn)化為字符數(shù)組

s.replace("需要替換的字符"蕉饼,"替換的字符"); 替換字符串,返回的是一個新的字符串

s.split(切割的符號)? 切割字符串玛歌,返回是String數(shù)組

s.substring(截取開始的位置昧港,截取結(jié)束的位置)截取字符串

s.toUpperCase()字符轉(zhuǎn)大寫

s.toLowerCase()字符轉(zhuǎn)小寫

s.trim()去除空格!

第十二天

StringBuffer :字符串緩存區(qū):存在一個字符數(shù)組支子,默認(rèn)會有一個大写捶省:16字符,如果超了就會翻一倍值朋,類似于oc中的 可變數(shù)組

StringBuffer:具有容器的特性:

1.增加叹侄!

StringBuffer str = new StringBuffer();

str.append("字符串");

2.插入昨登!

str.insert(某一位置插入(后一位)趾代,插入的字符串);

3.刪除 !

str.delete(開始刪除的位置(包含起始)丰辣,結(jié)束刪除的位置(不包含結(jié)束))撒强;

deleteCharAt(刪除指定位置的字符串)

4.修改 !

str.replace(開始的位置,結(jié)束的位置笙什,替換的字符串)飘哨;

5.翻轉(zhuǎn)字符串!

str.reverse()得湘;

6.替換指定位置的字符杖玲!

str.setCharAt(指定的位置,替換的字符)淘正;

7.截取字符串摆马!

str.substring(開始的位置)臼闻;

str.substring(開始的位置,結(jié)束的位置)囤采;

8.查找述呐!

str.indexOf(需查找的字符串);查找小的字符串在大的字符串的位置

str.lastIndexOf(字符串)蕉毯;查找最后一個

str.lastIndexOf(字符串乓搬,指定位置);從指定位置開始查找

str.toString()將String變?yōu)镾tring

str.charAt(位置)查找指定的字符

StringBuffer 和 StringBulider 的使用方式是一樣的代虾!

相同點:1.兩個類都是字符緩沖類进肯!

2.兩個類的方法一樣

不同點:1.StringBuffer線程使用更安全,效率低棉磨;StringBulider線程不安全江掩,效率高

2.StringBuffer是jdk1.0就有了,StringBulider1.5才有乘瓤,推薦StringBulider

System的使用:

System是系統(tǒng)類环形,主要用途是用來獲取系統(tǒng)的數(shù)據(jù)? ,無參且不能被實例化衙傀,里面的方法都是靜態(tài)方法抬吟!

1.復(fù)制數(shù)組:arraycopy(需要復(fù)制的數(shù)組對象,復(fù)制的起始位置统抬,復(fù)制到的數(shù)組火本,復(fù)制到數(shù)組的起始位置(后一位!)蓄喇,指定數(shù)據(jù)的長度)发侵;

例:

int[] arr = {1,3,4,7,8,9};

int[] arr1 = new int[20];

arr1[0] =4;

arr1[1] = 5;

arr1[2] = 6;

System.arraycopy(arr,3,arr1,3,3);

2.返回以毫秒為單位的當(dāng)前時間:currentTimeMillis()妆偏;

3.終止jvm:System.exit(0);其實調(diào)用的是Runtime.exit()盅弛;方法G睢!

4.運行垃圾回收器:System.gc()挪鹏;

5.確定當(dāng)前系統(tǒng)的屬性:getProperties()见秽;

例:

Properties priperties = System.getProperties();

priperties.list(System.out)讨盒;

獲取操作系統(tǒng):以鍵:值? ? 存在

System.out.println(priperties.getProperty("os.name"));

在Java中最少有兩個線程:1.主線程 2.垃圾回收線程

Runtime:該程序代表了運行的環(huán)境解取,在程序中是單例

1.getRuntime():返回當(dāng)前程序運行的環(huán)境變量對象。

例:Runtime run = Runtime.getRuntime()返顺;

2.exec():根據(jù)指定的路徑來執(zhí)行對應(yīng)的可執(zhí)行文件禀苦!

例:Process process = run.exec(路徑)蔓肯;

3.destroy():殺掉子進(jìn)程的可執(zhí)行的文件!

例:process.destroy()振乏;

4.exit():退出jvm虛擬機蔗包!

例:run.exit();

5.freeMemory():返回虛擬機的內(nèi)存

例:System.out.println(“虛擬機內(nèi)存還剩:”+run.freeMemory());

maxMemory();試圖使用最大的內(nèi)存

totalMemory()慧邮;獲取總內(nèi)存调限!

日期類的學(xué)習(xí):jdk1.1之前是Date,jdk1.1之后使用的是Calendar類來代替Date

date:獲取系統(tǒng)當(dāng)前的時間误澳,精確到毫秒

獲取當(dāng)前時間:Date date = new Date()耻矮;

1.getDate()返回多少號,棄用

Calendar:是一個抽象的類不能直接創(chuàng)建對象的忆谓!

例:Calendar cl = Calendar.getInstance()裆装;創(chuàng)建一個日歷單例

System.out.println("年"+cl.get(Calender.YEAR));獲取年份

System.out.println("月"+(cl.get(Calender.MONTH)+1));獲取月份陪毡,十二進(jìn)制 0-11

日+ Calender.DATE 獲取日

星期+? ((Calender.DAY_OF_WEEK)-1);獲取星期米母,七進(jìn)制 0-6

時+ Calender.HOUR_OF_DAY;獲取小時

分+ Calender.MINUTE;獲取分鐘

秒+ Calendar.SECOND毡琉;獲取秒

System.out.println(cl.getTimeInMillis());返回1970到現(xiàn)在的毫秒數(shù)

SimpleDateFormat:時間的打印格式

1.將一個時間通過制定的格式以字符串形式輸出

2.將一個字符串也是以指定的格式轉(zhuǎn)為時間類型

例:

Date date = new Date()铁瞒;

指定一格式

String formate = "yyyy年MM月dd日? hh:mm:ss";

創(chuàng)建格式化對象:

SimpleDateFormate dateF = new SimpleDateFormate(formate);

String time = dateF.format(date)桅滋;

打印時間

System.out.println(time)慧耍;

定義字符串時間要與格式化格式一樣

String dateStr = “時間”;

Date newDate = dateF.parse(dateStr)丐谋;

System.out.println(newDate)芍碧;

finalize 是程序或?qū)ο笤诒籫c回收時調(diào)用此方法

第十三天

Math:數(shù)學(xué)類

Math.abs(數(shù)字):返回絕對值

Math.ceil(數(shù)字(duoble))向上取整!

Math.floor(數(shù)字(double)):向下取整

Math.round(數(shù)字):四舍五入

(int)(Math.random()*范圍):產(chǎn)生隨機數(shù)

Random random = new Random(10)号俐;產(chǎn)生0-9的隨機數(shù)

random.nextInt(10)泌豆;同上!

Array:用來存同一種數(shù)據(jù)類型的容器吏饿;

Object【】 arr:可以存放任意類型的對象踪危!

1.但比較浪費內(nèi)存,而且容量是固定的猪落,無法隨元素的變化而變化贞远!

2.存放的數(shù)據(jù)類型不統(tǒng)一

集合:用來存放對象的容器,對象類型是任意的笨忌,長度可變蓝仲!collection!

集合與數(shù)組的區(qū)別:

數(shù)組和集合類都是容器

數(shù)組長度是固定的,集合長度是可變的袱结。數(shù)組中可以存儲基本數(shù)據(jù)類型亮隙,集合只能存儲對象數(shù)組中存儲數(shù)據(jù)類型是單一的,集合中可以存儲任意類型的對象擎勘。

集合類的特點

用于存儲對象咱揍,長度是可變的,可以存儲不同類型的對象棚饵。集合中只能存對象煤裙!

集合的結(jié)構(gòu):

collection 接口 根接口 集合的公共都在接口中! 單列集合

----》List 接口 可以有重復(fù)元素的集合噪漾,有序

List特有的方法: 接口

---->ArrayList:存在一個數(shù)組(Object[]),添加硼砰、刪除元素慢,查找快

元素在內(nèi)存中是有序的欣硼!默認(rèn)的數(shù)組長度是Object[10];當(dāng)不夠時會增加為原來的1.5倍题翰,涉及到了增容和數(shù)組的拷貝所以較慢

ArrayList的特有方法:

ArrayList list = new ArrayList();

ensureCapacity(容量);手動增加容量

trimToSize()诈胜;調(diào)整容量剛好符合元素的個數(shù)

---->LinkedList:添加元素快豹障,刪除、查找慢:鏈?zhǔn)降慕Y(jié)構(gòu)=剐佟血公!

元素在內(nèi)存中是無序的,但打印是有序的

LinkedList的特有方法:

LinkedList list = new LinkedList()缓熟;

list.add(對象)累魔;

list.addFlist(對象);

list.addLast(對象)够滑;

addFlist():添加位于第一個的元素

addLast()垦写;添加位于最后一個的元素

----》Set 接口 不可以有重復(fù)元素的集合,無序

集合的目的:增刪改查更方便彰触!

例:Collection是接口 需要通過實現(xiàn)類來創(chuàng)建對象梯投,集合只能存對象

Collection? coll = new ArrayList();

增加:

1:add()將指定對象存儲到容器中况毅,add 方法的參數(shù)類型是Object便于接收任意對象

coll.add(10(對象))晚伙;添加指定的對象

2:addAll()將指定集合中的元素添加到調(diào)用該方法和集合中

Collection coll1 = new ArrayList<>();

coll1.add("李四");

coll.addAll(coll1)俭茧;將一個數(shù)組中的元素添加到另一個數(shù)組中

刪除:

3:remove()將指定的對象從集合中刪除

coll.remove("李四");從集合中刪除指定的對象

4:removeAll()將指定集合中的元素刪除

coll.removeAll(coll1);刪除指定集合中的元素

修改

5:clear()清空集合中的所有元素

coll.clear();清空集合中的所有元素!

判斷

6:isEmpty()判斷集合是否為空

coll.isEmpty()漓帚;返回boolean值母债,

7:contains()判斷集合何中是否包含指定對象

coll.contains("元素");查找指定元素返回boolean

如果比較的是自定義對象? 這時候需要重寫equals方法和hashCode方法

其實也是調(diào)用可equalse();方法

8:containsAll()判斷集合中是否包含指定集合

其實也是調(diào)用可equalse();方法

c.contatinsAll(conll)毡们;

獲取:? 9:int size()返回集合容器的大小

coll.size()迅皇;返回有多少個!

轉(zhuǎn)成數(shù)組10:toArray()集合轉(zhuǎn)換數(shù)組

Object[] o = c.toArray()衙熔;返回的是數(shù)組登颓!

11.保留集合中相同的對象 retainAll()

c.retainAll(c1);保留兩個集合中共有的對象红氯,求交集

遍歷集合元素框咙!

1.將集合變?yōu)閿?shù)組

Object[] o = c.toArray(可以指定對象開始變數(shù)組);

for(int i=0痢甘;i

System.out.println(o[i])喇嘱;

}

List特有的方法:List中特有的方法都是通過下標(biāo)來操作的!

---->ArrayList

---->LinkList

List list = new List<>();

插入

1.add(對象,指定位置)塞栅;

addAll(指定位置者铜,集合); 插入集合

list.add("張三");

list.add(0,"李四");

集合1.addAll(指定位置放椰,集合2)作烟;

返回、獲取

2.get(指定位置)

System.out.println(list.get(位置));

打印集合中的對象

查找

3.IndexOf()砾医;查找指定的對象在集合中第一個出現(xiàn)的位置:返回位置

System.out.println("是否存在對象:在什么位置:"+list.indexOf("對象"));

4.lastIndexOf()拿撩;查找指定的對象在集合中最后一次出現(xiàn)的位置:返回位置

System.out.println("是否存在對象:在什么位置:"+list.lastIndexOf("對象"));

5.listIterator();迭代器:用于操作集合中的元素藻烤,增刪绷雏,獲取集合中的對象!

使用的注意事項:

1.當(dāng)用迭代器來操作集合元素時怖亭,不要集合來操作元素涎显!java.util.ConcurrentModificationException:不允許在用迭代器時用集合

2.

Iterator:迭代器的超級接口:所有的迭代器都繼承于Iterator

迭代器默認(rèn)指向第一個元素(指針);當(dāng)調(diào)用next()方法后指針就會下移一位兴猩,不再指向第一個期吓!

迭代器中常用的方法:

例:Collection c = new ArrayList<>();

c.add("狗娃");..... 添加元素

Iterator it = c.iterator();

1.hasNext()倾芝;判斷當(dāng)前指針是否存在元素讨勤,返回boolean

System.out.println("當(dāng)前指針是否存在元素?"+it.hasNext())晨另;

2.next()潭千;獲取當(dāng)前指針指向的元素,當(dāng)被調(diào)用是就會下移

while(it.hasNext()){

System.out.println(it.next());

}

3.remove()借尿;移除最后一次操作的元素

it.remove()

ListItreaor:特有的方法

例:List list = new List()刨晴;

list.add(“”)屉来;.....

1.獲取迭代器對象

ListIterator it = list.listIterator();

2.hasPrevious()狈癞;判斷當(dāng)前指針上一個是否存在元素

it.hasPrevious()茄靠;獲取當(dāng)前指針指向的上一個元素,返回boolean

3.previous()蝶桶;獲取上一個值慨绳,指針有上移了一位

it.previous();

倒序遍歷集合中的元素

1.首先需要指針移動到最后一個元素的下方

while(it.hasNext()){

it.next();

}

while(it.hasPrevious()){

System.out.println(it.prevopis())真竖;

}

4.previousIndex()脐雪;返回上一個指針的索引值

System.out.println(it.previousIndex());

5.add()疼邀;通過迭代器的指針的位置來添加元素喂江,添加到當(dāng)前的指針

it.add(“對象”);

6.set()旁振;替換元素

it.set(對象)获询;,替換當(dāng)前指針指向的元素拐袜,最好不要與add()一起用吉嚣,當(dāng)用時需要it.next(),否則指針會不知道指哪里

更新

6.set(指定位置蹬铺,替換的對象)尝哆;更換指定位置的對象

list.set(位置,對象)甜攀;

刪除

7.remove(指定位置)秋泄;刪除指定索引位置!

list.remove(list.size()-1)规阀;

8.List.subList(開始恒序,結(jié)束);截取集合的某一段谁撼,生成一個新的集合

List.subList(開始歧胁,結(jié)束)將指定的位置保留為另外一個集合。

List newList = list.subList(開始的位置,結(jié)束的位置)厉碟;

遍歷集合

for(int i = 0喊巍;i

System.out.println(list.get(i));

}

第十四天

當(dāng)想讓對象打印成員變量時可復(fù)寫toString()方法!

1.LinkedList:

LinkedList list = new LinkedList()箍鼓;

list.add()崭参;.....

list.addFirst(“對象”);添加第一個

list.addLast()款咖;添加最后一個

list.getFirst()阵翎;輸入第一個逢并;

list.getLast();輸出最后一個

list.removeLast()郭卫;刪除最后一個,返回 最后一個元素

list.removerFirst()背稼;刪除第一個贰军,返回 最后一個元素

當(dāng)集合中沒有元素時會拋出java.util.NosuchElementException這個異常

2.數(shù)據(jù)節(jié)構(gòu)

1.棧:先進(jìn)后出

push();當(dāng)被推入時會被推入到第一的位置蟹肘!在棧中

list.push(對象)词疼;往集合中的堆棧中推入一個對象

pop();當(dāng)推出時會移除最上一位的對象帘腹!在棧中

當(dāng)push()的被去除完后就會變成ArrayList的順序來----》小的先走贰盗,大的后走

list.pop();在集合中的堆棧中推出一個對象

2.隊列:先進(jìn)先出

offer()阳欲;按順序推入到集合中

list.offer()舵盈;添加到最后一個!

poll()球化;推出ArrayList的第一個

list.poll()秽晚;推出第一個

3.獲取逆序的迭代器:descendingIterator

Iterator it = list.descendingIerator();返回的迭代器時逆序的狀態(tài)!

while(it.hasNext()){

System.out.println(it.next())筒愚;

}

Vector: 描述的是一個線程安全的ArrayList 使用跟ArrayList一樣

Vector與ArrayList的區(qū)別:

相同點:底層都是使用Object[]數(shù)組來實現(xiàn)

不同點:1.ArrayList是線程不同步赴蝇,操作效率高!

Vector是線程同步的巢掺,操作效率低

2.ArrayList是在jdk1.2出現(xiàn)的句伶,Vector是在jdk1.0出現(xiàn)的!

Set集合:也是接口陆淀,繼承與Collection接口

特點:無序的元素不能重復(fù)

---->HashSet():

存值原理:存在于哈希表中考余,會通過調(diào)用對象的hashCode(先)和equals(后)方法獲取哈希值,然后用移位的運算倔约,獲取哈希表的位置值秃殉!

情況一:如果我計算的位置上沒有任何元素,將對象放在位置上

情況二:如果計算的位置上已經(jīng)存在對象浸剩,這時候就會將要存的對象與已存在的對象作比較钾军,如果equals返回的是true :對象就是重復(fù)元素,如果是false就在原來的位置上添加绢要!

哈希表中是以桶式的結(jié)構(gòu)來存放數(shù)據(jù)吏恭,一格可存放多個對象!

例:復(fù)寫HashCode(){

如果是string就返回this.成員變量.hashCode()值(成員變量V刈铩)

int就返回this.成員變量

return 自定義的哈希樱哼;

}

復(fù)寫equals(){

如果是string就返回(this.對比值).equals(obj.成員變量)

int就返回this.成員變量==obj.成員變量

return 自定義的值是否相等

}

例:

Set set = new HashSet()哀九;

set.add(對象)掠拳;.....當(dāng)添加的元素重復(fù)時無法進(jìn)行添加铃慷!返回Boolean值

打印的是無序的!躬存!

遍歷Hashset()集合

1.集合變?yōu)閿?shù)組遍歷

2.迭代器遍歷(無序:添加的順序和打印出來的順序是不一樣的)

---->TreeSet()茄唐;使用元素的自然順序?qū)υ剡M(jìn)行排序.底層使用二叉樹實現(xiàn)

注意點:存進(jìn)去的對象需要具備自然排序的特性息裸,取第一個字符根據(jù)阿斯特碼(ASCII)來排!

1.往TreeSet添加對象的時候沪编,如果對象有自然排序的特性呼盆,就按照這個自然排序進(jìn)行排序!

2.往TreeSet添加對象時蚁廓,如果對象本身不具備自然排序的特性访圃,運行直接報錯,如果要儲存對象相嵌,那么對象的類必須要實現(xiàn)一個Comparable ? 接口的compareTo方法腿时!

public int compareTo(Object o){

Book b =(Book)o;

return this.對比成員-b.對比的成員;

}

3.往TreeSet添加對象時平绩,如果對象本身不具備自然排序的特性圈匆,并且沒有實現(xiàn)Comparable? 接口,那么這個時候就需要創(chuàng)建一個TreeSet類的時候傳入一個比較器捏雌。

比較器的定義方式

TreeSet set = new TreeSet(new sunComp(創(chuàng)建比較器))跃赚;在main或別的類的時候

比較的類(比較器也是一個類)必須與Compartor相接

class sunComp(類名)implements Compartor{

復(fù)寫此方法!

public int compare (Object o1,Object o2){

o1,o2集合中的對象:book

Book b1= (Book)o1;

Book b2 = (Book)o2;

return? b1.對比的值-b2.對比的值性湿;

}

}

4.如果類中實現(xiàn)了Comparable的接口纬傲,又創(chuàng)建TreeSet時傳入了一個比較器,這時候以比較器為標(biāo)準(zhǔn)

例:

TreeSet set = new TreeSet()肤频;

set.add("對象")叹括;

會自動的將對象排序!

字符串的比較規(guī)則:

1.獲取字符串的第一個值進(jìn)行比較宵荒,通過自然排序比較汁雷,如果都是一樣的就比較下一個值還是一樣的就再比較下一個,直到無法再比較

2.這個時候就會比較字符串的長度报咳!

第十五天

二叉樹:紅黑樹規(guī)則:左小右大侠讯!

泛型:確定集合中只能存放某一種數(shù)據(jù)類型的對象,jdk1.5之后推出的

優(yōu)點:1.將運行時的錯誤提前到編譯時暑刃。2.避免了無謂的強制轉(zhuǎn)換厢漩!

如果傳進(jìn)去的是基本數(shù)據(jù)類型,接收時應(yīng)用改用它的包裝類來接收岩臣!

int--->Integer;

short--->Short;

double--->Double;

float--->Float;

byte--->Btey;

boolean--->Boolean;

long--->Long;

char--->Charactor

ArrayList<這個就是泛型> = new ArrayList<這個也是>();

自定義泛型方法:就是一個數(shù)據(jù)類型的 占位或一個數(shù)據(jù)類型變量溜嗜,一般用T(Typt)或E(Element)來做占位符,占位符可以隨意寫宵膨,必須要滿足遵守標(biāo)識符的命名規(guī)范!

注意:1.泛型方法中自定義一個泛型數(shù)據(jù)類型實在實際參數(shù)傳遞時被確定的

2.泛型所用標(biāo)識符需要符合標(biāo)識符的命名規(guī)范炸宵!一般用大寫辟躏!

格式:public static T 方法名(T s){

return s;

}

接收:String s = 方法名("傳進(jìn)去的對象");

定義一個泛型類:

定義格式:

class 類名<聲明自定義的泛型>{}

泛型類的使用注意點:

1.泛型類定義的自定義泛型的類型是在創(chuàng)建泛型類對象時確定的!

2.如果一個自定義泛型類在創(chuàng)建時候沒有指定類型焙压,默認(rèn)為Object類型鸿脓!

3.靜態(tài)方法是不能夠使用自定義類的泛型,只能在靜態(tài)方法中再次寫一個泛型涯曲!

泛型接口的定義方式

interface 接口名<聲明自定義的泛型>{}

class 類名 implements 接口名<指定類型>{}

泛型接口注意點:

1.接口上自定義的泛型是在實現(xiàn)接口時被指定的!

2.如果接口上沒有指定接口在塔,默認(rèn)為Object類型幻件!

3.如果需要創(chuàng)建接口實現(xiàn)類對象是指定數(shù)據(jù)類型,

那么需要格式:class 類名 <聲明自定義泛型> implements? 接口<聲明自定義泛型>{}

Java可以后臺數(shù)據(jù)管理也可以前端;桌!绰沥!

Map:集合? 接口? 雙列集合? K:V? 鍵值對? OC中的字典很象!

特點:存儲數(shù)據(jù)是以鍵和值的方式贺待,鍵不允許重復(fù)徽曲,值是允許重復(fù)的!

----->HashMap:基于哈希表麸塞,而且是無序的秃臣!

使用注意點:

1.鍵可以是任意的對象!哪工,值也可以是任意的對象奥此!

2.Map集合中也可以存集合(嵌套集合)(List、Map)雁比;

3.當(dāng)鍵相同時后面的Value會覆蓋前面的Value

儲存原理:也是使用哈希表來存放稚虎!

往HashMap添加元素,首先會調(diào)用鍵的HashCode()方法? 獲得一個哈希值偎捎,然后經(jīng)過運算獲取一個位置:情況有:

1.如果位置沒有元素蠢终,就直接將元素存放在該位置

2.如果位置上有元素,就會調(diào)用元素的equals()方法與這個位置上的元素做比較茴她,如果返回是true那么就被視為相同的鍵 就不存了寻拂;false就是不同的鍵 就存該元素

----->TreeMap:二叉樹的結(jié)構(gòu)儲存。特點:以鍵來做自然排序的特性败京!

使用注意點:

1.往TreeMap添加的元素時兜喻,如果元素的鍵具備自然排序,那么就會通過自然排序?qū)υ剡M(jìn)行排序赡麦!

2.如果不具備自然排序特性朴皆,鍵所屬的類必須實現(xiàn)Comparable 接口帕识,把鍵的比較規(guī)則定義在compareTo()方法中!

3.如果不具備自然排序特性遂铡,也沒有實現(xiàn)Comparable接口肮疗,創(chuàng)建TreeMap的時候給其一個比較器

結(jié)構(gòu):

class 類名 implements Compartor 接口{

如果返回的是負(fù)數(shù)就是在后面

是1就是在前面

0就是不添加!

}

鍵的比較規(guī)則定義在compare方法扒接!

----->HashTable:HashMap一樣的使用伪货,線程安全,訪問比較慢(了解<卣)

Map常用方法:

Map map = new HashMap()碱呼;

添加:

put(K,V)宗侦;

map.put(鍵(可存對象)愚臀,值(可存對象));

putAll(K矾利,V(集合))姑裂;A.putAll(B);將B中的元素添加到A中

Map map2 = new HashMap();

map.putAll(map2)男旗;

刪除:

clear()舶斧;

map.clear();清空Map集合中所以的元素察皇!

remove()茴厉;

map.remove(鍵);通過鍵刪除指定的元素让网!

獲妊接恰:

get(鍵);

map.get(鍵)溃睹;通過鍵來獲取值而账!

size();

map.size()因篇;返回map集合里面的元素個數(shù)泞辐!

獲取鍵的方法

判斷:

isEmpty();判斷集合是否為空竞滓!

map.isEmpty()咐吼;判斷集合中是否為空!false是不為空商佑!

containsKey(K)锯茄;

map.containsKey(鍵);判斷是否存在某一個鍵!有返回true

containsValue(V)肌幽;

map.containsValue(值)晚碾;判斷是否含有某一個值!需要復(fù)寫equals()和HashCode()方法喂急!

Map的遍歷方式:

迭代器遍歷:

entrySet()格嘁;

KeySet();

values()廊移;

例:

1.定義Map

Map map = new HashMap();

2.添加元素

map.put("范冰冰","李晨");

3.遍歷

map遍歷元素方式一:keySet()糕簿;獲取所有的鍵用Set集合來保存!

特點:通過遍歷鍵狡孔,通過鍵來取值

Set set = map.keySet();

Iterator it = set.iterator();

while(it.hashNext()){

String key = it.next();

System.out.println("鍵"+key+“:值”+map.get(key))懂诗;

}

map遍歷元素方式二:values():獲取map集合中所有的值,用Collection集合保存

Collection coll = map.values();

Iterator it = coll.iterator();

while(it.hashNext()){

String value = it.next();

System.out.println(“值:”+value)苗膝;

}

map遍歷元素方式三:entrySet()

Set> entry = map.entrySet();

Iterator> it = entry.iterator();

while(it.hashNext()){

Map.Entry entry = it.next();

Map.Entry:接口:提供給用戶操作map集合

getKey()响禽;獲取鍵

getValue();獲取值

setValue()荚醒;更改值

System.out.println("鍵:"+entry.getKey()+"值:"+entry.getValue());

}

Collection:接口

Collections:集合的工具類

Collection與Collections的區(qū)別隆嗅?

Collection 是一個單列集合的根接口界阁,Collections是操作集合的工具類!只能操作list集合 胖喳!

Collections中常有的方法

Collections:常見方法:

Collections.sort()泡躯;排序

1, 對list進(jìn)行二分查找:

前提該集合一定要有序丽焊。

int binarySearch(list,key)较剃;

Collections.binarySearch(集合,"對象");返回索引的位置? 沒找到返回是一個負(fù)數(shù)技健,索引

//必須根據(jù)元素自然順序?qū)α斜磉M(jìn)行升級排序

//要求list 集合中的元素都是Comparable 的子類写穴。

int binarySearch(list,key,Comparator);

2,對list集合進(jìn)行排序雌贱。

sort(list);

//對list進(jìn)行排序,其實使用的事list容器中的對象的compareTo方法

sort(list,comaprator);

//按照指定比較器進(jìn)行排序

3啊送,對集合取最大值或者最小值。

max(Collection)

max(Collection,comparator)

min(Collection)

min(Collection,comparator)

4欣孤,對list集合進(jìn)行反轉(zhuǎn)馋没。

reverse(list);

5,對比較方式進(jìn)行強行逆轉(zhuǎn)降传。

Comparator reverseOrder();

Comparator reverseOrder(Comparator);

6篷朵,對list集合中的元素進(jìn)行位置的置換。

swap(list,x,y);

7,對list集合進(jìn)行元素的替換声旺。如果被替換的元素不存在笔链,那么原集合不變。

replaceAll(list,old,new);

8艾少,可以將不同步的集合變成同步的集合卡乾。

Set synchronizedSet(Set s)

Map synchronizedMap(Map m)

List synchronizedList(List list)

9.如果想要將集合變數(shù)組:

可以使用Collection 中的toArray 方法。注意:是Collection不是Collections工具類

傳入指定的類型數(shù)組即可缚够,該數(shù)組的長度最好為集合的size幔妨。

第十六天

進(jìn)程:就是正在運行的程序,作用是分配內(nèi)存讓應(yīng)用程序能夠運行谍椅!

windows系統(tǒng)號稱多任務(wù)(可以同時運行多個應(yīng)用程序)误堡。

宏觀上:windows確實是運行的多個程序

微觀上:CPU快速作了切換操作,肉眼不可察

線程:線程在一個進(jìn)程中負(fù)責(zé)代碼的執(zhí)行雏吭!就是一個進(jìn)程的執(zhí)行路徑锁施!

Java程序在運行的時候,jvm會幫我們創(chuàng)建一個主線程和一個垃圾回收器(也是一個線程)杖们。主線程主要負(fù)責(zé)main方法中的代碼執(zhí)行悉抵。垃圾回收器負(fù)責(zé)垃圾回收!main是主線程摘完!

一個Java程序中至少有兩個線程姥饰。

多線程:在一個進(jìn)程中有多個線程存在并且線程“同時”執(zhí)行不同的任務(wù)⌒⒅危“同時”:單核CPU快速切換多個線程執(zhí)行任務(wù)列粪,速度很快,肉眼不可察

好處:1.可以解決一個進(jìn)程中同時執(zhí)行多個任務(wù)的問題

2.可以提高資源的利用率

壞處:1.增加CPU的負(fù)擔(dān)谈飒!不是線程越多越好

2.降低進(jìn)程中線程的執(zhí)行效率岂座。

3.會引發(fā)線程安全問題

4.容易出現(xiàn)死鎖

Java創(chuàng)建線程:

方式一:Thread(線程類)

1.需要定義一個類來繼承Thread類

2.重寫Thread類中的run方法!把自定義線程的任務(wù)代碼寫在run方法中杭措。每一個線程都有自己的任務(wù)代碼费什,jvm創(chuàng)建主線程的任務(wù)代碼就是main,自定義想成的任務(wù)代碼就寫在run方法中瓤介!

class 類名 extends Thread{

public void run(){

//自定義線程的任務(wù)代碼

for(int i=0吕喘;i<100;i++){

System.out.println(“多線程”+i);

}

}

}

3.創(chuàng)建Thread的子類,并且調(diào)用start開啟線程刑桑!

在main中開啟線程氯质,

注:1.在main中代碼的執(zhí)行是從上到下,必須放在執(zhí)行main的上面

2.一旦線程開啟祠斧,就會默認(rèn)執(zhí)行線程對象的run方法闻察,但是直接千萬不要調(diào)用,如果直接調(diào)用run方法就跟普通方法沒有區(qū)別!

類名 名字 = new 類名()辕漂;

名字.start()呢灶;

for(int i=0;i<100;i++){

System.out.println(“主線程”+i)钉嘹;

}

方式二:推薦!由于Java是單繼承鸯乃,所以就不能繼承Thread和該繼承的類,但接口可以有多個跋涣!

1.自定義一個類實現(xiàn)Runable接口缨睡,接口就會提供一個run方法!

2.實現(xiàn)Runable接口中的run方法陈辱。將線程中的任務(wù)寫在run方法中

3.實現(xiàn)Runable接口的實現(xiàn)類對象奖年!

4.創(chuàng)建一個Thread對象

5.調(diào)用Thread的對象的start方法!

class 類名 implements Runnable{

public void run(){

}

}

main函數(shù):

類名 對象名 = new 類名()沛贪;-----》不是線程對象陋守!只有是Thread或者是Thread的子類才是線程對象!

Thread thread = new Thread(對象名)利赋;

thread.start()水评;

為什么要將Runable接口實現(xiàn)類的對象作為參數(shù)傳遞?

讓對象中的run方法能夠在線程中的run方法中執(zhí)行媚送!

線程的生命周期:-

---->CPU的等待資格

---->CPU的執(zhí)行權(quán)

1.創(chuàng)建一個線程:new 子線程類

2.等待運行狀態(tài)之碗,改狀態(tài)只有CPU的等待資格:

3.運行狀態(tài),改狀態(tài)具備了CPU的執(zhí)行權(quán)與CPU的等待資格

4.線程結(jié)束季希,

線程的阻塞狀態(tài):可由運行狀態(tài)轉(zhuǎn)化,一個線程執(zhí)行了sleep或者wait方法幽纷,線程會處于阻塞狀態(tài)式塌!如果是sleep方法,如果超過了睡眠時間線程會立馬進(jìn)入等待運行狀態(tài)友浸!如果是wait峰尝,就需要通過其他的線程來喚醒!

線程中常用的方法:

1.Thread(String name)初始化線程名字

main 函數(shù)中

類名 對象名 = new 類名(“線程名”)收恢;

對象名.setName(“更換線程名”)武学;

Thread maint = Thread.currentThread();CPU當(dāng)前執(zhí)行的線程

System.out.println("獲取線程的優(yōu)先級"+maint.getPriority())伦意;

定義一個構(gòu)造方法來調(diào)用父類的構(gòu)造方法

public 類名(String name){

super(name)火窒;

}

類中重寫run方法

public void run(){

執(zhí)行的代碼!睡眠后打印線程名驮肉!

try{異常只能處理:Thread父類的sleep方法沒有拋出異常所以子類也不允許拋

this.sleep(毫秒)熏矿;或Thread.sleep(“毫秒”);可以拋異常

}catch(異常){

。。票编。褪储。

}

System.out.println(“線程名”+this.getName());

}

2.getName()返回線程的名字

3.setName(String name)設(shè)置線程對象名

4.sleep(毫秒)線程睡眠是靜態(tài)的可以通過類方法調(diào)用!誰執(zhí)行的Thread.sleep就睡眠誰

5.getPriority()返回線程對象的優(yōu)先級默認(rèn)是5慧域,最高是10

6.Thread.currentThread()鲤竹;

CPU當(dāng)前執(zhí)行的線程,指的是正在執(zhí)行的run方法的線程對象

this不是線程對象昔榴!

7.setPriority(10);給該對象設(shè)置線程的優(yōu)先級

線程安全問題:

Java的線程鎖:

方式一:同步代碼塊P猎濉!推薦

Java中的任意一個對象都會有一個對象的狀態(tài)论泛,就可以通過對象的狀態(tài)作為鎖的標(biāo)識符

優(yōu)點:1.同步代碼塊的鎖對象可以由自己指定揩尸,同步函數(shù)是固定的的

2.同步代碼塊可以控制被同步的范圍,同步函數(shù)必須是整個函數(shù)屁奏!

注意:1.任意對象都可以做鎖對象

2.如果在同步代碼塊中調(diào)用sleep方法岩榆,鎖對象不會被釋放!

3.只有真正存在線程安全的時候才會需要使用同步代碼塊坟瓢,否則會降低效率

4.多線程操作鎖對象必須是唯一的勇边,否則無效

static Object? o = new Object(); 鎖的對象應(yīng)該是同一個對象static 或 單例

synchronized(鎖對象 o){鎖對象可以使任意Java中的對象折联,也可以是字符串

代碼A0!诚镰!

}

方式二:同步函數(shù)奕坟,用關(guān)鍵字sybnchronized修飾函數(shù)

同步函數(shù)是否有鎖對象:有!

同步函數(shù)使用注意點:

1.如果是一個非靜態(tài)的函數(shù)清笨,同步函數(shù)的鎖就是調(diào)用方法的對象(this對象)月杉,如果是一個靜態(tài)函數(shù)同步函數(shù)的鎖對象是當(dāng)前函數(shù)所屬類的字節(jié)碼文件(Class對象)!

2.同步函數(shù)的鎖對象固定抠艾,不能夠自己來指定

3.同步函數(shù)是同步整個函數(shù)的代碼塊苛萎!

線程什么時候安全什么時候不安全?

出現(xiàn)線程安全的根本原因:

1.存在兩個或兩個以上的線程检号,并且線程之間共享著一個資源

2.多個語句同時操作的共享資源腌歉!

代碼同步是可以解決線程安全問題!如果使用不當(dāng)會導(dǎo)致線程的死鎖齐苛!

A線程等B線程 翘盖,B線程又在等A線程 結(jié)果兩個人就一直等下去,這時候就造成了線程的死鎖

線程死鎖不一定會出現(xiàn)凹蜂,有可能出現(xiàn)最仑!

死鎖的解決方法:盡量避免出現(xiàn)線程之間的等待問題藐俺!

public void run() {

if("張三".equals(Thread.currentThread().getName())){

synchronized ("遙控器") { //鎖對象就鎖住了

System.out.println("張三拿到了遙控器 ,準(zhǔn)備去拿電池");

synchronized ("電池") {//已經(jīng)被鎖住了

System.out.println("張三拿到了遙控器和電池泥彤,開著空調(diào)欲芹,在也 不冷了");

}

}

}else if("老王".equals(Thread.currentThread().getName())){

synchronized ("電池") { //鎖也被鎖住了? 電池對象的狀態(tài) 變?yōu)殒i住的狀態(tài)

System.out.println("老王拿到電池吟吝,準(zhǔn)備去拿遙控器");

synchronized ("遙控器") { //遙控器也被鎖住了

System.out.println("老王拿到了遙控器和電池菱父,開著空調(diào),在也 不冷了");

}

}

}

}

線程的通訊:一個線程完成自己的任務(wù)剑逃,去通知另外一個線程去完成另外一個任務(wù)浙宜!

wait();等待如果線程執(zhí)行了wait()方法蛹磺,那么該線程就會處于等待狀態(tài)粟瞬,等待狀態(tài)的線程必須通過其他線程來調(diào)用notify()方法來喚醒!通過鎖對象來調(diào)用

try{

鎖對象.wait()萤捆;

}catch(){

}

notify()裙品;喚醒? 隨機喚醒一個

鎖對象.notify();

notifyAll()俗或;喚醒全部線程

生產(chǎn)者和消費者

注意:1.wait和notify都是屬于Object對象的

2.wait方法和notify方法必須在同步線程中使用

3.wait方法和notify方法必須由鎖對象來調(diào)用市怎!

線程的停止:

1.停止一個線程 一般通過一個變量來控制

2.如果需要停止一個處于等待狀態(tài)的線程,應(yīng)配合interrupt方法辛慰!

Thread.currentThread().stop()区匠;停止當(dāng)前前程!已過時帅腌!此方法不安全

對象.interrupt()驰弄;直接調(diào)用interrupt是沒有用的

如何創(chuàng)建后臺(守護(hù))線程:在一個進(jìn)程中只剩下后臺(守護(hù))線程,守護(hù)線程也會死掉速客!

線程默認(rèn)的不是后臺線程揩懒!將某個對象的線程標(biāo)記為守護(hù)線程

對象.setDaemon(布爾值);true是守護(hù) false一般線程

join方法 加入:可以在一個線程中挽封,加入另外一個線程執(zhí)行,前面的線程會等待加入的線程執(zhí)行完畢后在執(zhí)行臣镣!

run方法中加入另外一個線程

類名 對象名 = new 類名()辅愿;

對象.start();

try{如果有一個線程執(zhí)行join語句忆某,有一個新的線程加入点待,在執(zhí)行的線程需要讓步新的線程執(zhí)行完畢,然后才能執(zhí)行

對象.joun()弃舒;

}catch(){

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末癞埠,一起剝皮案震驚了整個濱河市状原,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌苗踪,老刑警劉巖颠区,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異通铲,居然都是意外死亡毕莱,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進(jìn)店門颅夺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來朋截,“玉大人,你說我怎么就攤上這事吧黄〔糠” “怎么了?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵拗慨,是天一觀的道長廓八。 經(jīng)常有香客問我,道長胆描,這世上最難降的妖魔是什么瘫想? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮昌讲,結(jié)果婚禮上国夜,老公的妹妹穿的比我還像新娘。我一直安慰自己短绸,他們只是感情好车吹,可當(dāng)我...
    茶點故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著醋闭,像睡著了一般窄驹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上证逻,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天乐埠,我揣著相機與錄音,去河邊找鬼囚企。 笑死丈咐,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的龙宏。 我是一名探鬼主播棵逊,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼银酗!你這毒婦竟也來了辆影?” 一聲冷哼從身側(cè)響起徒像,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蛙讥,沒想到半個月后锯蛀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡键菱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年谬墙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片经备。...
    茶點故事閱讀 37,989評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡拭抬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出侵蒙,到底是詐尸還是另有隱情造虎,我是刑警寧澤,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布纷闺,位于F島的核電站算凿,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏犁功。R本人自食惡果不足惜氓轰,卻給世界環(huán)境...
    茶點故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望浸卦。 院中可真熱鬧署鸡,春花似錦、人聲如沸限嫌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽怒医。三九已至炉抒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間稚叹,已是汗流浹背焰薄。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留扒袖,地道東北人塞茅。 一個月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像僚稿,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蟀伸,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,700評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法蚀同,類相關(guān)的語法缅刽,內(nèi)部類的語法,繼承相關(guān)的語法蠢络,異常的語法衰猛,線程的語...
    子非魚_t_閱讀 31,581評論 18 399
  • //Clojure入門教程: Clojure – Functional Programming for the J...
    葡萄喃喃囈語閱讀 3,616評論 0 7
  • (一)Java部分 1、列舉出JAVA中6個比較常用的包【天威誠信面試題】 【參考答案】 java.lang;ja...
    獨云閱讀 7,071評論 0 62
  • java筆記第一天 == 和 equals ==比較的比較的是兩個變量的值是否相等刹孔,對于引用型變量表示的是兩個變量...
    jmychou閱讀 1,485評論 0 3
  • 早上聽了一集俗世奇才啡省,感覺俗世中真是奇才不少,同時也覺得這天下也沒有什么新鮮之事髓霞。 事情是這樣的卦睹。天津某地方來了一...
    木子峯閱讀 316評論 0 0