中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java中int轉string與string轉int的效率有什么不同

發布時間:2022-03-14 09:24:06 來源:億速云 閱讀:7045 作者:小新 欄目:開發技術

這篇文章將為大家詳細講解有關java中int轉string與string轉int的效率有什么不同,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

    int轉string與string轉int的效率對比

    string轉int,兩種方法

    Interger.parseInt(String)
    Interger.valueOf(String).intValue()

    第二種方法可以去看源碼,實現了第一種方法。

    java中int轉string與string轉int的效率有什么不同

    注釋大概就是這樣的意思

    /**
          *返回一個包含整數的對象
          *指定的{@ String String}的值。 這個說法是
          *被解釋為表示一個有符號的十進制整數
          *就好像這個論據是給予{@link的
          * #parseInt(java.lang.String)}方法。 結果是一個
          表示整數值的整數對象
          *由字符串指定。
         *
          換句話說,這個方法返回一個{@code Integer}
          *對象等于以下值:
         *
          * <blockquote>
          * {@code new Integer(Integer.parseInt(s))}
          * </ blockquote>
         *
          * @param是要解析的字符串。
          * @返回一個保存值的{整數}對象
          *由字符串參數表示。
          * @exception NumberFormatException如果字符串不能被解析
          *作為一個整數。
         */

    在valueOf()里面實現了parseInt()方法。時間對比第二種比第一種要快了很多。

     Integer.parseInt(str) : 21
     Integer.valueOf(str).intValue() : 14

    int 轉string一般用三種方法

    • 第一種:number + ""

    • 第二種:string.valueOf()

    • 第三種:.toString()

    • 先說第一種,簡單粗暴。

    • 第二種方法:底層使用的依舊是.toString()方法

    • 第三種就是toString()

    上代碼。

    int num = 888888;
     
            //(1)num + ""
            long start = System.currentTimeMillis();//得到開始運行時系統時間
            for(int i=0; i<100000; i++){
                String str = num + "";
            }
            long end = System.currentTimeMillis();//得到結束運行時系統時間
            System.out.println("num + \"\" : " + (end - start));
     
            //(2)String.valueOf(num)
            start = System.currentTimeMillis();
            for(int i=0; i<100000; i++){
                String str = String.valueOf(num);
            }
            end = System.currentTimeMillis();
            System.out.println("String.valueOf(num) : " + (end - start));
     
            //(3)Integer.toString(num)
            start = System.currentTimeMillis();
            for(int i=0; i<100000; i++){
                String str = Integer.toString(num);
            }
            end = System.currentTimeMillis();
            System.out.println("Integer.toString(num) : " + (end - start));

    結果就是

    num + "" : 82
    String.valueOf(num) : 32
    Integer.toString(num) : 9

    經過多次的反復測試,toString()是最快的,num+""是最慢的,在使用String.valueOf()中源碼是這樣的。

    public static String valueOf(Object obj) {
        return (obj == null) ? "null" : obj.toString();
    }

    也就是說在使用的時候,不用去判斷所傳的對象是否為null,但是尤其注意,如果傳的為空,返回來的是一個為null的字符串而不是null值,這個地方需要謹記。

    string轉int問題分析

    相信很多同學在面試時都遇到過這樣一個問題,要求封裝一個函數,將String類型轉換為int類型。這個看似簡單的問題其實隱藏著很多細節,要想真正封裝好這個函數并不容易。面試官要考察的其實并不是算法本身的難度,這個問題的算法其實沒有什么難度可言,主要要考察的是程序員寫代碼的仔細程度,考慮問題是否全面,也就是說,我們要盡可能的讓代碼具有魯棒性。下面我們一步步的分析這個問題中隱藏的細節。

    分析一波

    首先我們不考慮任何的異常處理,假設函數的調用者傳入的數據都是正確的,很容易就可以寫出下面的代碼:

        public int strToInt(String str) {
            int number = 0;
            for (int i=0; i<str.length(); i++) {
                number *= 10;
                number += (str.charAt(i) - '0');
            }
            return number;
        }

    上面的代碼將遍歷字符串的每一位字符,并將其轉換為對應的整數,然后將其一一融入到整形數據number中。

    如果你給面試官提交的是這樣一份代碼,結果肯定不會滿意。因為你沒有考慮到程序的魯棒性,我們封裝的函數相當于API接口,是提供給所有開發者調用的,難免其他開發者不會傳入一些奇怪的參數,而這段代碼對異常參數沒有做任何處理,一旦傳入異常參數,程序將直接崩潰。下面我們一步步來完善這個函數,提高其魯棒性。

    1、針對傳入的字符串為空對象或者字符串為空的字符串
        public int strToInt(String str) throws NumberFormatException{
            if (str == null || str.contentEquals("")) { // 如果傳入的字符串為空對象或者傳入的字符串為空字符串,則拋出異常
                throw new NumberFormatException("null or empty string"); // 這里直接利用java封裝好的異常類,當然我們也可以自己封裝異常類,面試官要考察的不是對異常類的封裝,而是你要知道要處理異常情況
            }
            int number = 0;
            for (int i=0; i<str.length(); i++) {
                number *= 10;
                number += (str.charAt(i) - '0');
            }
            return number;
        }

    首先我們字符串是否為空或者是否為空的字符串,如果是,則直接拋出異常,這里我們使用的是Java封裝好的異常類NumberFormatException,當然我們也可以自己封裝異常類,面試官要考察的不是對異常類的封裝,而是你要知道要處理異常情況。

    2、針對符號位的處理

    這個我們最好提前問一下面試官,有沒有可能傳入的是負數,當為正數時,是否允許帶符號位,如果是的話,我們就要針對符號位進行處理,負數的第一個字符是“-”,我們只要判斷第一個字符是否為“-”就可以知道傳入的是否為負數了,如果正數允許帶符號位,那邊第一個字符有可能是“+”,我們也要做對應的處理:

        public int strToInt(String str) throws NumberFormatException{
            if (str == null || str.contentEquals("")) { // 如果傳入的字符串為空對象或者傳入的字符串為空字符串,則拋出異常
                throw new NumberFormatException("null or empty string"); // 這里直接利用java封裝好的異常類,當然我們也可以自己封裝異常類,面試官要考察的不是對異常類的封裝,而是你要知道要處理異常情況
            }
            boolean negative = false; // negative為true表示是負數,反之為正數
            int pos = 0;
            if (str.charAt(0) == '-') { // 如果為負數
                negative = true;
                pos++; // 調過第一位符號位
            } else if (str.charAt(0) == '+') {
                pos++; // 調過第一位符號位
            }
            int number = 0;
            while (pos < str.length()) {
                number *= 10;
                number += (str.charAt(pos) - '0');
                pos++;
            } 
            return negative ? -number : number; // 如果為負數則返回對應的負數
        }
    3、針對錯誤字符的處理

    函數的調用者可能會傳入一下亂七八糟的字符串,比如“abc23123”,針對這種情況我們也要做對應的處理,應該給調用者拋出一個異常,告知其傳入的字符串是非法字符串:

        public int strToInt(String str) throws NumberFormatException{
            if (str == null || str.contentEquals("")) { // 如果傳入的字符串為空對象或者傳入的字符串為空字符串,則拋出異常
                throw new NumberFormatException("null or empty string"); // 這里直接利用java封裝好的異常類,當然我們也可以自己封裝異常類,面試官要考察的不是對異常類的封裝,而是你要知道要處理異常情況
            }
            boolean negative = false; // negative為true表示是負數,反之為正數
            int pos = 0;
            if (str.charAt(0) == '-') { // 如果為負數
                negative = true;
                pos++; // 調過第一位符號位
            } else if (str.charAt(0) == '+') {
                pos++; // 調過第一位符號位
            }
            int number = 0;
            while (pos < str.length()) {
                if (str.charAt(pos) >= '0' && str.charAt(pos) <= '9') { // 只有字符在'0'到'9'的范圍內,才算正確的字符
                    number *= 10;
                    number += (str.charAt(pos) - '0');
                    pos++; 
                } else {
                    throw new NumberFormatException("invalid string"); // 當字符是其他字符時,拋出異常告知調用者傳入的字符串錯誤
                }
            } 
            return negative ? -number : number; // 如果為負數則返回對應的負數
        }
    4、針對整形數據超出范圍的處理

    調用者傳入的字符串可能是一個很長的字符串,轉換為整數可能超出了整數的存儲范圍,比如“12345678674324334”,在這種情況下,我們要拋出一個異常告知調用者傳入的字符串超出了整形的范圍:

        public int strToInt(String str) throws NumberFormatException{
            if (str == null || str.contentEquals("")) { // 如果傳入的字符串為空對象或者傳入的字符串為空字符串,則拋出異常
                throw new NumberFormatException("null or empty string"); // 這里直接利用java封裝好的異常類,當然我們也可以自己封裝異常類,面試官要考察的不是對異常類的封裝,而是你要知道要處理異常情況
            }
            boolean negative = false; // negative為true表示是負數,反之為正數
            int pos = 0;
            if (str.charAt(0) == '-') { // 如果為負數
                negative = true;
                pos++; // 調過第一位符號位
            } else if (str.charAt(0) == '+') {
                pos++; // 調過第一位符號位
            }
            int limit = negative ? (-Integer.MIN_VALUE) : Integer.MAX_VALUE;
            int mult = limit / 10; // 記錄最大數/10,讓number和這個數比較,如果大于它,則number * 10肯定也就大于最大數
            int number = 0;
            while (pos < str.length()) {
                if (str.charAt(pos) >= '0' && str.charAt(pos) <= '9') { // 只有字符在'0'到'9'的范圍內,才算正確的字符
                    if (number > mult) {// 讓number和mult比較,如果大于它,則number * 10肯定也就大于最大數
                        throw new NumberFormatException("input string beyond int size");
                    }
                    number *= 10;
                    int digit = str.charAt(pos) - '0';
                    if (number > limit - digit) { // 這里不能用number + digit > limit來判斷,因為number + digit可能超出整數的存儲范圍,相加后的數可能是一個負數,但是limit - digit肯定不會超出
                        throw new NumberFormatException("input string beyond int size");
                    } else {
                        number += digit;
                    }
                    pos++;
                } else {
                    throw new NumberFormatException("invalid string"); // 當字符是其他字符時,拋出異常告知調用者傳入的字符串錯誤
                }
            } 
            return negative ? -number : number; // 如果為負數則返回對應的負數
        }

    上面的代碼中,我們判斷number是否會超出最大整數時首先是先讓其(最大整數/10)的值比較,而不是讓其乘以10與最大整數比較,這是因為number * 10如果超出了整數范圍,則會造成數據溢出,其得到的值可能是一個負數,而(最大整數/10)的值是不會數據溢出的,這也是一個小細節。可能你以為這樣這個函數就完美了,但是現在我要告訴你,上面的寫法是錯誤的。

    為什么呢?這要從整數的范圍說起,整數的取值范圍是(-2^31)至(2^31 - 1),從絕對值的角度看,最小負數相比于最大正數大1。所以上面代碼中(-Integer.MIN_VALUE)會超出整形的范圍,造成數據溢出,也就是說上面的代碼對負數最小范圍的限制的處理是錯誤的。那么怎么解決這個問題呢?

    我們換個角度思考,最小負數的絕對值比最大正數的絕對值大1,那(-Integer.MAX_VALUE)的值肯定不會超出整數的范圍,我們現在的程序是以正數的方式處理,如果反過來已負數的方式處理,問題不就解決了嗎?修改代碼如下:

        public int strToInt(String str) throws NumberFormatException{
            if (str == null || str.contentEquals("")) { // 如果傳入的字符串為空對象或者傳入的字符串為空字符串,則拋出異常
                throw new NumberFormatException("null or empty string"); // 這里直接利用java封裝好的異常類,當然我們也可以自己封裝異常類,面試官要考察的不是對異常類的封裝,而是你要知道要處理異常情況
            }
            boolean negative = false; // negative為true表示是負數,反之為正數
            int pos = 0;
            if (str.charAt(0) == '-') { // 如果為負數
                negative = true;
                pos++; // 調過第一位符號位
            } else if (str.charAt(0) == '+') {
                pos++; // 調過第一位符號位
            }
            int limit = negative ? Integer.MIN_VALUE : (-Integer.MAX_VALUE);
            int mult = limit / 10;
            int number = 0;
            while (pos < str.length()) {
                if (str.charAt(pos) >= '0' && str.charAt(pos) <= '9') { // 只有字符在'0'到'9'的范圍內,才算正確的字符
                    if (number < mult) {
                        throw new NumberFormatException("input string beyond int size");
                    }
                    number *= 10;
                    int digit = str.charAt(pos) - '0';
                    if (number < limit + digit) {
                        throw new NumberFormatException("input string beyond int size");
                    } else {
                        number -= digit;
                    }
                    pos++;
                } else {
                    throw new NumberFormatException("invalid string"); // 當字符是其他字符時,拋出異常告知調用者傳入的字符串錯誤
                }
            } 
            return negative ? number : -number;
        }

    OK,現在我們把能夠想到的異常情況處理了。再來考慮一個問題,為什么整形數據的范圍是(-2^31)至(2^31 - 1),最小負數的絕對值比最大正數的絕對值要大1呢?

    5、int數據范圍的討論

    我們知道,一個int類型占四個字節,也就是32位,其中第一位是符號位,符號位為0表示正數,為1表示負數,其余31位表示數值。正常來說int類型的數據范圍應該是(-2^31-1)到(2^31-1),為什么負數會多一位呢?

    我們首先看一下Java代碼中對Integer.MAX_VALUE和Integer.MIN_VALUE的定義:

        /**
         * A constant holding the minimum value an {@code int} can
         * have, -2<sup>31</sup>.
         */
        public static final int   MIN_VALUE = 0x80000000;
     
        /**
         * A constant holding the maximum value an {@code int} can
         * have, 2<sup>31</sup>-1.
         */
        public static final int   MAX_VALUE = 0x7fffffff;
    原碼、反碼、補碼

    我們知道,在計算機中,數據都是以二進制的形式存儲的,比如,數字10,其二進制形式就是1010。

    一個字節有8位,每位可以存儲一個01字符,byte類型占1個字節,也就是8位,其中,最高位是符號位,用來表示數值是正數還是負數,符號位為0表示正數,符號位為1表示負數。我們先來看一下原碼、反碼、補碼的定義:

    • 原碼:符號位加上真值的絕對值, 即用第一位表示符號, 其余位表示值。

    • 反碼:正數的反碼是其本身;負數的反碼是在其原碼的基礎上, 符號位不變,其余各個位取反。

    • 補碼:補碼的表示方法是:正數的補碼就是其本身;負數的補碼是在其原碼的基礎上, 符號位不變, 其余各位取反, 最后+1。 (即在反碼的基礎上+1)

    正數的原碼、反碼、補碼都是其本身;負數的反碼是在其原碼的基礎上,符號位不變,其余個位取反,負數的補碼是其反碼的基礎上+1。

    舉例說明(下面都以byte類型進行舉例):

    數據原碼反碼補碼
    10000010100000101000001010
    -10100010101111010111110110

    計算機中,數據都是以補碼的形式存儲的。為什么要以補碼的形式存儲呢?有兩個原因:

    1、如果數值以補碼的形式保存,對一個數進行求補運算,可以得到其相反值

    求補運算:將一個數(包括正數和負數)所有二進制位(包括符號位和數值位)取反,然后在最低位加上1。

    為什么對一個數進行求補運算,可以得到其相反值呢?我們先來分析一下求補運算的定義,現將所有的二進制取反,然后+1,首先一個數和它所有位取反得到的數相加,其結果肯定是11111111,這是因為它們每一位都不一樣,然后將結果+1,即11111111 + 1,結果是1 00000000,最高位的1已經溢出,換種方式說,如果以f(n)表示對n進行求補運算,那么對于任意的范圍內的數,可以得到:

    n + f(n) = 1 00000000

    f(n) = 1 00000000 - n

    而對于一個正數來說,對其進行求補運算其實得到的就是它的相反數的補碼(負數的補碼符號位保持不變,其他為全部取反再+1,因為正數和負數的符號位本來就不一樣,所以對一個正數進行求補其實得到的就是它的相反數的補碼)。

    那么對于一個負數來說呢?對其進行求補運算是否能夠得到其對應的正數的補碼呢?

    假設n>0,根據上面可知:

    f(n) = 1 00000000 - n

    對f(n)進行求補運算,有:

    f(f(n)) = f(1 00000000 - n) = 1 00000000 - (1 00000000 - n) = n

    其中,1 00000000 - n表示n對應負數的補碼,對其進行求補運算得到的就是n,正數的補碼就是其原碼。

    由上可知:如果數值以補碼的形式保存,對一個數進行求補運算,可以得到其相反值,即:f(n) = -n

    2、方便減法運算

    如果數值以補碼的方式存儲,可以將減法變為加法,省去了減法器,通過上面的推導,如果數據以補碼的方式存儲,以f(n)表示對n進行求補運算,可以得到:

    f(n) = -n

    那么現在我們需要計算m - n,應該要怎么計算呢?如果以補碼的方式存儲,那么就有:

    m - n = m + (-n) = m + f(n)

    也就是說,減去一個數只需要加上對其進行求補運算后得到的值即可。

    3、使用補碼存儲數據,可以對任意的兩個數直接進行相加運算,不用考慮符號位

    4、通過補碼形式存儲,規定10000000對應的負數的最小值,也就是-128。

    由上面可知,如果是byte類型,數據范圍應該為[-128,127],最小負數要比最大正數多一位。

    關于“java中int轉string與string轉int的效率有什么不同”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    嘉祥县| 溧水县| 新化县| 南华县| 靖西县| 连城县| 黄大仙区| 奉节县| 安龙县| 蚌埠市| 交口县| 县级市| 静乐县| 东源县| 略阳县| 阜康市| 灵丘县| 五常市| 微山县| 宜都市| 封开县| 泌阳县| 八宿县| 贺州市| 大田县| 晋州市| 布拖县| 汉寿县| 伊金霍洛旗| 屏东市| 商丘市| 乌兰察布市| 易门县| 桐乡市| 托克逊县| 河池市| 博野县| 泰安市| 赤水市| 昌图县| 商城县|