欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java接口中盡量避免使用數(shù)組

 更新時間:2015年07月10日 10:58:35   投稿:goldensun  
這篇文章主要介紹了Java接口中盡量避免使用數(shù)組的建議,根據(jù)實際示例展示了接口中使用數(shù)組而造成的影響程序速度的現(xiàn)象,需要的朋友可以參考下

 如果你發(fā)現(xiàn)在一個接口使用有如下定義方法:
 

public String[] getParameters();

那么你應該認真反思。數(shù)組不僅僅老式,而且我們有合理的理由避免暴露它們。在這篇文章中,我將試圖總結(jié)在Java API中使用數(shù)組的缺陷。首先從最出人意料的一個例子開始。
數(shù)組導致性能不佳

你可能認為使用數(shù)組是最快速的,因為數(shù)組是大多數(shù)collection實現(xiàn)的底層數(shù)據(jù)結(jié)構(gòu)。使用一個純數(shù)組怎么會比使用一個包含數(shù)組的對象性能更低?


讓我們先從這個看起來很熟悉的普遍的習慣用法開始:
 

public String[] getNames() {
 return namesList.toArray( new String[ namesList.size() ] );
}

這個方法從一個用來在其內(nèi)部保存數(shù)據(jù)的可變集合處創(chuàng)建了一個數(shù)據(jù). 它通過提供一個確切大小的數(shù)組來嘗試優(yōu)化數(shù)組的創(chuàng)建. 有趣的是,這一“優(yōu)化”使得其比下面的更簡單的版本速度還要慢(請看圖表中綠色VS橘色條):
 

public String[] getNames() {
 return namesList.toArray( new String[ 0 ] );
}

不過,如果方法返回的是一個List, 創(chuàng)建防御式的副本又更加的快了 (紅條):
 

public List<String> getNames() {
 return new ArrayList( namesList );
}

不同之處在于一個ArrayList將它的數(shù)據(jù)項放在一個Object[]數(shù)組中,并且使用的是無類型的toArray方法,其比有類型的方法要快很多(藍條). 這是類型安全的,因為無類型的數(shù)組時封裝在由編譯器檢查的泛型類型ArrayList<T>中的.

2015710105938872.png (664×146)

這個圖標展示了一個在Java 7上n=5的參考標準. 不過,更多的數(shù)據(jù)項或者是另外一個VM情況系啊,這幅圖片并不會改變太多. CPU的開銷可能并不會太劇烈,但是會有增長. 機會有一個數(shù)組的使用者應該將其轉(zhuǎn)換到一個集合中去,以便利用它做任何事情, 然后將結(jié)果轉(zhuǎn)換回一個數(shù)組,來送進另外一個接口的方法中,諸如此類做法.

是用一個簡單的ArrayList,而不是一個數(shù)組來提升性能,無需再動太多的手腳. ArrayList 為封裝的數(shù)組增加了32字節(jié)的恒定開銷. 例如,一個有十個對象的數(shù)組需要104字節(jié),一個ArrayList 136字節(jié).

使用 集合,你甚至可能決定返回內(nèi)部列表的一個不可修改的版本:
 

public List<String> getNames() {
 return Collections.unmodifiableList( namesList );
}

此操作會在固定的市價運行,因此他比任何上述其它的方法都要快很多(黃條). 其同一個防御式的拷貝不同。一個不可修改的集合將會在你的內(nèi)部數(shù)據(jù)變化時跟著變化。如果變化發(fā)生了,客戶端會在迭代數(shù)據(jù)項時運行到一個ConcurrentModificationException中. 可以認為它是一個糟糕的設計,接口提供了一個在運行時拋出一個UnsupportedOperationException. 不過,至少對于內(nèi)部的使用,這個方法對于一個防御式的拷貝而言,會是一個高性能的選擇 - 一些不可能使用數(shù)組實現(xiàn)的東西.

數(shù)組定義一個結(jié)構(gòu),而不是一個接口

Java 是一門面向?qū)ο蟮恼Z言。面向?qū)ο蟮暮诵母拍罹褪翘峁┮恍┓椒▉碓L問和操作它們的數(shù)據(jù),而不是直接對數(shù)據(jù)域進行操作. 這些方法創(chuàng)建一個接口來描述你可以在對象上面做的事情.

由于java已經(jīng)對性能做了設計,原生類型和數(shù)組已經(jīng)被融合進了類型系統(tǒng)之中. 對象可以使用數(shù)組來在內(nèi)容高效地存儲數(shù)據(jù). 然而,即使通過數(shù)組來呈現(xiàn)一個可變集合的元素,它們也不會提供任何方法來訪問和操作這些元素. 事實上,除了直接訪問的替換元素之外,在數(shù)組上你沒有多少其它事情可以做. 數(shù)組甚至連toString 和 equals 都沒有一個有意義的實現(xiàn), 而集合卻有:
 

String[] array = { "foo", "bar" };
List<String> list = Arrays.asList( array );
 
System.out.println( list );
// -> [foo, bar]
System.out.println( array );
// -> [Ljava.lang.String;@6f548414
 
list.equals( Arrays.asList( "foo", "bar" ) )
// -> true
array.equals( new String[] { "foo", "bar" } )
// -> false

不同于數(shù)組,集合的 API 提供了許多有用的方法來訪問元素. 用戶可以檢查包含的元素,提取子列表或者計算交集. 集合可以向數(shù)據(jù)層添加特定的特性, 諸如線程安全,同時將實現(xiàn)原理保持在內(nèi)部可見.

通過使用一個數(shù)據(jù),你定義了數(shù)據(jù)被保存在內(nèi)存中的哪個地方. 通過使用一個集合,你定義了用戶可以在數(shù)據(jù)上做的操作.

數(shù)組不是類型安全的

如果你依賴于編譯器檢查的類型安全,小心對象數(shù)組. 下面的代碼會在運行時奔潰,但是編譯器找不出問題所在:

Number[] numbers = new Integer[10];
numbers[0] = Long.valueOf( 0 ); // throws ArrayStoreException

原因是數(shù)組是“協(xié)變式”的, 比如,如果 T 是S 的一個子類型, 那么 T[] 就會是 S[] 的一個子類型. Joshua Bloch 在其著作 Effective Java 涵蓋了所有的理論, 每一個Java開發(fā)者必讀.

歸因于這個行為,暴露數(shù)組類型的接口允許返回聲明數(shù)組類型的一個子類型, 導致了一個怪異的運行時異常.


Bloch 同時也解釋說,數(shù)組與泛型類型不兼容. 因為數(shù)組會在運行時強制要求有類型信息,而泛型則會在編譯時被檢查,泛型類型不能被放到數(shù)組中.

  •     一般而言,數(shù)組和泛型不能很好的融合。如果你發(fā)現(xiàn)自己在融合它們而得到了一個編譯時錯誤或者警告,那你的第一反應應該是用list去替換數(shù)組.

- Joshua Bloch, Effective Java (第二版), 第29條
總結(jié)

數(shù)組底層的語言構(gòu)造、它們會被用在實現(xiàn)中,但是它們不應該想其它的類暴露. 在一個接口方法中使用數(shù)組違背了面向?qū)ο蟮脑瓌t,它會導致違和的API,并且它也可能給類型安全和性能造成短板.

相關文章

  • 在Java的Spring框架的程序中使用JDBC API操作數(shù)據(jù)庫

    在Java的Spring框架的程序中使用JDBC API操作數(shù)據(jù)庫

    這篇文章主要介紹了在Java的Spring框架的程序中使用JDBC API操作數(shù)據(jù)庫的方法,并通過示例展示了其存儲過程以及基本SQL語句的應用,需要的朋友可以參考下
    2015-12-12
  • Java使用Collections.sort對中文進行排序方式

    Java使用Collections.sort對中文進行排序方式

    這篇文章主要介紹了Java使用Collections.sort對中文進行排序方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 深入理解Java對象復制

    深入理解Java對象復制

    使用任何已有的工具,都沒有直接使用 get set 方式進行,對象轉(zhuǎn)換的速度快,雖然get set 方式代碼對一些比較麻煩,但是效率要高一些的,推薦使用 MapStruct 方式.,需要的朋友可以參考下
    2021-05-05
  • LeetCode?動態(tài)規(guī)劃之矩陣區(qū)域和詳情

    LeetCode?動態(tài)規(guī)劃之矩陣區(qū)域和詳情

    這篇文章主要介紹了LeetCode?動態(tài)規(guī)劃之矩陣區(qū)域和詳情,文章基于Java的相關資料展開對LeetCode?動態(tài)規(guī)劃的詳細介紹,需要的小伙伴可以參考一下
    2022-04-04
  • Java?精煉解讀類和對象原理

    Java?精煉解讀類和對象原理

    面向?qū)ο竽耸荍ava語言的核心,是程序設計的思想。Java語言的面向?qū)ο蠹夹g包括了面向?qū)ο蠛兔嫦蜻^程的基本概念,面向?qū)ο蟮奶卣?,Java語言的類,對象,修飾符,抽象類等一系列的知識點
    2022-03-03
  • Java實現(xiàn)人機猜拳小游戲

    Java實現(xiàn)人機猜拳小游戲

    這篇文章主要為大家詳細介紹了Java實現(xiàn)人機猜拳小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • mybatis分頁絕對路徑寫法過程詳解

    mybatis分頁絕對路徑寫法過程詳解

    這篇文章主要介紹了mybatis分頁絕對路徑寫法過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • 5個Java API使用技巧

    5個Java API使用技巧

    這篇文章主要為大家詳細介紹了Java API安全和性能方面的簡單易用技巧,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Springmvc自定義類型轉(zhuǎn)換器實現(xiàn)步驟

    Springmvc自定義類型轉(zhuǎn)換器實現(xiàn)步驟

    這篇文章主要介紹了Springmvc自定義類型轉(zhuǎn)換器實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-08-08
  • SpringMVC基于注解方式實現(xiàn)上傳下載

    SpringMVC基于注解方式實現(xiàn)上傳下載

    本文主要介紹了SpringMVC基于注解方式實現(xiàn)上傳下載,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-04-04

最新評論