コンテナ・フレームワーク図:
Collection
Set インタフェース: Collection のサブインタフェース >> Unordered non-repeatable HashSet: Set インタフェースの実装クラス
リスト・インターフェース:Collection のサブインターフェース >> ordered repeatable
ArrayList:Lisインタフェースの実装クラスtは、効率的なクエリです LinkedList:効率的な追加と削除するListインタフェースの実装クラス Vector:スレッドセーフListインタフェースの実装クラス
Map
HashMap: Map インターフェース実装クラス
Collection< E >インターフェース共通メソッド
以下のメソッドは、一般に2つのコンテナ間の操作に使用されます。ただし、1つのコンテナを使用して、それ自身との交点、マージ、差分などを実行することも可能ですが、通常は必要ありません。注意:2つのコンテナのデータ型は同じでなければなりません。
コードクイズは以下の通りです:
import java.util.ArrayList;
import java.util.Collection;
public class TestCollection {
public static void main(String[] args) {
Collection<String> coll = new ArrayList<>();
coll.add("1");
coll.add("2");
coll.add("3");
System.out.println(coll);//[1, 2, 3]
coll.clear();
System.out.println(coll);//[]
coll.add("A");
coll.add("B");
coll.add("C");
coll.add("DE");
System.out.println(coll);//[A, B, C, DE]
// coll.remove(2);//この意味は、配列の添え字2要素を削除するのではなく、整数2を削除することである
coll.remove("DE");
System.out.println(coll);//[A, B, C]
int a = coll.size();
System.out.println(a);//3
boolean b = coll.isEmpty();
System.out.println(b);//false
boolean c = coll.contains("A");
System.out.println(c);//true
Object[] d = coll.toArray();
System.out.println(d);//[Ljava.lang.Object;@15db9742
System.out.println("=========================================");
Collection<String> coll02 = new ArrayList<>();
coll02.add("B");
coll02.add("C");
coll02.add("D");
System.out.println("coll:"+coll);//coll:[A, B, C]
System.out.println("coll02:"+coll02);//coll02:[B, C, D]
boolean e = coll.containsAll(coll02);
System.out.println(e);//false
coll.retainAll(coll02);
System.out.println(coll);//[B, C]
coll.addAll(coll02);
System.out.println(coll);//[B, C, B, C, D]
coll.removeAll(coll02);
System.out.println(coll);//[]
}
}
List< E >インターフェース共通メソッド
コードクイズは以下の通りです:
import java.util.ArrayList;
import java.util.List;
/**
* Listインターフェースのメソッドは、添え字を追加する。
*/
public class TestList {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
System.out.println(list);//[1, 2, 3, 4, 5]
list.add(1,11);
System.out.println(list);//[1, 11, 2, 3, 4, 5]
// list.remove(11);//ここでは、要素の内容としての11ではなく、演算の添え字としての11がデフォルトとなる
list.remove(1);
System.out.println(list);//[1, 2, 3, 4, 5]
list.set(0,11);
System.out.println(list);//[11, 2, 3, 4, 5]
int a = list.get(0);
System.out.println(a);//11
list.add(5);
list.add(4);
list.add(3);
list.add(2);
list.add(11);
int b = list.indexOf(11);
System.out.println(b);//0
int c = list.lastIndexOf(11);
System.out.println(c);//9
List<Integer> list02 = new ArrayList<>();
list02.add(12);
list02.add(14);
list02.add(16);
list.addAll(1,list02);
System.out.println(list);//[11, 12, 14, 16, 2, 3, 4, 5, 5, 4, 3, 2, 11]
}
}
CollectionインターフェイスのremoveメソッドとListインターフェイスのremoveメソッドを区別してください。
import java.util.ArrayList;
import java.util.List;
/**
* CollectionインターフェイスのremoveメソッドとListインターフェイスのremoveメソッドを区別する
*
*/
public class TestRemove {
public static void main(String[] args) {
List<String> list01 = new ArrayList<>();
list01.add("1");
list01.add("2");
list01.add("3");
list01.add("4");
list01.add("5");
System.out.println(list01);//[1, 2, 3, 4, 5]
//removeメソッドの親インターフェースCollection
list01.remove("1");
System.out.println(list01);//[2, 3, 4, 5]
//Listインターフェース removeメソッド
list01.remove(1);
System.out.println(list01);//[2, 4, 5]
System.out.println("=========================================");
List<Integer> list02 = new ArrayList<>();
list02.add(1);
list02.add(2);
list02.add(3);
list02.add(4);
list02.add(5);
list02.add(11);
list02.remove(1);
System.out.println(list02);//[1, 3, 4, 5, 11]
/**
* java.lang.IndexOutOfBoundsException: Index: 11, Size: 5
*/
list02.remove(11);//int型ではデフォルトで添え字インデックスを参照するため、これは以下のような表が範囲外の例外を報告する。
}
}
練習1:ArrayListの手書きシミュレーションで配列を作成し、関数に要素を追加します:
/**
* 手書きのArrayListでコンテナを作成し、要素を追加する関数
* ジェネリックを追加する
*/
public class WriteArrayList<E> {
private Object[] array;
private int size;//配列の添え字
private static final int DEFAULT = 10;
public WriteArrayList() {
array = new Object[DEFAULT];
}
public WriteArrayList(int index) {
array = new Object[index];
}
public void add(E data) {
array[size++] = data;
}
@Override
public String toString() {
// [a,b,c]フォーマット出力
StringBuilder sb = new StringBuilder();
sb.append("[");
for(int i=0; i<size; i++) {
sb.append(array[i]+",");
}
sb.setCharAt(sb.length()-1,']');//最終出力のカンマ「,」を「,」に置き換える。]'記号、コード中の一重引用符を二重引用符に変更することはできない
return sb.toString();
}
public static void main(String[] args) {
WriteArrayList<Integer> wal = new WriteArrayList<>();
wal.add(11);
wal.add(12);
wal.add(13);
System.out.println(wal);
}
}
演習2:演習1に配列展開を追加
/**
* 配列の拡張を増やす
*/
public class WriteArrayList<E> {
private static Object[] array;
private int size;//配列の添え字
private static final int DEFAULT = 10;
public WriteArrayList() {
array = new Object[DEFAULT];
}
public WriteArrayList(int index) {
array = new Object[index];
}
public void add(E data) {
//いつ拡張するか?
if(size==array.length) {
//どのように拡張するのか?
Object[] newArray = new Object[array.length+(array.length>>1)];//アナロジー10+10/2,ここでは、プラス記号'+'よりも優先順位が高い。>>'
System.arraycopy(array, 0, newArray, 0, array.length);
array = newArray;
}
array[size++] = data;
}
@Override
public String toString() {
// [a,b,c]フォーマット出力
StringBuilder sb = new StringBuilder();
sb.append("[");
for(int i=0; i<size; i++) {
sb.append(array[i]+",");
}
sb.setCharAt(sb.length()-1,']');//最終出力のカンマ「,」を「,」に置き換える。]'記号、コード中の一重引用符を二重引用符に変更することはできない
return sb.toString();
}
public static void main(String[] args) {
WriteArrayList<Integer> wal = new WriteArrayList<>();
for(int i=0; i<40; i++) {
wal.add(i);
}
System.out.println(wal);
}
}
演習3:演習2にset()メソッドとget()メソッドを追加し、配列の境界検出を追加します。
/**
* setメソッドを追加する
* 配列の境界チェックを追加する
*/
public class WriteArrayList<E> {
private static Object[] array;
private int size;//配列の添え字
private static final int DEFAULT = 10;
public WriteArrayList() {
array = new Object[DEFAULT];
}
public WriteArrayList(int index) {
//判定を追加する
if(index<0) {
throw new RuntimeException("コンテナの容量を負にすることはできない: "+index);
} else if(index==0) {
array = new Object[DEFAULT];
} else {
array = new Object[index];
}
}
public void add(E data) {
//いつ拡張するか?
if(size==array.length) {
//どのように拡張するのか?
Object[] newArray = new Object[array.length+(array.length>>1)];//アナロジー10+10/2,ここでは、プラス記号'+'よりも優先順位が高い。>>'
System.arraycopy(array, 0, newArray, 0, array.length);
array = newArray;
}
array[size++] = data;
}
@Override
public String toString() {
// [a,b,c]フォーマット出力
StringBuilder sb = new StringBuilder();
sb.append("[");
for(int i=0; i<size; i++) {
sb.append(array[i]+",");
}
sb.setCharAt(sb.length()-1,']');//最終出力のカンマ「,」を「,」に置き換える。]'記号、コード中の一重引用符を二重引用符に変更することはできない
return sb.toString();
}
public E get(int index) {
checkIndex(index);
return (E)array[index];
}
public void set(int index, E data) {
checkIndex(index);
// //インデックスの法的判断、インデックス間隔は[0,size)
// if(index<0||index>size-1) {
// //不正、手動で例外をスローする
// throw new RuntimeException("インデックスは合法ではない:"+index);
// }
array[index] = data;
}
/**
* 多くの場所で、インデックスindexが合法かどうかを判断する必要があるため,
* というわけで、ここに独立したメソッドを書いて、必要なときに直接呼び出そう。
*/
public void checkIndex(int index) {
//インデックスの法的判断、インデックス間隔は[0,size)
if(index<0||index>size-1) {
//不正、手動で例外をスローする
throw new RuntimeException("インデックスは合法ではない:"+index);
}
}
public static void main(String[] args) {
WriteArrayList<Integer> wal = new WriteArrayList<>();
for(int i=0; i<40; i++) {
wal.add(i);
}
System.out.println(wal.get(10));
wal.set(1,100);
System.out.println(wal);
}
}
練習問題 4: 練習問題 3 に remove()、size()、isEmpty() メソッドの実装を追加します。
/**
* 種類のremove()実装メソッドを追加する
* sizeメソッドを追加する
*/
public class WriteArrayList<E> {
private static Object[] array;
private int size;//配列の添え字
private static final int DEFAULT = 10;
public WriteArrayList() {
array = new Object[DEFAULT];
}
public WriteArrayList(int index) {
//判定を追加する
if(index<0) {
throw new RuntimeException("コンテナの容量を負にすることはできない: "+index);
} else if(index==0) {
array = new Object[DEFAULT];
} else {
array = new Object[index];
}
}
public void add(E data) {
//いつ拡張するか?
if(size==array.length) {
//どのように拡張するのか?
Object[] newArray = new Object[array.length+(array.length>>1)];//アナロジー10+10/2,ここでは、プラス記号'+'よりも優先順位が高い。>>'
System.arraycopy(array, 0, newArray, 0, array.length);
array = newArray;
}
array[size++] = data;
}
@Override
public String toString() {
// [a,b,c]フォーマット出力
StringBuilder sb = new StringBuilder();
sb.append("[");
for(int i=0; i<size; i++) {
sb.append(array[i]+",");
}
sb.setCharAt(sb.length()-1,']');//最終出力のカンマ「,」を「,」に置き換える。]'記号、コード中の一重引用符を二重引用符に変更することはできない
return sb.toString();
}
public E get(int index) {
checkIndex(index);
return (E)array[index];
}
public void set(int index, E data) {
checkIndex(index);
// //インデックスの法的判断、インデックス間隔は[0,size)
// if(index<0||index>size-1) {
// //不正、手動で例外をスローする
// throw new RuntimeException("インデックスは合法ではない:"+index);
// }
array[index] = data;
}
/**
* 多くの場所で、インデックスindexが合法かどうかを判断する必要があるため,
* というわけで、ここに独立したメソッドを書いて、必要なときに直接呼び出そう。
*/
public void checkIndex(int index) {
//インデックスの法的判断、インデックス間隔は[0,size)
if(index<0||index>size-1) {
//不正、手動で例外をスローする
throw new RuntimeException("インデックスは合法ではない:"+index);
}
}
public void remove(int index) {
//移動が必要な配列の要素数
int numMoved = array.length - index - 1;
if(numMoved>0) {
//根本原理:配列のコピー
System.arraycopy(array, index+1, array, index, numMoved);
}
array[--size] = null;
}
public void remove(E data) {
for(int i=0; i<size; i++) {
if(array[i].equals(data)) {
remove(i);
}
}
}
public int size() {
return size;
}
public boolean isEmpty() {
return size==0?true:false;
}
public static void main(String[] args) {
WriteArrayList<Integer> wal = new WriteArrayList<>();
for(int i=0; i<40; i++) {
wal.add(i);
}
System.out.println(wal.get(10));
wal.set(1,100);
System.out.println(wal);
wal.remove(2);
System.out.println(wal);
WriteArrayList<String> s = new WriteArrayList<String>();
s.add("A");
s.add("B");
s.add("C");
s.add("D");
System.out.println(s);
s.remove(1);
System.out.println(s);
s.remove("D");
System.out.println(s);
System.out.println(s.size());
System.out.println(s.isEmpty());
}
}
StringBuilderクラスを学習し、それはappend()、setCharAt()メソッドマスターarraycopy()メソッドを提供しています:System.arraycopy(コピーする配列、コピーする最初の要素から、どの配列にコピーするには、どの位置に貼り付け、コピーする要素の数の合計);独自のArrayList実装クラスのスタンドアロン書き換え
演習1~4 テークアウェイ
以下のコードは私が独自に完成させたもので、練習問題4のコードとの本質的な違いは、sizeとarray.length固有の代表的な意味です。以下の私のコードは、sizeはコンテナ内の要素数を表し、array.lengthはコンテナのサイズを表します。配列の拡張により、コンテナのサイズは一般的に要素数よりも大きくなります。とequalsの違いに注意してください。
public class WriteArrayList02<E> {
private Object[] array;
private int size;
private static final int DEFAULT = 10;
public WriteArrayList02() {
array = new Object[DEFAULT];
}
public WriteArrayList02(int index) {
if(index == 0) {
array = new Object[DEFAULT];
}else if(index<0) {
throw new RuntimeException("インデックスを負にすることはできない: "+index);
}else {
array = new Object[index];
}
}
public void add(E element) {
if(size==array.length) {
Object[] newArray = new Object[array.length+(array.length>>1)];
System.arraycopy(array, 0, newArray, 0, array.length);
array = newArray;
}
array[size++] = element;
}
public void set(int index, E element) {
checkIndex(index);
array[index] = element;
}
public E get(int index) {
checkIndex(index);
return (E)array[index];
}
public void checkIndex(int index) {
if(index<0||index>=size) {
throw new RuntimeException("インデックスの例外:"+index);
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
for(int i=0; i<size; i++) {
sb.append(array[i]+",");
}
sb.setCharAt(sb.length()-1,']');
return sb.toString();
}
public void remove(E element) {
for(int i=0; i<size; i++) {
if(array[i].equals(element)) {
remove(i);
}
}
}
public void remove(int index) {
System.out.println(array.length);
//1,2,3,4,5,6,7
int numCopy = size - index - 1;
if(numCopy<0) {
throw new RuntimeException("インデックスの例外:"+index);
}else if(numCopy==0) {
array[size] = null;
}else {
System.arraycopy(array, index+1, array, index, numCopy);
}
//array[size-1] = null;
size--;
System.out.println(array.length);
}
public int size() {
return size;
}
public boolean isEmpty() {
return size==0?true:false;
}
public static void main(String[] args) {
WriteArrayList02<String> wal = new WriteArrayList02<>();
for(int i=0; i<40; i++) {
wal.add(i+"");
}
System.out.println(wal);
wal.set(1,"11");
System.out.println(wal);
System.out.println(wal.get(39));
wal.set(39,"12");
System.out.println(wal);
wal.remove(0);
System.out.println(wal);
// wal.remove(38);
// System.out.println(wal);
wal.remove("12");
System.out.println(wal);
System.out.println(wal.size());
System.out.println(wal.isEmpty());
}
}




