最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

黑馬程序員Java零基礎(chǔ)視頻教程_下部(Java入門,含斯坦福大學(xué)練習(xí)題+力扣算

2023-03-15 19:35 作者:別降下這么合適的雨a  | 我要投稿


Map加入集合也是無序的

put方法的作用添加和覆蓋

  1. 如果在添加數(shù)據(jù)的時候,鍵值不存在,則會直接添加到Map集合中,此時返回值是null。
  2. 如果鍵值存在,則直接覆蓋,但是會返回原有的鍵值的值。

remove方法不能單獨(dú)刪除value

Map集合第一種遍歷方式(健找值):

將Map集合中的key單獨(dú)拿出來,放到set集合中。利用的是keySet方法,返回值就是一個Set集合。然后再用Iterator,增強(qiáng)for或者lambda來遍歷就行。然后利用get方法獲取遍歷到的key中value的值。

Map集合第二種遍歷方式(鍵值對):

這里涉及到泛型嵌套,既泛型中再去指定泛型的泛型。

利用entrySet方法,將Map集合保存為一個Set集合,但是這次Set和的泛型指定為Map.Entry類型。

再用Iterator、增強(qiáng)for、lambda表達(dá)式遍歷,利用getKey與getValue方法分別得到鍵值對的值。


lambda表達(dá)式的底層其實是增強(qiáng)for循環(huán),


HashMap的底層原理與HashSet一樣,也是hash表的形式(數(shù)組+鏈表+紅黑樹)。

但是HashMap只比較健的hash值,只保證健的唯一

LinkedHashMap



hashMap默認(rèn)的空參構(gòu)造方法,只是加載加載因子用的

HashMap剛創(chuàng)建的時候,數(shù)組啥的是不存在的,只有當(dāng)添加元素的時候才會建立 。


觸發(fā)擴(kuò)容機(jī)制之后,會將原有的數(shù)據(jù)移動到或者復(fù)制到新的數(shù)組中

要存入的元素,先計算出hash值,再與數(shù)組長度進(jìn)行與運(yùn)算,就是當(dāng)前元素應(yīng)存入的位置,如果當(dāng)前位置沒有元素,就是數(shù)組當(dāng)前位置為null,則直接存入數(shù)組中。

當(dāng)添加的元素hash值與當(dāng)前數(shù)組中的元素相同時


當(dāng)hash值相同,并且key值也相同時,會執(zhí)行覆蓋

hash值相同,key值不同,還是回掛在鏈表的下面

...:表示可變參數(shù);底層是一個數(shù)組

且一個方法的形參中只能由一個可變參數(shù);

如果參數(shù)列表中除了可變參數(shù),還有其他類型的參數(shù)。則可變參數(shù)要寫在最后,不然方法調(diào)用時識別不出,其他類型變量的值。

Collections

addAll返回值是collection只能給單列集合批量添加

// copy方法不能直接創(chuàng)建集合進(jìn)行復(fù)制,而是先將新建的集合批量加入,并指定長度之后才能復(fù)制
// 否則會下標(biāo)越界


shift+F6:批量改名



雙列集合不能直接使用stream流,要先通過entrySet等轉(zhuǎn)為單列集合。


對stream流中數(shù)據(jù)進(jìn)行修改,只會影響流中的數(shù)據(jù),對原來集合或者數(shù)組中的數(shù)據(jù)沒有影響。

concat方法:

當(dāng)合并兩個流時,如果兩個流的數(shù)據(jù)類型不一致,則會選擇兩個流數(shù)據(jù)類型共同的父類作為流輸出。


收集器如果是Collector.toList()則,集合里面有重復(fù)數(shù)據(jù)也會保留;如果是Collector.toSet則,集合里面不會有重復(fù)的數(shù)據(jù)

如果將集合收集到map里面,需要指定鍵的規(guī)則和值的規(guī)則,而且鍵要保證不能重復(fù)。

Lambda表達(dá)式的方式書寫鍵值規(guī)則:

new Function(鍵的規(guī)則(l流當(dāng)中數(shù)據(jù)的類型,鍵的類型),值的規(guī)則(l流當(dāng)中數(shù)據(jù)的類型,值的類型))

將集合中的數(shù)據(jù)封裝到對象中,組成對象集合。

stream().map()中,map是用來進(jìn)行類型轉(zhuǎn)換的。



異常:程序中可能出現(xiàn)的問題


編譯時異常:java文件通過javac進(jìn)行編譯時出現(xiàn)的異常

作用在于提醒程序員檢查本地信息,如日期解析異常。

與運(yùn)行時異常:字節(jié)碼運(yùn)行時出現(xiàn)的異常,代碼出錯出現(xiàn)的異常


invoke:調(diào)用

異常的作用:

1.用來查詢bug的關(guān)鍵參考信息;

2.作為方法內(nèi)部的一種特殊返回值,以便通知調(diào)用者底層的執(zhí)行情況。

此時,調(diào)用者可以選擇自己在后臺進(jìn)行處理,或者打印到控制臺。

如果程序出現(xiàn)異常,那么虛擬機(jī)就會創(chuàng)建一個相應(yīng)異常的對象,如果此時使用try-catch去捕獲這個異常,則會執(zhí)行catch中的代碼。當(dāng)catch里面的代碼執(zhí)行完畢,就繼續(xù)執(zhí)行try-catch下面其他的代碼。

如果要捕獲多個異常,那么他們共同的父類也要捕獲的話,要寫在子異常的下面。

如果try中的一行代碼出了問題,那么這行代碼以下的代碼都不會執(zhí)行。直接進(jìn)行捕獲或者JVM去創(chuàng)建異常對象


System.err.println(要打印的語句);

將要打印的語句以紅色字體打印在控制臺

throws:寫在方法上

throw new:寫在方法里,并且結(jié)束方法運(yùn)行

運(yùn)行時異常用throws在方法上進(jìn)行拋出時,可以省略不寫。

拋出:方法將產(chǎn)生的異常傳給調(diào)用者。

捕獲:方法調(diào)用者將方法拋出的異常拿到。


自定義異常類,包括一個無參的構(gòu)造方法,一個有參的message提示方法

其中,如果是運(yùn)行時異常,要繼承RuntimeException

編譯時異常要繼承Exception

這樣,在catch里面捕獲就行

public class 異常類名{

public 異常類構(gòu)造方法(){

}

public 異常類構(gòu)造方法(參數(shù)列表){

}

}

IO流

程序在讀寫IO流中的數(shù)據(jù)

輸出流:程序->文件

輸入流:文件->程序



文件輸出流,就是把程序中的數(shù)據(jù)寫入到文件

步驟:

1.創(chuàng)建文件輸出流對象

既通過 FileOutputStream fos = new FileOutputStream("指定文件存放的路徑");建立程序與文件的傳輸通道。

2.寫數(shù)據(jù)

寫入數(shù)據(jù)就相當(dāng)于數(shù)據(jù)在這條通道上進(jìn)行行駛,再到終點(diǎn)。

3.釋放資源

就是將這條通道關(guān)閉。

FileOutputStream

創(chuàng)建輸出流對象,參數(shù)可以是用字符串表示的路徑,或者new一個File對象再把路徑給File對象也可以。

如果指定路徑中的文件不存在,則會創(chuàng)建新文件,但是要保證這個文件所在的文件夾存在,不像Linux一樣可以多級創(chuàng)建。

如果文件已經(jīng)存在,則會覆蓋文件內(nèi)容。


FileOutputStream底層,在創(chuàng)建對象的時候會new一個File對象和一個boolean的append參數(shù),append默認(rèn)時false(也就是默認(rèn)是覆蓋的),改為true之后就不會覆蓋,而是續(xù)寫了。

這樣再次執(zhí)行程序?qū)懭霑r,文件中的內(nèi)容就不會被覆蓋了。

FileInputStream

1.創(chuàng)建字節(jié)輸入流對象

FileInputStream fis = new FileInputStream("文件路徑");

2.讀取數(shù)據(jù)

int i = fis.read();

返回的是一個int型的變量,可以強(qiáng)轉(zhuǎn)成char

read方法更像是有個指針,一次讀一個

3.釋放資源

fis.close();





GBK字母存儲

GBK漢字的存儲

一個字節(jié)不夠,三個字節(jié)太多,所以用兩個字節(jié)就可以,可以標(biāo)識65535個漢字;為了與英文區(qū)分開。


UTF-8:可變字符長度(1-4字節(jié)),其中中文用三個字節(jié)表示;ASCII用一個字節(jié)。是unicode字符集的編碼方式

解碼時,是先將前面的固定格式去除,再去拼接為漢字就是兩個字節(jié)的二進(jìn)制位。再去查詢Unicode編碼表。

如果一開始用Unicode去編碼,然后再用GBK去解碼,此時解碼時查詢的是GBK編碼表,GBK用兩個字節(jié)表示一個漢字,而Unicode用三個字節(jié),所以讀完兩個字節(jié)之后剩下的一個字節(jié)就不讀了,所以一個漢字會出現(xiàn)讀不全的問題。


字符流

除了對象名不同,其他跟字節(jié)流差不多


FileReader fr = new FileReader("D:\\My Work National\\IJ_IDEA\\Day05\\a.txt");

int ch = 0;
while ((ch = fr.read()) != -1){
    System.out.print((char)ch);
}

fr.close();


java中的換行其實是兩個轉(zhuǎn)義字符\r\n


字符流底層原理

字符流有緩沖區(qū),字節(jié)流沒有

緩沖流

緩沖流只是一個中間態(tài)的東西,還是要關(guān)聯(lián)四大基本流來進(jìn)行操作

釋放資源的時候,緩沖流在底層會先釋放基本流資源。不需要自己關(guān)。

基本流會先讀取數(shù)據(jù),放入緩沖區(qū)當(dāng)中;

變量b會去讀緩沖區(qū)中的數(shù)據(jù),再把讀到的數(shù)據(jù)放入當(dāng),輸出流的緩沖區(qū)當(dāng)中。

newLine方法底層會去判斷使用的操作系統(tǒng)是什么樣的,然后輸出相應(yīng)的換行。

轉(zhuǎn)換流

字節(jié)流轉(zhuǎn)換為字符流

通常用于字節(jié)流轉(zhuǎn)字符流之后,用字符流里面的方法。


多線程

提高程序的運(yùn)行效率。

應(yīng)用場景:聊天軟件,拷貝、遷移大文件,加載大量資源文件,后臺服務(wù)程序。

并發(fā):同一時刻,多個指令在單個CPU上交替執(zhí)行。

并行:同一時刻,多個指令在多個CPU上同時進(jìn)行。

并發(fā)和并行

線程的啟動,new對象,用對象的引用去調(diào)用start()方法

繼承Thread父類

public class MyTread extends Thread{

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName() + "Hello World");
        }
    }
}
main方法中
/*MyTread m1 = new MyTread();
m1.setName("線程1");
m1.start();
MyTread m2 = new MyTread();
m2.setName("線程2");
m2.start();*/


實現(xiàn)Runable接口

public class MyRunable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            //Thread.currentThread.getName 獲取當(dāng)前線程的線程名
            System.out.println(Thread.currentThread().getName()+"你好!");
        }
    }
}
//main方法中
//創(chuàng)建對象
MyRunable myRunable = new MyRunable();
//創(chuàng)建線程對象
Thread t1 = new Thread(myRunable,"線程1");
t1.start();

Thread t2 = new Thread(myRunable,"線程2");
t2.start();


Callable接口如果指定泛型,則call方法的返回值就是這個泛型的返回類型。如果不指定默認(rèn)是Object類型。

public class MyCallable implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 0; i < 100; i++) {
            sum += i;
        }
       
        return sum;
    }
}


JVM虛擬機(jī)在啟動的時候,會默認(rèn)創(chuàng)建多條線程。

其中一條就是main線程,作用是調(diào)用main方法,執(zhí)行里面的代碼

關(guān)于優(yōu)先級:

不指定優(yōu)先級默認(rèn)就是5

優(yōu)先級的取值范圍:1~10,越大優(yōu)先級越高

守護(hù)線程

當(dāng)把一個線程定義為守護(hù)線程之后,當(dāng)其他非守護(hù)線程結(jié)束之后守護(hù)線程也會陸續(xù)結(jié)束,但不是立馬,因為JVM跟線程之間也有通信時間。

設(shè)置一個程序為守護(hù)進(jìn)程:

Thread t1 = new Thread(程序,設(shè)置程序名);

t1.setDaemon(true);

所謂守護(hù) 線程,是指在程序運(yùn)行的時候在后臺提供一種通用服務(wù)的線程,比如垃圾回收線程就是一個很稱職的守護(hù)者,并且這種線程并不屬于程序中不可或缺的部分。 因此,當(dāng)所有的非守護(hù)線程結(jié)束時,程序也就終止了,同時會殺死進(jìn)程中的所有守護(hù)線程。


如果其他線程的優(yōu)先級太小,會導(dǎo)致設(shè)置的守護(hù)進(jìn)程先執(zhí)行完了,而其他非守護(hù)進(jìn)程還在執(zhí)行。


線程的生命周期

線程在就緒狀態(tài),會不斷地跟其他線程搶奪執(zhí)行權(quán),當(dāng)搶奪到之后,程序進(jìn)入運(yùn)行狀態(tài),期間如果被sleep,則會進(jìn)入阻塞狀態(tài),直到sleep的時間到了,會進(jìn)入就緒繼續(xù)上面的步驟,直到run方法中的代碼執(zhí)行完。

鎖對象是唯一的,什么都行,Object的也行,但是必須是唯一的

唯一:一把鎖對應(yīng)一道門

public class PayTicket implements Runnable{
    static private int ticket = 1;

    static Object o = new Object();

    @Override
    public void run() {
        while (true){
//這個鎖一般定義為當(dāng)前類的字節(jié)碼文件。
            synchronized (PayTicket.class) {
                if (ticket <= 100) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "正在賣第" + ticket + "張票");
                } else {
                    break;
                }
                ticket++;
            }
        }
    }
}



線程同步四種方式:

  • 一、通過Object的wait和notify
  • 二、通過Condition的awiat和signal
  • 三、通過一個阻塞隊列
  • 四、通過兩個阻塞隊列


StringBuffer和StringBuilder的區(qū)別:

StringBuffer是線程安全的,因為每個方法都加了sychronized同步鎖。

如果程序是單線程的,不需要考慮數(shù)據(jù)安全性問題,則可以用StringBuilder;

如果是多線程的,需要考慮數(shù)據(jù)的安全,則可以用StringBuffer。

Lock鎖

public void run() {
    //synchronized (PayTicketWithThread.class){
        while (true) {
            lock.lock();
            if (ticket == 100) {
                break;
            } else {
                ticket++;
                System.out.println(Thread.currentThread().getName() + "正在賣第" + ticket + "張票");
            }
            //如果unlock釋放鎖加在這里,則當(dāng)ticket==100成立時,直接break跳出程序,沒有執(zhí)行釋放鎖的操作
            lock.unlock();
        }
    //}
}



public class Disk {
    /**
     *
     * 用于控制生產(chǎn)者和消費(fèi)者的執(zhí)行
     *
     *
     */

    //是否有面條;有:1;沒有:0;默認(rèn):0
    public static int foodFlag = 0;

    //面條總數(shù)
    public static int count = 10;

    //鎖對象
    public static Object lock = new Object();
}


public class Foodie extends Thread{

    @Override
    public void run() {
        //先寫循環(huán)
        while(true){
            synchronized (Disk.lock){
                if (Disk.count == 0){
                    break;
                }else {
                    //判斷是否有面條,0表示沒有則去等待
                    if (Disk.foodFlag == 0){
                        try {
                            Disk.lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }else {
                        //面條-1
                        Disk.count--;
                        System.out.println("還有"+Disk.count+"碗");
                        //吃完之后喚醒廚師
                        Disk.lock.notify();
                        //修改面條改為沒有0
                        Disk.foodFlag = 0;
                    }
                }
            }
        }
    }
}


public class Cook extends Thread{
    @Override
    public void run() {
        while (true){
            synchronized (Disk.lock){
                if (Disk.count == 0){
                    break;
                }else {
                    if (Disk.foodFlag == 1){
                        try {
                            //如果桌上有面條,則lock要等待
                            Disk.lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }else {
                        //如果沒有,則生產(chǎn)一碗面條
                        Disk.foodFlag = 1;
                        //喚醒消費(fèi)者去吃
                        Disk.lock.notify();
                    }
                }
            }
        }
    }
}


Cook c = new Cook();
Foodie f = new Foodie();

c.setName("廚師");
f.setName("吃貨");

c.start();
f.start();


線程池

將跟連wifi一樣,指定最大連接數(shù)


//獲取線程池對象

ExcutorService pool = Excutors.newCachedThreadPool(可以指定線程的數(shù)量);

//提交任務(wù)

pool.submit(new 類名);

//關(guān)閉資源

pool.shutdown



這時,cpu會創(chuàng)建臨時線程處理任務(wù)7和任務(wù)8

此時任務(wù)10會拒絕服務(wù)

主要是第一個拒絕策略。









黑馬程序員Java零基礎(chǔ)視頻教程_下部(Java入門,含斯坦福大學(xué)練習(xí)題+力扣算的評論 (共 條)

分享到微博請遵守國家法律
额尔古纳市| 南召县| 平定县| 驻马店市| 布尔津县| 建湖县| 楚雄市| 墨江| 遂溪县| 临泽县| 县级市| 买车| 锡林浩特市| 北票市| 南陵县| 古蔺县| 绥滨县| 南宁市| 滕州市| 凯里市| 秦安县| 延安市| 水城县| 全椒县| 东乌| 拜城县| 蓝田县| 九台市| 富民县| 苍南县| 永靖县| 龙口市| 余干县| 得荣县| 普陀区| 英山县| 张家港市| 蓬安县| 彩票| 东台市| 怀安县|