【Javaお勉強日記】リストとセットとマップの取り扱い方を勉強する
ArrayListって配列でしょって思っていたわたしへ。
ちがいます。
わたしより。
リストとセットとマップと配列
「配列」が、ごく一般的な配列。
int[] a = new int[5];
a[0] = 10;
a[1] = 11;
...
System.out.println(a[0]); // 10
みたいに使うやつ。先に型と要素数を決めておかないといけない、VBAの配列に近い感じ。ただし、要素数の再定義は出来ない。
要素数の再定義出来ないと、不便!!
というときに登場するのが、可変長であるリスト。
リストは、配列のように同じ要素を重複して格納できて、格納順も保存される。で、要素を追加すると自動的に拡張してくれる。
ただし「List」自体はインターフェイスなので、Listそのもののインスタンスを作ることはできない。そこで、Listインターフェイスを実装した、ArrayListクラスを使う。
ArrayList<String> testList;
で宣言する。このとき必ず、<>を使って値の型を宣言する必要があるので注意。(指定しなくてもエラーにはならないけど、古い仕様なので必ず宣言する習慣を付ける)あと、java.util.Listのインポートが必要。
他に、
要素の重複が出来ないSet
キーと値をペアで格納できるMap
がある。これらもインターフェイスで、使えるクラスはそれぞれ
HashSet→要素が重複出来ない・要素の並び順が不定
HashMap→キーと値のペアで格納できるが、並び順は不定
SetとMapはHashが基本でListだけArrayなのがわかりにくいけど、覚える。
さらにオプションで、格納順が保存されるLinkedシリーズ
LinkedList→要素の挿入・削除の効率のいいList実装クラス
LinkdHashSet→重複不可だが、格納順が保存される
LinkdHashMap→格納した順番で取り出せるMap
並べ替えに便利なTreeシリーズ
TreeMap→キーでソートした状態で取り出せるMap
TreeSet→重複不可で、ソートした状態で取り出せる
がある。
それぞれ、List同士、Set同士、Map同士なら同じインターフェイスを実装しているので、
List<String> listTest = new ArrayList<>();
みたいに、インターフェイス型でインスタンスを作っておくと、後々の取り回しが楽。
ちなみに、 new ArrayList<>(); の <>部分は、本来型指定をするんだけど、そこはコンパイラが自動でやってくれるから空欄で大丈夫。
自作クラスのオブジェクトをリストに追加したい
自作クラスのオブジェクトもリストに追加出来る。
例えば、Memberクラスを作っておいて、
List<Member> memberList = new ArrayList<>();
ってするだけでMember型のListを作ることが出来る。
んだけど、このままだと比較とか同一性の確認が出来ないので、List、Set、Mapに格納したいオブジェクトは equals() と hashCode() をオーバーライドしないといけない。(ただ複数のオブジェクトをまとめて格納したいだけなら、オーバーライドしなくても動くには動く)
オーバーライドの方法はこんな感じ
public class Member {
private int id;
private String name;
// コンストラクタとgetter略
@Override
public int hashCode(){
// 一意になる値を返す
return this.id;
}
@Override
public boolean equals(Object obj){
if(this == obj){
// this == obj で、それぞれに入っている参照先を比べられる。
// 参照先が同一なら同一のインスタンスなので同一オブジェクト。
return true;
}
if(obj == null){
// 渡されたobjがnullだったら同一であるはずがないのでfalse。
return false;
}
if(this.getClass() != obj.getClass()){
// 違うクラスのインスタンスだったら同じであるはずがないのでfalse。
return false;
}
// 同じクラスのインスタンスなのは確認済みなので、自クラスにキャストできる
Member other = (Member) obj;
// 「この値が同じなら同じものとして扱う」フィールドを比較する
// 例えばここでは個人ID
if(this.id != other.getId()){
// 違ったらfalse
return false;
}
// ここまで全てをくぐり抜けてきたらtrue。
return true;
}
}
hashCode()はオブジェクトごとに一意になる値を返せばいい。自動生成とかで作ると、素数の倍数作ってこねくり回したりするけど、一意になるint値持ってるならそれを返せば良い。
あと、ソート機能を使いたい場合、Comparableインターフェイスを実装して、compareTo()メソッドをオーバーライドする必要がある。必要になったらやり方調べる。
ArrayListを宣言して値を追加して取り出す流れ
List<Member> memberList = new ArrayList<>();
Member member1 = new Member(1, "田中太郎");
memberList.add(member1);
System.out.println(memberList.get(0).getId());
インスタンスを作る際の、 new ArrayList<>(); のカッコの順番と、値にアクセスしたい時に、list[n]じゃなくてlist.get(n)で取る事に気をつければ、後はそんなに難しくない。
Setもadd()で要素を追加できる。
Mapの場合は、addじゃなくてput(key,val)を使う。
この記事が気に入ったらサポートをしてみませんか?