プログラミングで文字列操作と同じくらいよく扱うのが、配列やリストの操作です。
複数のデータを管理する配列やリストには、様々な種類があり、用途に応じて使い分けることが重要となります。
本記事では、Javaの配列・リストについて、種類と操作方法をまとめました。
プログラミング初心者の方の学習や、忘れてしまった方の復習として、参考にしていただければ幸いです。
記載しているプログラムは、Java8を使って動作確認をしています。
JavaScriptの配列・リスト操作
配列・リスト操作として、以下の内容をとりあげます。
- 配列・リストの種類
- 配列・リストの作成
- 配列・リストから値を取得する
- 配列・リストの長さ(要素数)を取得する
- 配列・リストに要素を追加する
- 配列・リストから要素を削除する
- 配列・リストをコピーする
- 配列・リストをループさせる
- 配列・リストの順番を入れ替える
- 配列・リスト同士を結合する
- 配列・リストを検索する
配列・リストの種類
複数のデータを管理する配列やリストは、プログラミング言語によって様々なデータ構造がサポートされています。
Javaでは、以下の4種類を扱うことができます。
- 配列:intのプリミティブやStringのオブジェクトを管理する。インデックスは番号で管理される。最初に宣言した長さで固定となる。
- List:Listインタフェースから派生するArrayListやLinkedListなどがある。順番を保持していてインデックスで管理される。
- Map:Mapインタフェースから派生するHashMapやTreeMapなどがある。keyとvalueで管理される。Mapの種類により順序が保証されるものとされないものがある。
- Set:Setインタフェースから派生するHashSetやTreeSetなどがある。重複する要素は持たず、1つとなる。順序は保証しない。
今回は配列に関する操作を中心にまとめていきます。
List、Map、Setについては、各インタフェースが提供する操作を中心にまとめていきます。
配列・リストの作成
配列の作成方法は、変数の宣言時に初期値を指定する方法としない方法があります。
String[] a = {"Hello", "Java"}; System.out.println(Arrays.asList(a)); // -> [Hello, Java]
String[] a2 = new String[2]; a2[0] = "Hello"; a2[1] = "Java"; System.out.println(Arrays.asList(a2)); // -> [Hello, Java]
Listの作成方法は、該当クラスをnewする、Arrays.asListで作成する方法があります。
List l = new ArrayList<>(); System.out.println(l); // -> []
List l2 = Arrays.asList(); System.out.println(l2); // -> []
Mapの作成方法は、該当クラスをnewします。
Map<Integer, String> m = new HashMap<>(); System.out.println(m); // -> {}
Setの作成方法は、該当クラスをnewします。
Set s = new HashSet<>(); System.out.println(s); // -> []
配列・リストから値を取得する
配列から値を取得するには、取得したい要素のインデックスを指定します。
a[0] = "Hello"; a[1] = "Java"; r = a[1]; System.out.println(r); // -> Java
Listから値を取得するには、getに取得したい要素のインデックスを指定します。
l = Arrays.asList("Hello", "Java"); r = l.get(1); System.out.println(r); // -> Java
Mapから値を取得するには、getに取得したいkeyを指定します。
m = new HashMap<>(); m.put(1, "Hello"); m.put(2, "Java"); r = m.get(2); System.out.println(r); // -> Java
Setから直接任意の値は取得できないため、ループで取り出す、Listに変換するなどにより取得します。
配列・リストの長さ(要素数)を取得する
配列の長さを取得するには、lengthを使います。
a[0] = "Hello"; a[1] = "Java"; rn = a.length; System.out.println(rn); // -> 2
Listの長さを取得するには、sizeを使います。
l = Arrays.asList("Hello", "Java"); rn = l.size(); System.out.println(rn); // -> 2
Mapの長さを取得するには、sizeを使います。
m = new HashMap<>(); m.put(1, "Hello"); m.put(2, "Java"); rn = m.size(); System.out.println(rn); // -> 2
Setの長さを取得するには、sizeを使います。
s = new HashSet<>(); s.add("Hello"); s.add("Java"); rn = s.size(); System.out.println(rn); // -> 2
配列・リストに要素を追加する
配列は作成時に長さが固定となるため、そのまま追加することはできません。
新たな要素を加えるためには、別の配列を作成する必要があります。
Listに要素を追加するには、addを使います。
第1引数にインデックスを指定すると、任意の場所に追加することができます。
l = new ArrayList<>(); l.add("Hello"); l.add("Java"); System.out.println(l); // -> [Hello, Java]
Mapに要素を追加するには、putを使います。
m = new HashMap<>(); m.put(1, "Hello"); m.put(2, "Java"); System.out.println(m); // -> {1=Hello, 2=Java}
Setに要素を追加するには、addを使います。
s = new HashSet<>(); s.add("Hello"); s.add("Java"); System.out.println(s); // -> [Java, Hello]
配列・リストから要素を削除する
配列は作成時に長さが固定となるため、削除することはできません。
Listから要素を削除するには、removeを使います。
インデックスを指定しても良いし、値を指定しても削除できます。
removeAllでは指定したコレクションに含まれる要素を削除します。
l = new ArrayList<>(); l.add("Hello"); l.add("Java"); l.remove(0); System.out.println(l); // -> [Java]
Mapから要素を削除するには、removeを使います。
keyのみ指定する方法と、keyとvalueの両方を指定する方法があります。
m = new HashMap<>(); m.put(1, "Hello"); m.put(2, "Java"); m.remove(1); System.out.println(m); // -> {2=Java}
Setから要素を削除するには、removeを使います。
removeAllでは指定したコレクションに含まれる要素を削除します。
s = new HashSet<>(); s.add("Hello"); s.add("Java"); s.remove("Hello"); System.out.println(s); // -> [Java]
配列・リストをコピーする
配列をコピーするには、System.arraycopyを使います。
a[0] = "Hello"; a[1] = "Java"; String[] ra = new String[a.length]; System.arraycopy(a, 0, ra, 0, a.length); System.out.println(Arrays.asList(ra)); // -> [Hello, Java]
Listをコピーするには、コンストラクタの引数に指定します。
この方法によるコピーは浅いコピーになります。
l = new ArrayList<>(); l.add("Hello"); l.add("Java"); List rl = new ArrayList<>(l); System.out.println(rl); // -> [Hello, Java]
Mapをコピーするには、コンストラクタの引数に指定します。
m = new HashMap<>(); m.put(1, "Hello"); m.put(2, "Java"); Map<Integer, String> rm = new HashMap<>(m); System.out.println(rm); // -> {1=Hello, 2=Java}
Setをコピーするには、コンストラクタの引数に指定します。
s = new HashSet<>(); s.add("Hello"); s.add("Java"); Set rs = new HashSet<>(s); System.out.println(rs); // -> [Java, Hello]
配列・リストをループさせる
配列をループさせるには、拡張for文を使います。
a[0] = "Hello"; a[1] = "Java"; for (String item : a) { System.out.println(item); // -> Hello -> Java }
Listをループさせるには、拡張for文とforEachを使う方法があります。
l = new ArrayList<>(); l.add("Hello"); l.add("Java"); for (String item : l) { System.out.println(item); // -> Hello -> Java }
l = new ArrayList<>(); l.add("Hello"); l.add("Java"); l.forEach(item -> { System.out.println(item); // -> Hello -> Java });
Mapをループさせるには、拡張for文とforEachを使う方法があります。
m = new HashMap<>(); m.put(1, "Hello"); m.put(2, "Java"); for (Map.Entry<Integer, String> entry : m.entrySet()) { System.out.println(entry.getKey() + " " + entry.getValue()); // -> 1 Hello -> 2 Java }
m = new HashMap<>(); m.put(1, "Hello"); m.put(2, "Java"); m.forEach((key, value) -> { System.out.println(key + " " + value); // -> 1 Hello -> 2 Java });
Setをループさせるには、iteratorとforEachを使う方法があります。
s = new HashSet<>(); s.add("Hello"); s.add("Java"); Iterator iterator = s.iterator(); while(iterator.hasNext()) { System.out.println(iterator.next()); // -> Java -> Hello }
s = new HashSet<>(); s.add("Hello"); s.add("Java"); s.forEach(item -> { System.out.println(item); // -> Java -> Hello });
配列・リストの順番を入れ替える
配列の要素をソートするには、Arrays.sortを使います。
a[0] = "Java"; a[1] = "Hello"; Arrays.sort(a); System.out.println(Arrays.asList(a)); // -> [Hello, Java]
Listの要素をソートするには、Collections.sortを使う方法と、独自のComparatorを実装する方法があります。
l = new ArrayList<>(); l.add("Java"); l.add("Hello"); Collections.sort(l); System.out.println(l); // -> [Hello, Java]
配列・リスト同士を結合する
配列の結合は、System.arraycopyを使う方法と、Streamを使う方法があります。
a[0] = "Java"; a[1] = "Hello"; String[] aa = {"A", "B", "C"}; ra = new String[a.length + aa.length]; System.arraycopy(a, 0, ra, 0, a.length); System.arraycopy(aa, 0, ra, a.length, aa.length); System.out.println(Arrays.asList(ra)); // -> [Java, Hello, A, B, C]
a[0] = "Java"; a[1] = "Hello"; String[] aaa = {"A", "B", "C"}; Stream stream = Stream.concat(Arrays.stream(a), Arrays.stream(aaa)); String[] raa = stream.toArray(String[]::new); System.out.println(Arrays.asList(raa)); // -> [Java, Hello, A, B, C]
Listの結合は、addAllを使います。
l = new ArrayList<>(); l.add("Java"); l.add("Hello"); List ll = new ArrayList<>(); ll.add("A"); ll.add("B"); ll.add("C"); l.addAll(ll); System.out.println(l); // -> [Java, Hello, A, B, C]
Mapの結合は、putAllを使います。
m = new HashMap<>(); m.put(1, "Hello"); m.put(2, "Java"); Map<Integer, String> mm = new HashMap<>(); mm.put(3, "A"); mm.put(4, "B"); mm.put(5, "C"); m.putAll(mm); System.out.println(m); // -> {1=Hello, 2=Java, 3=A, 4=B, 5=C}
Setの結合は、addAllを使います。
s = new HashSet<>(); s.add("Hello"); s.add("Java"); Set ss = new HashSet<>(); ss.add("A"); ss.add("B"); ss.add("C"); s.addAll(ss); System.out.println(s); // -> [Java, A, B, C, Hello]
配列・リストを検索する
配列から特定の値を検索するには、一旦Listに変換後containsを使います。
a[0] = "Java"; a[1] = "Hello"; rb = Arrays.asList(a).contains("Java"); System.out.println(rb); // -> true
Listから特定の値を検索するには、containsを使う方法とindexOfを使う方法があります。
l = new ArrayList<>(); l.add("Java"); l.add("Hello"); rn = l.indexOf("Java"); System.out.println(rn); // -> 0
Mapのkeyから特定の値を検索するには、containsKeyを使います。
Mapのvalueから特定の値を検索するには、containsValueを使います。
m = new HashMap<>(); m.put(1, "Hello"); m.put(2, "Java"); rb = m.containsKey(1); System.out.println(rb); // -> true rb = m.containsValue("Java"); System.out.println(rb); // -> true
Setから特定の値を検索するには、containsを使います。
s = new HashSet<>(); s.add("Hello"); s.add("Java"); rb = s.contains("Java"); System.out.println(rb); // -> true
配列・リストの操作はやりたい処理によって使うメソッドを変えよう
配列やリストの操作には、同じ結果を得られる方法が、処理を組み合わせることによって何通りもあります。
ですが、特にループの場合には、処理の仕方によってはパフォーマンスが悪いこともあります。
どんなメソッドを使うのかは、やりたい処理によって適宜変えられるように、日頃からたくさん引出しを持っておくことをおすすめします。
今回は、Javaの配列・リスト操作についてまとめました。
参考になれば幸いです。
コメント