Useful Java Coding Tips (1)- Collection

4277 ワード

Javaコレクションフレームワークに関連するクラスは、Deque、List、Set、Queue、Mapなど、日常的な符号化でよく使用されるツールクラスであり、add()/put()、contains()/get()、remove()など、一連の一般的な方法を定義している.Javaコレクションフレームワークの操作に関するいくつかのテクニックをまとめます. 
  • はリストを巡回し、下付きではなくIteratorを使用する.リストの実装がLinkedListである場合、遍歴動作はO(n*n)に劣化するからである.ループ中に要素の下付き文字を知る必要がある場合は、ループ外で下付き文字変数を定義します.
        private void visitList(List<String> foo) {
            // Bad Practice, Don't do that    
            for (int i = 0; i < foo.size(); i++) {
                String bar = foo.get(i);
            }
        }
  • ArrayListやHashmapのような自動拡張可能な集合オブジェクトを作成する場合、その要素の個数が固定されている場合は、add()/put()操作時の配列自動拡張/Rehashを回避するために、初期サイズを含む構造方法を選択する必要があります.1つの一般的なシーンは、ある集合オブジェクトの要素を別の集合オブジェクトにコピーすることです.
  • メソッドが空の集合オブジェクトを返す必要がある場合は、Collections.EMPTY_を使用します.LIST, Collections.EMPTY_MAP, Collections.EMPTY_SETは,new操作を用いて新しい空の集合を作成することを避ける.
        private Map<String, String> copyProperties(Properties foo) {
            if (foo == null || foo.isEmpty()) {
                return Collections.EMPTY_MAP;
            }
    
            Map<String, String> bar = new HashMap<String, String>(foo.size());
            for (Object key : foo.keySet()) {
                bar.put(String.valueOf(key), String.valueOf(foo.get(key)));
            }
    
            return bar;
        }
  • コレクションを巡回中に一部の要素を削除する必要がある場合は、コレクションの変更によってIteratorが不正になることに注意し、java.util.C o n c u r r e ntModificationExceptionを放出しますが、Iteratorに対して独自のremove()メソッドを呼び出すことはできません.
        private void removeOddBad(List<Integer> foo) {
            int i = 0;
            for (Integer bar : foo) {
                if (bar % 2 != 0) {
                    foo.remove(i);
                }
                i++;
            }
    
        }
    
        private void removeOddGood(List<Integer> foo) {
            Iterator<Integer> bar = foo.iterator();
            while (bar.hasNext()) {
                if (bar.next() % 2 != 0) {
                    bar.remove();
                }
            }
    
        }
  • 修正が許可されていない集合オブジェクトを返す場合は、Collections.unmodifiableXXX()シリーズメソッドを使用して元の集合オブジェクトをカプセル化し、変更操作を制限するために独自の集合クラスをカスタマイズする必要はありません.
  • Apache CommonsとGoogle Gauvaは、集合を交差させるなど、非常に豊富な集合クラスAPIを提供しています.In-Processを実現するLRU Cacheは、Google GauvaのLoading Cacheを使用することができます.繰り返し発明ホイールを避ける.
  • 集合フレームワークのインタフェースには異なる実装があり、どの実装を選択するかは、まず、ビジネスロジックペアの増加、削除、検索の頻度を明確にし、次に実装クラスの下位データ構造に基づいて、最も頻繁な操作に最適な時間複雑度を提供する実装を選択する必要がある.
  • PriorityQueueはデータ構造のスタックの実装であり、PriorityQueueに要素を追加し、要素タイプがComparableインタフェースを実装すると、デフォルトではPriorityQueueは小さなスタック(スタックトップの要素が最小)であり、カスタムComparatorを実装することで大きなスタックを実装することができる.次の例は,N個の乱数配列の要素を与え,順序配列の最小K個の要素を探し出すTOP K問題の実現である(K< // find the smallest K elements in a given array with N elements private void findSmallestElements(List<Integer> list, int k) { // define the compare result for integer Comparator<Integer> compartor = new Comparator<Integer>() { @Override public int compare(Integer x, Integer y) { return x.compareTo(y) * -1; } }; PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(k, compartor); for (Integer val : list) { if (maxHeap.size() == k) { int top = maxHeap.peek(); if (val < top) { maxHeap.poll(); maxHeap.add(val); } } else { maxHeap.add(val); } } while (maxHeap.size() > 0) { System.out.print(maxHeap.poll() + " "); } } private void test() { int n = 100; int k = 10; List<Integer> list = new ArrayList<Integer>(n); for (int i = 0; i < n; i++) { list.add(i); } // re-arrange the list randomly for (int i = 1; i < n; i++) { // generate a random position j between [i, n-1] int j = (int) Math.random() * (n - 1 - i) + i; // swap value at i and j int tmp = list.get(i); list.set(i, list.get(j)); list.set(j, tmp); } // find the smallest 10 elements: {9 8 7 6 5 4 3 2 1 0 } findSmallestElements(list, k); }