収集処理


1. 【必須】hashCodeとequalsの処理については以下のルールに従ってください:

1)equalsを書き換える限り、hashCodeも書き換​​える必要があります。

2) Set は一意のオブジェクトを格納し、hashCode と等しい値に基づいて判断されるため、Set に格納された

オブジェクトはこれら 2 つのメソッドをオーバーライドする必要があります。

3) カスタム オブジェクトをマップ キーとして使用する場合は、hashCode と equals をオーバーライドする必要があります。

良い例: String は hashCode メソッドと equals メソッドをオーバーライドするため、String オブジェクト をキーとして問題なく使用できます。


#2. [必須] ArrayList の subList の結果を ArrayList に強制的に変換することはできません、そうでない場合は ClassCastException 例外がスローされます: java . util . RandomAccessSubList を java . util . ArrayList ;

説明: subList は、ArrayList ではなく、ArrayList の内部クラス SubList を返しますが、ArrayList のビューを返します。 SubList に対するすべての操作は、最終的には元のリストに反映されます。


3. [必須] subList シナリオでは、元のコレクション内の要素の数を変更することに細心の注意を払ってください。サブリスト 追加および削除すると、ConcurrentModificationException が生成されます。


4. [必須] コレクションを配列に変換するメソッドを使用するには、コレクションの toArray(T[] array) を使用する必要があります。渡される型は完全に 同じ配列、サイズは list.size() です。

カウンターの例: パラメータなしで toArray を直接使用することには問題があります。このメソッドの戻り値は Object[] クラスのみです。他のものを強制キャストした場合 型を配列にすると ClassCastException が発生します。

正の例:

List<String> list = new ArrayList<String>(2);
list.add("guan");
list.add("bao");
String[] array = new String[list.size()];
array = list.toArray(array);

説明: toArray パラメーター メソッドを使用し、入力パラメーターに割り当てられた配列スペースが十分な大きさではありません。toArray メモリ空間はメソッド内で内部的に再割り当てされ、新しい配列アドレスが返されます。配列要素が実際に必要なサイズよりも大きい場合は、配列 要素に添え字 [ list .size()] は null に設定されます。他の配列要素は元の値を保持するため、メソッド入力パラメータ グループのサイズを、リスト内の 要素の数と一致するように定義することをお勧めします。コレクション。


5. [必須] ツール クラス Arrays.asList() を使用して配列をコレクションに変換する場合、その変更に関連するメソッドは使用できません。 collection の場合、その add/remove/clear メソッドは UnsupportedOperationException をスローします。

注: asList の戻りオブジェクトは Arrays 内部クラスであり、コレクション変更メソッドを実装しません。配列。asList はインターフェイスのみを変換するアダプター モードを具体化しており、バックグラウンド データは依然として配列です。

String[] str = new String[] { "a", "b" };
List list = Arrays.asList(str);

最初の状況: list.add("c"); 実行時例外。

2 番目のケース: str[0]= "gujin"; の場合、list.get(0) もそれに応じて変更されます。


6. [必須] 返されたデータを受け取るには、汎用ワイルドカード文字 <? extends T > を使用します。このメソッドで記述された汎用コレクションには add メソッドを使用できません。方法。 ### 。

説明: リンゴを梱包した後、<? extends Fruits > オブジェクトが返されます。このオブジェクトは、 リンゴを含む果物を追加できません。


7. [必須] foreach ループ内の要素に対して削除/追加操作を実行しないでください。要素を削除するには Iterator

メソッドを使用してください。同時に操作する場合は、Iterator オブジェクトをロックする必要があります。

反例:

List<String> a = new ArrayList<String>();
a.add("1");
a.add("2");
for (String temp : a) {
if("1".equals(temp)){
a.remove(temp);
}
}

説明: 上記のコードの実行結果は間違いなくみんなの予想を超えているので、「1」を置き換えてみてください。 「2」になりますが、結果は同じになりますか?

肯定的な例:

Iterator<String> it = a.iterator();
while(it.hasNext()){
String temp = it.next();
if(删除元素的条件){
it.remove();
}
}
8. [必須] JDK バージョン 7 以降では、Comparator は反射性、推移性、対称性を満たす必要があり、それ以外の場合は配列です。 sort、

Collections.sort は IllegalArgumentException 例外を報告します。

説明:

1) 反射性: x と y の比較結果は、y と x の比較結果と逆になります。

2) 推移性: x > y、y > z、そして x > z。

3) 対称性: x = y の場合、x と z の比較結果は y と z の比較結果と同じになります。

反例:

次の例では等価の状況は処理されず、実際の使用では例外が発生する可能性があります:

new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getId() > o2.getId() ? 1 : -1;
}
}
9. [推奨事項] コレクションを初期化するときは、次のようにしてください。コレクションの初期値のサイズを指定します。

注:

ArrayList(int initialCapacity) を使用して ArrayList を初期化してみてください。


10. [推奨] Map クラス コレクション KV を走査するには、keySet ではなく、entrySet を使用します。

説明:

keySet は実際には 2 回走査されます。1 つは Iterator オブジェクトに変換することで、もう 1 つは hashMap から key に対応する値を取得することです。 entrySet は 1 回だけトラバースし、キーと値の両方をエントリに入れるため、より効率的です。 JDK 8の場合は、 Map . foreach メソッドを使用します。

良い例: values() はリスト コレクション オブジェクトである V 値セットを返し、keySet() は Set コレクション オブジェクトである K 値セットを返します。返されるのは、K - V 値の組み合わせのコレクションです。


11. [推奨] 次の表に示すように、Map クラス コレクション K / V に null 値を格納できるかどうかに細心の注意を払ってください。

QQ截图20170211092116.png

反例: HashMap の干渉により、多くの人は ConcurrentHashMap が null 値を配置できると考えています。## を格納するときに NPE 例外がスローされることに注意してください。 #null 値。


12. 【参考】集合の順序(ソート)と安定性(オーダー)をうまく利用し、集合の乱れ(アンソート)を避けるそして、

不安定性(秩序の乱れ)によって引き起こされる悪影響。

説明:

安定性とは、コレクション内の要素の順序が、走査されるたびに確実であることを意味します。順序性とは、走査結果が特定の比較ルール に従って順序どおりに配置されていることを意味します。例: ArrayList は順序付け / 並べ替えなし、HashMap は並べ替えなし / 並べ替えなし、TreeSet は 順序付け / 並べ替えです。


#13. [参考] Set 要素のユニークな特性を利用すると、コレクションの重複をすばやく排除し、List の

contains メソッドの使用を回避できます。重複した操作をトラバース、比較、および削除します。