发现大量Java原语集合处理
在閱讀博客文章5減少Java垃圾收集開銷的技巧時 ,我想起了一個名為Trove的小型Java收集庫,該庫“為Java提供了高速的常規和原始收集”。 我對應用Trove允許原始類型的集合而不是要求集合中的元素成為完整的引用對象的能力特別感興趣。 我在這篇文章中會更詳細地介紹Trove 。
JDK的標準集合尊重泛型,并要求對象引用為其元素,并且不允許在集合中存儲基元。 甚至看起來似乎在標準JDK集合中放置基元的代碼實際上也通過自動裝箱將對象引用放置在集合中。 這種泛型方法的優點是能夠使許多不同類型的對象使用相同的類和方法。 代價是即使可以存儲更精簡的基元,也需要存儲完整的參考對象。
Trove庫具有LPGL許可證 ,并且相對較小(不足10 MB),如“下載”頁面的下一個屏幕快照所示:
小型下載文件不僅包含JAR格式的必需庫。 它還包含文檔和源。 庫JAR本身(本例中trove-3.1a1.jar )的大小約為2.5 MB。
Trove易于使用的原因之一是,它在其自己的集合的API中很大程度上模仿了JDK集合的接口。 下一個代碼清單演示了如何將值添加到List實現實質上是與使用JDK 7 List (在這種情況下為ArrayList)還是Trove提供的TDoubleArrayList相同的API調用。
向JDK的ArrayList和Trove的TDoubleArrayList添加元素
/*** Demonstrate standard JDK {@code ArrayList<Double>}* with some JDK 8 functionality.*/ public void demonstrateJdkArrayListForDoubles() {final ArrayList<Double> doubles = new ArrayList<>();doubles.add(15.5);doubles.add(24.4);doubles.add(36.3);doubles.add(67.6);doubles.add(10.0);out.println("JDK ArrayList<Double>:");out.println("\tDoubles List: " + doubles);out.println("\tMaximum double: " + doubles.stream().max(Double::compare));out.println("\tMinimum double: " + doubles.stream().min(Double::compare));out.println("\tSum of doubles: " + doubles.stream().mapToDouble(Double::doubleValue).sum()); }/*** Demonstrate use of TDoubleArrayList and show how* similar using it is to using {@code ArrayList<Double>}.*/ public void demonstrateTroveArrayListForDoubles() {// Demonstrate adding elements to TDoubleArrayList is// exactly like adding elements to ArrayList<Double>.final TDoubleArrayList doubles = new TDoubleArrayList();doubles.add(15.5);doubles.add(24.4);doubles.add(36.3);doubles.add(67.6);doubles.add(10.0);out.println("Trove TDoubleArrayList:"); // TDoubleArrayList overrides toString()out.println("\tDoubles List: " + doubles);out.println("\tMaximum double: " + doubles.max());out.println("\tMinimum double: " + doubles.min());out.println("\tSum of doubles: " + doubles.sum()); }上面的代碼清單還演示了使用數組列表的Trove實現訪問雙精度集合的最大值,最小值和總和是多么容易。 將這些集合寫入特定原始數據類型(在這種情況下為double)的優點之一是,可以在實現中提供專門應用于該數據類型的方法。 盡管對于String的集合或任意對象的集合返回最大值,最小值和總和來說并沒有TDoubleArrayList意義,但是這些方法的含義對于專門用于雙精度的集合(例如TDoubleArrayList是顯而易見的。 上面的清單確實指示了如何使用流使用JDK 8實現相同的功能。
當查看上面的代碼時,一個細微的差異可能并不明顯(由于自動裝箱),這是JDK實現ArrayList存儲引用Double對象,而Trove TDoubleArrayList實現存儲原始double 。 Trove提供了各種數字類型的列表,集合和映射的實現,例如字節,字符,short,整數,long,float和double。
Trove提供的有趣的數據結構/集合之一是TDoubleArrayStack 。 在剛剛演示過的TDoubleArrayList的支持下, TDoubleArrayStack并未在其API中公開用于添加元素的add方法。 相反,它的方法反映了后進先出(LIFO)堆棧實現中可能期望的語義: push(double)添加, pop()訪問和刪除最近添加的條目,以及peek()查看最近添加的條目而不刪除它。 下一個代碼清單顯示了此堆棧實現的應用程序。 還有其他數字數據類型的堆棧實現。
Trove的TDoubleArrayStack
/*** Demonstrate Trove's Double Array Stack.** Trove's TDoubleArrayStack allows access to its* contents via push, pop, and peek.*/ public void demonstrateTroveDoubleArrayStack() {final TDoubleArrayStack stack = new TDoubleArrayStack();stack.push(15.5);stack.push(17.3);stack.push(16.6);stack.push(2.2);out.println("Trove Array Stack of Doubles");out.println("\tPeek: " + stack.peek() + "; After Size: " + stack.size());out.println("\tPop: " + stack.pop() + "; After Size: " + stack.size());out.println("\tPeek: " + stack.peek() + "; After Size: " + stack.size()); }盡管未在此處顯示,但Trove在其gnu.trove.queue包中還支持Java原始類型的先進先出(FIFO)隊列結構。 該軟件包中的類提供了遵循隊列語義的方法: offer , poll和peek 。
使用JDK集合時, java.util.Collections類提供了許多有用的功能。 Trove提供了java.util.Collections功能的子集,用于在其自己的名為gnu.trove.TCollections的類中使用基于Trove的集合。 具體來說,在撰寫本文時, TCollections類為同步和未修改的Trove集合提供支持。 下一個代碼清單演示了如何使用TCollections ,還演示了如何使用Trove集合,該集合面向的數據類型不是double (在這種情況下為int )和其他數據結構類型(鏈接列表)。
展示了TCollections和TIntLinkedList
/*** Demonstrate one of Trove's "equivalent"s of the* java.util.Collections class.*/ public void demonstrateTroveCollectionsClass() {final TIntLinkedList integers = new TIntLinkedList();integers.add(5);integers.add(7);integers.add(3);integers.add(1);final TIntList unmodifiableIntegers = TCollections.unmodifiableList(integers);try{unmodifiableIntegers.add(15);}catch (Exception ex){out.println("\tException caught: " + ex);} }當希望對基于Trove的集合進行迭代時,可以通過傳統的迭代器對其進行訪問,如下面的代碼清單所示。 盡管在此示例中,集合和關聯的迭代器在long值上起作用,但是Trove為Java的其他原始數據類型提供了類似的集合和迭代器。
使用Trove迭代器迭代Trove集合
/*** Demonstrate "traditional" iteration of a* Trove collection.*/ public void demonstrateIterationWithIterator() {final TLongHashSet longs = new TLongHashSet();longs.add(15);longs.add(6);longs.add(12);longs.add(13);longs.add(2);TLongIterator longIterator = longs.iterator();while (longIterator.hasNext()){final long longValue = longIterator.next();out.println(longValue);} }迭代Trove集合的另一種方法是使用Procedure 。 下面的兩個代碼清單對此進行了演示。 第一個清單演示了一個自定義的面向long過程的過程,第二個清單演示了將該自定義過程通過其forEach方法應用于TLongLinkedList上的迭代。
使用Trove過程迭代Trove集合
/*** Demonstrate iteration of a Trove collection* using a Procedure.*/ public void demonstrateIterationWithProcedure() {final TLongLinkedList longs = new TLongLinkedList();longs.add(15);longs.add(6);longs.add(12);longs.add(13);longs.add(2);longs.forEach(new StandardOutputLongProcedure()); }先前迭代示例中使用的過程實現
package dustin.examples.trove;import static java.lang.System.out;import gnu.trove.procedure.TLongProcedure;/*** Simple implementation of TLongProcedure that* iterates over Trove collection of {@code long}* values and writes those values to standard* output with one value per line.*/ public class StandardOutputLongProcedure implements TLongProcedure {@Overridepublic boolean execute(long longValue){out.println(longValue);return true;} }值得注意的是Trove集合傾向于提供forEachDescending方法以及以相反順序提供迭代。
與GNU Trove相關的其他觀察
- GNU Trove是一個提供“ Java的高速常規和原始集合”的庫,不應與Trove混淆,后者是“ OpenStack的數據庫即服務 ”。
- Trove集合和數據結構的名稱都以“ T”開頭(對于Trove)。 實際上,除了HashingStrategy , IdentityHashingStrategy和Version之外,Trove中的所有類和接口都以“ T” 開頭 。
- Trove集合通常提供接受其基礎數據類型的數組的構造函數,并提供toArray()方法以原始數組的形式提供其數據元素。
- Trove集合通常提供顯式覆蓋的toString()實現,這些實現允許像JDK集合一樣輕松編寫各個數據元素,并且與Java數組(需要Arrays.toString()方法)不同。
- 有關Trove的其他詳細信息,請參見概述 , 常見問題解答和消息論壇 。 其他資源包括使用此Treasure Trove增強集合性能 , Java HashMap性能 , Java中的高性能庫以及TROVE – Java高性能集合 。
- Trove的Java軟件包通常按數據結構類型進行組織,對于同一數據包中給定的數據結構類型,所有特定于原始類型的實現都可以進行組織。 例如,軟件包的名稱類似gnu.trove.list , gnu.trove.set等。
- 因為每個Trove集合都特定于特定的原始數據類型,所以每個集合都不需要通用參數,并且沒有與通用相關的問題(例如擦除)。 此方法還允許每個集合支持特定于該集合中存儲的數據類型的方法。 例如,數字類型的集合可以提供sum方法,而特定于字符類型的集合可以提供grep方法。
結論
在許多常見用途中,JDK提供的集合將表現良好,并且存儲對象引用可能不是問題。 但是,在某些情況下,使用Trove集合(特別是存儲基元而不是對象引用)的能力可能會提供必要的優勢。 隨著集合變大,在集合中存儲基元而不是它們的等效對象引用的優勢變得更加明顯。
翻譯自: https://www.javacodegeeks.com/2016/01/discovering-trove-java-primitives-collection-handling.html
總結
以上是生活随笔為你收集整理的发现大量Java原语集合处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ddos防御手段有哪些(ddos防御手段
- 下一篇: 与Selenium的集成测试