Javaのコレクション「List」とは?便利な使い方も紹介!
Listとは?
ざっくりいうと、順番通りに並べられるデータのことです。
「ラーメン屋に並ぶ人の列」的なイメージです。
並ぶときは最後尾から並ぶ、途中で抜けたら順番を詰められる、
呼ばれるときは名前は知らないので、次の方とか何番目の方とかで呼ばれたり、
だいたいそんな感じです。
まぁかたくるしく言うと、順番で管理された重複可能なコレクションです。
もう何語ですか?って感じですね。
配列との違い
Listに似たようなものとして、「配列」というのがあります。
配列とListの違いは、配列は入れれる数が決められていて、
Listは何個でも入れれるという違いです。
さらにListに関しては、非常に便利な機能がいっぱい搭載されています。
そのため配列でやろうとすると、面倒くさい処理を一発でできたりもします。
じゃ配列のメリットなくね?
となりますが、もちろん配列は配列でメリットがあるので、
どちらかが劣っていてどちらかが優れているというよりは
時と場合によってどちらのほうが向いているか
ということを考えないといけないです。
Listの種類
さっきからList、Listと言ってますが、
実はListとはあくまで入れ物のようなもの(インターフェース)なだけで、
実際に動作する実物は以下の二種類あります。
ArrayList
- 中身を見に行くスピードが速い
- 中身を追加したり削除するスピードが遅い
LinkedList
- 中身を見に行くスピードが遅い
- 中身を追加したり削除するスピードが速い
使い分け
中身を変更することが多い場合はLinkedListを使用し、
それ以外は基本的にArrayListを使用しておけば、だいたいは最適化されるはずです。
正直LinkedListの知名度が低いので、どちらか迷うようなら
可読性も上がるので、ArrayListを使用しておいたほうがいいと思います。
宣言する型について
一般的に下記のような宣言を見ることが多いかと思います。
List<String> 変数名 = new ArrayList<>();
このように、Listの中に実物を入れていることが多いと思います。
ただ同じ型に入れることももちろん可能です。
ArrayList<String> 変数名 = new ArrayList<>();
どう違うのかと言うと、使える機能が違います。
細かくいえば他にも違いはありますが、基本的にはListのインターフェースに格納し、
必要に応じてインターフェースに無い機能を使いたい時だけArrayList等を使用するイメージで大丈夫だと思います。
そのため以下は全てListに格納しております。
基本的な使い方
まずListの中身のことは「要素」と呼びます。
そしてややこしいですが、インデックス(管理番号のようなもの)は0から数えます。
なので、1番目(最初)が0、2番目が1、のようになります。
初期化する
Listオブジェクトを初期化(生成)します。
基本的に引数は指定しなくてもいいですが、「初期容量」を指定できます。
何かというと、オブジェクト生成時にまず、初期容量分の保存領域を確保します。
そして要素を追加していく中で、初期容量の負荷係数個に到達すると、保存領域を拡張します。
この要領を拡張するという動作が非常に重たい動作になるので、できる限り最適に設定していきたいので、
最初からある程度量が分かっているのであれば、指定してあげるとパフォーマンスがよくなります。
import java.util.ArrayList;
import java.util.List;
public class ListTest {
public static void main(String[] args) {
// インスタンスを生成
List<String> nameList1 = new ArrayList<>();
// 初期容量100のインスタンスを生成
List<String> nameList2 = new ArrayList<>(100);
}
}
要素を追加する
佐藤・鈴木のように、通常は最後に要素を追加しますが、
田中のように追加する場所を指定すれば、任意の位置に要素を追加できます。
引数に「1」を指定すれば2番目の位置に追加し、
すでにあった2番目の要素以降はすべて1つ後ろにずれます。
import java.util.ArrayList;
import java.util.List;
public class ListTest {
public static void main(String[] args) {
// インスタンスを生成
List<String> nameList = new ArrayList<>();
// 最後尾に追加 [佐藤]
nameList.add("佐藤");
// 最後尾に追加 [佐藤, 鈴木]
nameList.add("鈴木");
// 2番目に割り込み [佐藤, 田中, 鈴木]
nameList.add(1, "田中");
}
}
要素を削除する
インデックスを指定して削除をするか、
要素を指定して削除を行います。
削除した要素以降の要素は、詰めるように1つ手前にずれます。
import java.util.ArrayList;
import java.util.List;
public class ListTest {
public static void main(String[] args) {
// インスタンスを生成
List<String> nameList = new ArrayList<>();
// 最後尾に追加 [佐藤]
nameList.add("佐藤");
// 最後尾に追加 [佐藤, 鈴木]
nameList.add("鈴木");
// 2番目に割り込み [佐藤, 田中, 鈴木]
nameList.add(1, "田中");
// 1番目を削除 [田中, 鈴木]
nameList.remove(0);
// 「鈴木」を削除 [田中]
nameList.remove("鈴木");
}
}
要素を取得する
インデックスを指定して、要素を取得します。
import java.util.ArrayList;
import java.util.List;
public class ListTest {
public static void main(String[] args) {
// インスタンスを生成
List<String> nameList = new ArrayList<>();
// 最後尾に追加 [佐藤]
nameList.add("佐藤");
// 最後尾に追加 [佐藤, 鈴木]
nameList.add("鈴木");
// 1番目の要素を取得 > 佐藤
nameList.get(0);
// 2番目の要素を取得 > 鈴木
nameList.get(1);
}
}
要素を変更する
インデックスを指定して、すでにある要素を変更します。
import java.util.ArrayList;
import java.util.List;
public class ListTest {
public static void main(String[] args) {
// インスタンスを生成
List<String> nameList = new ArrayList<>();
// 最後尾に追加 [佐藤]
nameList.add("佐藤");
// 最後尾に追加 [佐藤, 鈴木]
nameList.add("鈴木");
// 1番目を田中に変更 [田中, 鈴木]
nameList.set(0, "田中");
}
}
要素の数を取得する
List内の要素の数を取得します。
取得できる数は人間が数える数字と同じなので、
1個、2個と数えるやり方と同じです。
そのため、要素数を使ってインデックスを指定するのであれば
-1しないといけません。
import java.util.ArrayList;
import java.util.List;
public class ListTest {
public static void main(String[] args) {
// インスタンスを生成
List<String> nameList = new ArrayList<>();
// 中身の数を取得 > 0
nameList.size();
// 最後尾に追加 [佐藤]
nameList.add("佐藤");
// 中身の数を取得 > 1
nameList.size();
// 最後尾に追加 [佐藤, 鈴木]
nameList.add("鈴木");
// 中身の数を取得 > 2
nameList.size();
}
}
要素があるか判定する
Listに要素があるかどうかを判定します。
ただし完全一致しないと存在しないと判定されます。
例だと「佐藤」に「藤」は含まれてはいますが、
完全一致はしないので、containsはfalseを返します。
import java.util.ArrayList;
import java.util.List;
public class ListTest {
public static void main(String[] args) {
// インスタンスを生成
List<String> nameList = new ArrayList<>();
// 最後尾に追加 [佐藤]
nameList.add("佐藤");
// 最後尾に追加 [佐藤, 鈴木]
nameList.add("鈴木");
// 中身に存在するかを判定
if (nameList.contains("佐藤")) {
// 今回は存在するのでtrue
}
if (!nameList.contains("藤")) {
// 今回は完全一致しないのでtrue
}
}
}
便利な使い方
あいまい(Like)検索をする
上のほうで基本的な使い方で紹介した「contains」は、
完全一致しか検索ができません。
そのため一部だけ一致しないようなものを検索したければ、
独自で検索するしかありません。
Listの中身を1つ1つ確認していって、
検索したいものが含まれているかどうかを見ています。
ちなみに「indexOf」のように、含まれているかどうかの処理は、
変数の型によったり、やり方が異なる可能性があるのでご注意ください。
import java.util.ArrayList;
import java.util.List;
public class ListTest {
public static void main(String[] args) {
// インスタンスを生成
List<String> nameList = new ArrayList<>();
// 最後尾に追加 [佐藤]
nameList.add("佐藤");
// 最後尾に追加 [佐藤, 鈴木]
nameList.add("鈴木");
// List内をすべてループ
for (String name : nameList) {
// 「木」という文字が入っていればtrue
if (name.indexOf("木") != -1) {
// 文字が入っているので出力 > 鈴木
System.out.println(name);
}
}
}
}
並び替え(ソート)する
昇順や降順で並び替えるには、
「Collections」の「sort」機能を使います。
並び替えたいListだけ指定して使うと昇順になり、
さらに「reverseOrder」を指定すると降順に並び替えます。
今回はわかりやすいように数字で行いましたが、
文字列でも並び替えることはできます。
アルファベット、ひらがな、カタカナは、
おそらく想定する順番になるかと思いますが、
注意すべきは漢字です。
並び替える基準が文字コード順に並び替えられているのです。
文字コードが何かわからないと思いますが、
文字一つ一つに管理番号みたいなのが振り分けられていて、
その順番で並び替えられるので、
漢字に関しては順番がぐちゃぐちゃになるかと思います。
日本語でもひらがなやカタカナがうまくいくのは、
文字コードが順番通りになっているからです。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ListTest {
public static void main(String[] args) {
// インスタンスを生成
List<Integer> nameList = new ArrayList<>();
// 最後尾に追加 [2]
nameList.add(2);
// 最後尾に追加 [2, 1]
nameList.add(1);
// 最後尾に追加 [2, 1, 3]
nameList.add(3);
// 昇順で並び替え [1, 2, 3]
Collections.sort(nameList);
// 降順で並び替え [3, 2, 1]
Collections.sort(nameList, Collections.reverseOrder());
}
}
奇数・偶数番ごとに処理を分ける
ループ回数によって、奇数番目と偶数番目を判定して、
処理を分けるようなことをしています。
またややこしいですが、インデックスは0からなので、
人間が数える奇数番目が、インデックスでいう偶数になります。
ループ回数を2で割って、余りが0なら偶数という判定です。
交互に処理を変えたいときとかに使用します。
import java.util.ArrayList;
import java.util.List;
public class ListTest {
public static void main(String[] args) {
// インスタンスを生成
List<String> nameList = new ArrayList<>();
// 最後尾に追加 [佐藤]
nameList.add("佐藤");
// 最後尾に追加 [佐藤, 鈴木]
nameList.add("鈴木");
// List内をすべてループ
for (int i = 0; i < nameList.size(); i++) {
// 偶数か奇数かを判定
if (i % 2 == 0) {
// 奇数個目を出力 佐藤
System.out.println(nameList.get(i));
} else {
// 偶数個目を出力 鈴木
System.out.println(nameList.get(i));
}
}
}
}
まとめ
Javaのコレクションの「List」の紹介でした。
Listに限らずにJavaのコレクションを使いこなせれば、
楽に処理を実装できますし、わかりやすく書けますので、WinWinです。
使いこなせれば世界が変わるといっても過言ではないと思います!
以上、ここまで見ていただきありがとうございます。
皆さまの快適な開発ライフに、ほんの少しでもお役に立てれば幸いです。