Javaプログラミング思想総括編——第十六章
4022 ワード
第十六章配列
1配列はなぜ特殊なのか
配列と他の種類の容器の違いには、効率、タイプ、基本タイプを保存する能力の3つの面があります.
Javaでは配列が最も効率的なストレージとランダムアクセスオブジェクト参照シーケンスの方法です.
配列は単純な線形シーケンスであり、要素へのアクセスが非常に高速です.しかし、この速度の代価は、配列オブジェクトのサイズが固定され、そのライフサイクルで変更できないことである.
汎用型の出現は容器にもタイプ検査の能力を備えさせ、自動箱詰め機構は容器を配列とほぼそっくりに基本タイプに使用することができ、配列の大きな果実が残っている利点は効率である.
配列が汎用以前のコンテナより優れているのは、ツリーを作成して基本的なタイプを持つことができるためです.これは、コンパイル期間チェックによって、挿入エラータイプと抽出不適切なタイプを防止できることを意味します.
2配列は最初のオブジェクトのセットです
オブジェクト配列は参照を保存し、基本タイプ配列は値を保存します.
配列の宣言には、集計初期化(Aggregation Initialization)メソッドを使用します.
int[] integers = {0, 1, 2, 3, 4};
ただし、宣言時に初期化しない場合は、ダイナミック集計初期化(Dynamic Aggregation Initialization)メソッドを使用する必要があります.
int[] integers;
integers = new int[] {0, 1, 2, 3, 4};
基本タイプ:数値型は0、char型は(char)O、boolean型はfalseに初期化します.
オブジェクトタイプ:nullに初期化されます.
3配列を返す
C++とは異なり、Javaは配列を返すことができます.
4次元配列
Java 1.5に追加されたArrays.deepToString()メソッドは、多次元配列を読み取り可能なStringに変換することができる.
配列内のマトリクスを構成する各ベクトルは、粗い配列と呼ばれる任意の長さを有することができる.
次のようになります.
a[][] = {{{}, {0} }, {{0,0}, {0,0,0}, {0,0,0,0,0}},{{0}} }
自動包装メカニズムは配列初期化器にも機能します.
5配列とパターン
配列と汎用はうまく結合できません.配列は、タイプの安全を強制的に保証するために、正確なタイプを知っていなければならないからです.
汎用パラメータタイプを持つ配列はインスタンス化できません:
Peel[] peels = new Peel[10];//erro
将来的にアップグレードされず、需要が比較的簡単であると判断した場合、汎用配列を作成できます.しかし、汎用コンテナは、常に汎用配列よりも良い選択をします.
6テストデータの作成
Java標準クラスライブラリArraysには、複数の場所を同じ値でしか埋められない、非常に限られたfill()メソッドがあります.オブジェクトに対しては、同じ参照をコピーして埋めたり、配列の領域だけを埋めたりすることができます.
配列を塗りつぶすには、次のようにします.
double[] a = new double[5];
Arrays.fill(a,1.0);
String[] b = new String[7];
Arrays.fill(b,3,5,"Feynman");
7 Arraysユーティリティ
6つの基本機能: equals()比較配列が等しいかどうか fill()パディングデータ sort()ソート binarySearch()ソート配列で を検索 hashCode()生成ハッシュコード List()がList容器 に移行する.
配列のコピー:
Java標準クラスライブラリはstaticメソッドSystemを提供する.arraycopy()は,forループでコピーするよりも配列をコピーする方がずっと速い.
System.arraycopy(Object src, int srcPosition, Object dest, int destPosition, int length);
基本タイプ配列とオブジェクト配列はコピーできます.オブジェクト配列をコピーすると、オブジェクト自体のコピーではなく、オブジェクトの参照のみがコピーされます.これは浅いコピーと呼ばれます.System.arraycopy()は自動パッケージの自動分解を実行しません.2つの配列は同じ正確なタイプでなければなりません.
配列比較:
条件を考えます:要素の個数は等しくて、要素の内容は等しいです.
Arraysクラスは配列全体を比較するための静的equals()法を提供する.配列が等しい条件は,要素の個数が等しくなければならず,対応する位置の要素も等しくなければならないことであり,各要素に対してequals()法を用いて比較する.
Arraysを使うdeepEquals()は多次元配列を比較することができる.
静的手法を用いるsort()用語は配列を並べ替える.
配列要素の比較:
Javaには、比較機能を提供する2つの方法があります.
1.javaを実現する.lang.Comparableインタフェース、そのcomparareTo()メソッドを上書きします.Comparableインタフェースが実装されていない場合、sort()を呼び出すとClassCastException例外が放出されます.
2.クラスのインタフェースを常に変更したり、コードを変更したりすることはできません.より柔軟なのは、比較が必要な場合に、Comparableインタフェースを実現するクラスを作成することです.これはポリシー設計モードの適用例です.このクラスには2つのメソッドcompare()とequals()メソッドがあります.Objectのequals()メソッドから間接的に継承されるため、equals()メソッドを実装する必要はありません.
配列のソート:
Collectionsクラスには、自然なソート順序を反転させることができるreverseOrder()静的メソッドが含まれています.
Stringのソートアルゴリズムは辞書の編成順にソートされるので、大文字の先頭の語はすべて前に置いて、それから小文字です.
一緒に並べ替えたいならString.CASE_INSENSITIVE_ORDER.例えば:Arrays.sort(sa, String.CASE_INSENSITIVE_ORDER);
ソートされた配列で検索:
並べ替えられた配列に対してArraysを使用する.binarySearch()クイック検索は、ソートされた配列でなければ使用できません.
ソートされていない配列に対してbinarySearch()を使用すると、予想外の結果が得られます(要素が見つからない場合を指す場合があります).
配列に検索する値が見つかった場合は、その値が存在する場所のインデックスを返し、見つからない場合は負の値を返します.その計算方法は-(挿入点)-1で、挿入点は要素の数より大きい最初の場所を指します.配列{1,2,4,5}に対して3を検索すると、-2-1=-3を返します.
重複していない要素の配列のソートが必要な場合は、TreeSet(ソート順序を保持)またはLinkedHashSet(挿入順序を保持)を使用します.これらのクラスは、すべての詳細を自動的に処理します.プログラムのパフォーマンスのボトルネックにならない限り、配列を自分で維持する必要はありません.
オブジェクト配列をComparatorで並べ替えた場合、binarySearch()を使用する場合は、同じComparatorを指定する必要があります.
8まとめ
新しいバージョンのJavaを使用する場合、配列ではなくコンテナが好ましい.パフォーマンスが問題になっていることが証明されている場合(配列に切り替えることがパフォーマンスの向上に役立ちます)、プログラムを配列の使用に再構築する必要があります.
1配列はなぜ特殊なのか
配列と他の種類の容器の違いには、効率、タイプ、基本タイプを保存する能力の3つの面があります.
Javaでは配列が最も効率的なストレージとランダムアクセスオブジェクト参照シーケンスの方法です.
配列は単純な線形シーケンスであり、要素へのアクセスが非常に高速です.しかし、この速度の代価は、配列オブジェクトのサイズが固定され、そのライフサイクルで変更できないことである.
汎用型の出現は容器にもタイプ検査の能力を備えさせ、自動箱詰め機構は容器を配列とほぼそっくりに基本タイプに使用することができ、配列の大きな果実が残っている利点は効率である.
配列が汎用以前のコンテナより優れているのは、ツリーを作成して基本的なタイプを持つことができるためです.これは、コンパイル期間チェックによって、挿入エラータイプと抽出不適切なタイプを防止できることを意味します.
2配列は最初のオブジェクトのセットです
オブジェクト配列は参照を保存し、基本タイプ配列は値を保存します.
配列の宣言には、集計初期化(Aggregation Initialization)メソッドを使用します.
int[] integers = {0, 1, 2, 3, 4};
ただし、宣言時に初期化しない場合は、ダイナミック集計初期化(Dynamic Aggregation Initialization)メソッドを使用する必要があります.
int[] integers;
integers = new int[] {0, 1, 2, 3, 4};
基本タイプ:数値型は0、char型は(char)O、boolean型はfalseに初期化します.
オブジェクトタイプ:nullに初期化されます.
3配列を返す
C++とは異なり、Javaは配列を返すことができます.
4次元配列
Java 1.5に追加されたArrays.deepToString()メソッドは、多次元配列を読み取り可能なStringに変換することができる.
配列内のマトリクスを構成する各ベクトルは、粗い配列と呼ばれる任意の長さを有することができる.
次のようになります.
a[][] = {{{}, {0} }, {{0,0}, {0,0,0}, {0,0,0,0,0}},{{0}} }
自動包装メカニズムは配列初期化器にも機能します.
5配列とパターン
配列と汎用はうまく結合できません.配列は、タイプの安全を強制的に保証するために、正確なタイプを知っていなければならないからです.
汎用パラメータタイプを持つ配列はインスタンス化できません:
Peel[] peels = new Peel[10];//erro
将来的にアップグレードされず、需要が比較的簡単であると判断した場合、汎用配列を作成できます.しかし、汎用コンテナは、常に汎用配列よりも良い選択をします.
List[] ls;
List[] la = new List[20];
ls = (List[])la;
ls[0] = new ArrayList();
//erro
//ls[1] = new ArrayList();
Object[] objects = ls;
objects[1] = new ArrayList();
6テストデータの作成
Java標準クラスライブラリArraysには、複数の場所を同じ値でしか埋められない、非常に限られたfill()メソッドがあります.オブジェクトに対しては、同じ参照をコピーして埋めたり、配列の領域だけを埋めたりすることができます.
配列を塗りつぶすには、次のようにします.
double[] a = new double[5];
Arrays.fill(a,1.0);
String[] b = new String[7];
Arrays.fill(b,3,5,"Feynman");
7 Arraysユーティリティ
6つの基本機能:
配列のコピー:
Java標準クラスライブラリはstaticメソッドSystemを提供する.arraycopy()は,forループでコピーするよりも配列をコピーする方がずっと速い.
System.arraycopy(Object src, int srcPosition, Object dest, int destPosition, int length);
基本タイプ配列とオブジェクト配列はコピーできます.オブジェクト配列をコピーすると、オブジェクト自体のコピーではなく、オブジェクトの参照のみがコピーされます.これは浅いコピーと呼ばれます.System.arraycopy()は自動パッケージの自動分解を実行しません.2つの配列は同じ正確なタイプでなければなりません.
配列比較:
条件を考えます:要素の個数は等しくて、要素の内容は等しいです.
Arraysクラスは配列全体を比較するための静的equals()法を提供する.配列が等しい条件は,要素の個数が等しくなければならず,対応する位置の要素も等しくなければならないことであり,各要素に対してequals()法を用いて比較する.
Arraysを使うdeepEquals()は多次元配列を比較することができる.
静的手法を用いるsort()用語は配列を並べ替える.
配列要素の比較:
Javaには、比較機能を提供する2つの方法があります.
1.javaを実現する.lang.Comparableインタフェース、そのcomparareTo()メソッドを上書きします.Comparableインタフェースが実装されていない場合、sort()を呼び出すとClassCastException例外が放出されます.
2.クラスのインタフェースを常に変更したり、コードを変更したりすることはできません.より柔軟なのは、比較が必要な場合に、Comparableインタフェースを実現するクラスを作成することです.これはポリシー設計モードの適用例です.このクラスには2つのメソッドcompare()とequals()メソッドがあります.Objectのequals()メソッドから間接的に継承されるため、equals()メソッドを実装する必要はありません.
配列のソート:
Collectionsクラスには、自然なソート順序を反転させることができるreverseOrder()静的メソッドが含まれています.
Stringのソートアルゴリズムは辞書の編成順にソートされるので、大文字の先頭の語はすべて前に置いて、それから小文字です.
一緒に並べ替えたいならString.CASE_INSENSITIVE_ORDER.例えば:Arrays.sort(sa, String.CASE_INSENSITIVE_ORDER);
ソートされた配列で検索:
並べ替えられた配列に対してArraysを使用する.binarySearch()クイック検索は、ソートされた配列でなければ使用できません.
ソートされていない配列に対してbinarySearch()を使用すると、予想外の結果が得られます(要素が見つからない場合を指す場合があります).
配列に検索する値が見つかった場合は、その値が存在する場所のインデックスを返し、見つからない場合は負の値を返します.その計算方法は-(挿入点)-1で、挿入点は要素の数より大きい最初の場所を指します.配列{1,2,4,5}に対して3を検索すると、-2-1=-3を返します.
重複していない要素の配列のソートが必要な場合は、TreeSet(ソート順序を保持)またはLinkedHashSet(挿入順序を保持)を使用します.これらのクラスは、すべての詳細を自動的に処理します.プログラムのパフォーマンスのボトルネックにならない限り、配列を自分で維持する必要はありません.
オブジェクト配列をComparatorで並べ替えた場合、binarySearch()を使用する場合は、同じComparatorを指定する必要があります.
8まとめ
新しいバージョンのJavaを使用する場合、配列ではなくコンテナが好ましい.パフォーマンスが問題になっていることが証明されている場合(配列に切り替えることがパフォーマンスの向上に役立ちます)、プログラムを配列の使用に再構築する必要があります.