最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中實現(xiàn)代碼優(yōu)化的技巧分享

 更新時間:2022年08月19日 11:19:31   作者:葉秋學(xué)長  
這篇文章主要跟大家談?wù)剝?yōu)化這個話題,那么我們一起聊聊Java中如何實現(xiàn)代碼優(yōu)化這個問題,小編這里有幾個實用的小技巧分享給大家,需要的可以參考一下

1.用String.format拼接字符串

不知道你有沒有拼接過字符串,特別是那種有多個參數(shù),字符串比較長的情況。

比如現(xiàn)在有個需求:要用get請求調(diào)用第三方接口,url后需要拼接多個參數(shù)。

以前我們的請求地址是這樣拼接的:

String url = "http://susan.sc.cn?userName="+userName+"&age="+age+"&address="+address+"&sex="+sex+"&roledId="+roleId;

字符串使用+號拼接,非常容易出錯。

后面優(yōu)化了一下,改為使用StringBuilder拼接字符串:

StringBuilder urlBuilder = new StringBuilder("http://susan.sc.cn?");
urlBuilder.append("userName=")
.append(userName)
.append("&age=")
.append(age)
.append("&address=")
.append(address)
.append("&sex=")
.append(sex)
.append("&roledId=")
.append(roledId);

代碼優(yōu)化之后,稍微直觀點。

但還是看起來比較別扭。

這時可以使用String.format方法優(yōu)化:

String requestUrl = "http://susan.sc.cn?userName=%s&age=%s&address=%s&sex=%s&roledId=%s";
String url = String.format(requestUrl,userName,age,address,sex,roledId);

代碼的可讀性,一下子提升了很多。

我們平??梢允褂肧tring.format方法拼接url請求參數(shù),日志打印等字符串。

但不建議在for循環(huán)中用它拼接字符串,因為它的執(zhí)行效率,比使用+號拼接字符串,或者使用StringBuilder拼接字符串都要慢一些。

2.創(chuàng)建可緩沖的IO流

IO流想必大家都使用得比較多,我們經(jīng)常需要把數(shù)據(jù)寫入某個文件,或者從某個文件中讀取數(shù)據(jù)到內(nèi)存中,甚至還有可能把文件a,從目錄b,復(fù)制到目錄c下等。

JDK給我們提供了非常豐富的API,可以去操作IO流。

例如:

public class IoTest1 {
    public static void main(String[] args) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            File srcFile = new File("/Users/dv_susan/Documents/workspace/jump/src/main/java/com/sue/jump/service/test1/1.txt");
            File destFile = new File("/Users/dv_susan/Documents/workspace/jump/src/main/java/com/sue/jump/service/test1/2.txt");
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(destFile);
            int len;
            while ((len = fis.read()) != -1) {
                fos.write(len);
            }
            fos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

這個例子主要的功能,是將1.txt文件中的內(nèi)容復(fù)制到2.txt文件中。這例子使用普通的IO流從功能的角度來說,也能滿足需求,但性能卻不太好。

因為這個例子中,從1.txt文件中讀一個字節(jié)的數(shù)據(jù),就會馬上寫入2.txt文件中,需要非常頻繁的讀寫文件。

優(yōu)化:

public class IoTest {
    public static void main(String[] args) {
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            File srcFile = new File("/Users/dv_susan/Documents/workspace/jump/src/main/java/com/sue/jump/service/test1/1.txt");
            File destFile = new File("/Users/dv_susan/Documents/workspace/jump/src/main/java/com/sue/jump/service/test1/2.txt");
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(destFile);
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);
            byte[] buffer = new byte[1024];
            int len;
            while ((len = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
            bos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bos != null) {
                    bos.close();
                }
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (bis != null) {
                    bis.close();
                }
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

這個例子使用BufferedInputStream和BufferedOutputStream創(chuàng)建了可緩沖的輸入輸出流。

最關(guān)鍵的地方是定義了一個buffer字節(jié)數(shù)組,把從1.txt文件中讀取的數(shù)據(jù)臨時保存起來,后面再把該buffer字節(jié)數(shù)組的數(shù)據(jù),一次性批量寫入到2.txt中。

這樣做的好處是,減少了讀寫文件的次數(shù),而我們都知道讀寫文件是非常耗時的操作。也就是說使用可緩存的輸入輸出流,可以提升IO的性能,特別是遇到文件非常大時,效率會得到顯著提升。

3.減少循環(huán)次數(shù)

在我們?nèi)粘i_發(fā)中,循環(huán)遍歷集合是必不可少的操作。

但如果循環(huán)層級比較深,循環(huán)中套循環(huán),可能會影響代碼的執(zhí)行效率。

反例:

for(User user: userList) {
   for(Role role: roleList) {
      if(user.getRoleId().equals(role.getId())) {
         user.setRoleName(role.getName());
      }
   }
}

這個例子中有兩層循環(huán),如果userList和roleList數(shù)據(jù)比較多的話,需要循環(huán)遍歷很多次,才能獲取我們所需要的數(shù)據(jù),非常消耗cpu資源。

正例:

Map<Long, List<Role>> roleMap = roleList.stream().collect(Collectors.groupingBy(Role::getId));
for (User user : userList) {
    List<Role> roles = roleMap.get(user.getRoleId());
    if(CollectionUtils.isNotEmpty(roles)) {
        user.setRoleName(roles.get(0).getName());
    }
}

減少循環(huán)次數(shù),最簡單的辦法是,把第二層循環(huán)的集合變成map,這樣可以直接通過key,獲取想要的value數(shù)據(jù)。

雖說map的key存在hash沖突的情況,但遍歷存放數(shù)據(jù)的鏈表或者紅黑樹的時間復(fù)雜度,比遍歷整個list集合要小很多。

4.用完資源記得及時關(guān)閉

在我們?nèi)粘i_發(fā)中,可能經(jīng)常訪問資源,比如:獲取數(shù)據(jù)庫連接,讀取文件等。

我們以獲取數(shù)據(jù)庫連接為例。

反例:

//1. 加載驅(qū)動類
Class.forName("com.mysql.jdbc.Driver");
//2. 創(chuàng)建連接
Connection connection = DriverManager.getConnection("jdbc:mysql//localhost:3306/db?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8","root","123456");
//3.編寫sql
String sql ="select * from user";
//4.創(chuàng)建PreparedStatement
PreparedStatement pstmt = conn.prepareStatement(sql);
//5.獲取查詢結(jié)果
ResultSet rs = pstmt.execteQuery();
while(rs.next()){
   int id = rs.getInt("id");
   String name = rs.getString("name");
}

上面這段代碼可以正常運行,但卻犯了一個很大的錯誤,即:ResultSet、PreparedStatement和Connection對象的資源,使用完之后,沒有關(guān)閉。

我們都知道,數(shù)據(jù)庫連接是非常寶貴的資源。我們不可能一直創(chuàng)建連接,并且用完之后,也不回收,白白浪費數(shù)據(jù)庫資源。

正例:

//1. 加載驅(qū)動類
Class.forName("com.mysql.jdbc.Driver");
 
Connection connection = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
    //2. 創(chuàng)建連接
    connection = DriverManager.getConnection("jdbc:mysql//localhost:3306/db?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8","root","123456");
    //3.編寫sql
    String sql ="select * from user";
    //4.創(chuàng)建PreparedStatement
    pstmt = conn.prepareStatement(sql);
    //5.獲取查詢結(jié)果
    rs = pstmt.execteQuery();
    while(rs.next()){
       int id = rs.getInt("id");
       String name = rs.getString("name");
    }
} catch(Exception e) {
  log.error(e.getMessage(),e);
} finally {
   if(rs != null) {
      rs.close();
   }
   
   if(pstmt != null) {
      pstmt.close();
   }
   
   if(connection != null) {
      connection.close();
   }
}

這個例子中,無論是ResultSet,或者PreparedStatement,還是Connection對象,使用完之后,都會調(diào)用close方法關(guān)閉資源。

在這里溫馨提醒一句:ResultSet,或者PreparedStatement,還是Connection對象,這三者關(guān)閉資源的順序不能反了,不然可能會出現(xiàn)異常。

5.使用池技術(shù)

我們都知道,從數(shù)據(jù)庫查數(shù)據(jù),首先要連接數(shù)據(jù)庫,獲取Connection資源。

想讓程序多線程執(zhí)行,需要使用Thread類創(chuàng)建線程,線程也是一種資源。

通常一次數(shù)據(jù)庫操作的過程是這樣的:

  • 創(chuàng)建連接
  • 進行數(shù)據(jù)庫操作
  • 關(guān)閉連接

而創(chuàng)建連接和關(guān)閉連接,是非常耗時的操作,創(chuàng)建連接需要同時會創(chuàng)建一些資源,關(guān)閉連接時,需要回收那些資源。

如果用戶的每一次數(shù)據(jù)庫請求,程序都都需要去創(chuàng)建連接和關(guān)閉連接的話,可能會浪費大量的時間。

此外,可能會導(dǎo)致數(shù)據(jù)庫連接過多。

我們都知道數(shù)據(jù)庫的最大連接數(shù)是有限的,以mysql為例,最大連接數(shù)是:100,不過可以通過參數(shù)調(diào)整這個數(shù)量。

如果用戶請求的連接數(shù)超過最大連接數(shù),就會報:too many connections異常。如果有新的請求過來,會發(fā)現(xiàn)數(shù)據(jù)庫變得不可用。

這時可以通過命令:

show variables like max_connections

查看最大連接數(shù)。

然后通過命令:

set GLOBAL max_connections=1000

手動修改最大連接數(shù)。

這種做法只能暫時緩解問題,不是一個好的方案,無法從根本上解決問題。

最大的問題是:數(shù)據(jù)庫連接數(shù)可以無限增長,不受控制。

這時我們可以使用數(shù)據(jù)庫連接池。

目前Java開源的數(shù)據(jù)庫連接池有:

  • DBCP:是一個依賴Jakarta commons-pool對象池機制的數(shù)據(jù)庫連接池。
  • C3P0:是一個開放源代碼的JDBC連接池,它在lib目錄中與Hibernate一起發(fā)布,包括了實現(xiàn)jdbc3和jdbc2擴展規(guī)范說明的Connection 和Statement 池的DataSources 對象。
  • Druid:阿里的Druid,不僅是一個數(shù)據(jù)庫連接池,還包含一個ProxyDriver、一系列內(nèi)置的JDBC組件庫、一個SQL Parser。
  • Proxool:是一個Java SQL Driver驅(qū)動程序,它提供了對選擇的其它類型的驅(qū)動程序的連接池封裝,可以非常簡單的移植到已有代碼中。

目前用的最多的數(shù)據(jù)庫連接池是:Druid。

到此這篇關(guān)于Java中實現(xiàn)代碼優(yōu)化的技巧分享的文章就介紹到這了,更多相關(guān)Java代碼優(yōu)化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot解決java.lang.ArrayStoreException異常

    springboot解決java.lang.ArrayStoreException異常

    這篇文章介紹了springboot解決java.lang.ArrayStoreException異常的方法,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-12-12
  • Java編程實現(xiàn)排他鎖代碼詳解

    Java編程實現(xiàn)排他鎖代碼詳解

    這篇文章主要介紹了Java編程實現(xiàn)排他鎖的相關(guān)內(nèi)容,敘述了實現(xiàn)此代碼鎖所需要的功能,以及作者的解決方案,然后向大家分享了設(shè)計源碼,需要的朋友可以參考下。
    2017-10-10
  • 詳解JUnit5參數(shù)化測試的幾種方式

    詳解JUnit5參數(shù)化測試的幾種方式

    參數(shù)化測試一直是津津樂道的話題,我們都知道JMeter有四種參數(shù)化方式:用戶自定義變量、用戶參數(shù)、CSV文件、函數(shù)助手,那么JUnit5有哪些參數(shù)化測試的方式呢
    2021-07-07
  • Maven版本沖突的三種解決方法

    Maven版本沖突的三種解決方法

    在Maven項目中,依賴傳遞可能導(dǎo)致Jar包版本沖突,常見的解決策略包括依賴排除、版本鎖定和使用maven-shade-plugin插件,本文就來介紹一下這三種解決方法,感興趣的可以了解一下
    2024-10-10
  • SpringBoot 使用 OpenAPI3 規(guī)范整合 knife4j的詳細(xì)過程

    SpringBoot 使用 OpenAPI3 規(guī)范整合 knife4j的詳細(xì)過程

    Swagger工具集使用OpenAPI規(guī)范,可以生成、展示和測試基于OpenAPI規(guī)范的API文檔,并提供了生成客戶端代碼的功能,本文給大家介紹SpringBoot使用OpenAPI3規(guī)范整合knife4j的詳細(xì)過程,感興趣的朋友跟隨小編一起看看吧
    2023-12-12
  • 在Java中讀取CSV文件的方式

    在Java中讀取CSV文件的方式

    在項目開發(fā)中我們經(jīng)常需要讀取csv的內(nèi)容的操作,讀取的邏輯并不復(fù)雜,下面這篇文章主要給大家介紹了關(guān)于在Java中讀取CSV文件的方式,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • Java圖像處理之RGB調(diào)色面板

    Java圖像處理之RGB調(diào)色面板

    這篇文章主要為大家詳細(xì)介紹了Java圖像處理之RGB調(diào)色面板,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • springboot調(diào)用python腳本的實現(xiàn)示例

    springboot調(diào)用python腳本的實現(xiàn)示例

    本文介紹了在SpringBoot應(yīng)用中調(diào)用Python腳本,包括ProcessBuilder類和ApacheCommonsExec庫兩種方法,具有一定的參考價值,感興趣的可以了解一下
    2024-12-12
  • Java實現(xiàn)茶葉售賣商城系統(tǒng)(java+SSM+JSP+EasyUi+mysql)

    Java實現(xiàn)茶葉售賣商城系統(tǒng)(java+SSM+JSP+EasyUi+mysql)

    這篇文章主要介紹了基于SSM框架實現(xiàn)的一個茶葉售賣商城系統(tǒng),應(yīng)用到的技術(shù)有Jsp、SSM 、EasyUi,文中的示例代碼具有一定的學(xué)習(xí)價值,需要的朋友可以參考一下
    2021-12-12
  • 教你使用Java實現(xiàn)掃雷小游戲(最新完整版)

    教你使用Java實現(xiàn)掃雷小游戲(最新完整版)

    本文給大家介紹使用Java實現(xiàn)掃雷小游戲,本程序封裝了五個類,分別是主類GameWin類,繪制底層地圖和繪制頂層地圖的類MapBottom類和MapTop類,繪制底層數(shù)字的類BottomNum類,以及初始化地雷的BottomRay類和工具GameUtil類,用于存靜態(tài)參數(shù)和方法,感興趣的朋友一起看看吧
    2022-05-05

最新評論

抚松县| 鄂伦春自治旗| 抚顺县| 六盘水市| 威信县| 剑川县| 康马县| 望江县| 昌吉市| 登封市| 汉中市| 吉安市| 泊头市| 汝州市| 南川市| 内丘县| 阳泉市| 海阳市| 六枝特区| 嘉义市| 安阳市| 威海市| 兴宁市| 萨迦县| 大港区| 安多县| 吴忠市| 文山县| 保靖县| 黑山县| 且末县| 临沭县| 新闻| 静宁县| 柳河县| 汉中市| 黄梅县| 曲阳县| 光泽县| 三亚市| 永济市|