【Java】配列, リスト(List), 連想配列(Map) の初期化 
2015/12/06 Sun [edit]
今までのサンプルコードにも散々使ってるけど、少し複雑なものになると書くのが結構大変なので、テンプレ用にまとめてみようと思った。調べてみたら意外と使われていない(?)んだよね。ただし、あくまで値をあらかじめセットしておくグローバルな初期化のみでやってみる。ローカルの場合はブロック表記「{~}」が不要なだけで、基本的には同じ。
よく使う例として、リスト(List) と リストを配列化したもの(List[])、連想配列(Map)もついでにやってみよう。
●1次元配列の初期化 : int[]
public class ArrayInitTest {
int[] arr = {1, 2, 3};
public static void main(String[] args) throws Exception {
new ArrayInitTest();
}
public ArrayInitTest() {
for (int v : arr) {
System.out.print(v + " ");
}
}
}
2次元での初期化も同じように書ける。
●2次元配列の初期化 : int[][]
public class ArrayInitTest {
int[][] arr = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9},
};
public static void main(String[] args) throws Exception {
new ArrayInitTest();
}
public ArrayInitTest() {
for (int[] is : arr) {
for (int v : is) {
System.out.print(v + " ");
}
System.out.println();
}
}
}
4 5 6
7 8 9
例をグローバル変数にしたのは、初期化ブロック(「{~}」で囲まれた部分)というものが使えるというのを説明するためだ。もちろんローカル変数なら必要ない。連番とか計算値をあらかじめ入れておくのには良い。内容的には全く同じものになる。
●初期化ブロックを使った、2次元配列の初期化 : int[][]
public class ArrayInitTest {
int[][] arr = new int[3][3];
{
for (int i = 0, p = 1; i < 3; i++) {
for (int j = 0; j < 3; j++) {
arr[i][j] = p++;
}
}
}
public static void main(String[] args) throws Exception {
new ArrayInitTest();
}
public ArrayInitTest() {
for (int[] is : arr) {
for (int v : is) {
System.out.print(v + " ");
}
System.out.println();
}
}
}
4 5 6
7 8 9
静的(static)な変数やメソッドとして使いたい場合は、ブロック自体に「static」を書くと良い(クラス共通となる)。
●静的初期化ブロックを使った、2次元配列の初期化 : static int[][]
public class ArrayInitTest {
static int[][] arr = new int[3][3];
static {
for (int i = 0, p = 1; i < 3; i++) {
for (int j = 0; j < 3; j++) {
arr[i][j] = p++;
}
}
}
public static void main(String[] args) throws Exception {
for (int[] is : arr) {
for (int v : is) {
System.out.print(v + " ");
}
System.out.println();
}
}
}
4 5 6
7 8 9
- - - - - - - - - - - - - - - - - -
■リスト(List) の初期化
次にリスト(List)を初期化してみよう。「{~}」が2重になるが、メソッドを使った初期化もできる。
●リストの初期化 : List<E>
public class ListInitTest {
@SuppressWarnings("serial")
List<Integer> list = new ArrayList<Integer>(){
{
add(1); add(2); add(3);
}
};
public static void main(String[] args) throws Exception {
new ListInitTest();
}
public ListInitTest() {
for (int v : list) {
System.out.print(v + " ");
}
}
}
通常の配列と同じように、初期化ブロックを使って、for ループなどで追加しても良いだろう。「@SuppressWarnings()」は警告を消しているだけなので、無くても動く。
リストの2次元(ネスト)も同じように考えればできる。ちょっと中括弧「{~}」が多くなるが、ある程度まとめてしまえば、それほど難しくはないだろう。
●2次元のリスト(ネスト)の初期化 : List<List<E>>
public class ListInitTest {
@SuppressWarnings("serial")
List<List<Integer>> list = new ArrayList<List<Integer>>(){{
add(new ArrayList<Integer>(){{
add(1); add(2); add(3);
}});
add(new ArrayList<Integer>(){{
add(4); add(5); add(6);
}});
add(new ArrayList<Integer>(){{
add(7); add(8); add(9);
}});
}};
public static void main(String[] args) throws Exception {
new ListInitTest();
}
public ListInitTest() {
for (List<Integer> li : list) {
for (int is : li) {
System.out.print(is + " ");
}
System.out.println();
}
}
}
4 5 6
7 8 9
通常の配列のときのように、連番や計算値などなら初期化ブロックを使うのも良いだろう。
●初期化ブロックを使った、2次元のリスト(ネスト)の初期化 : List<List<E>>
public class ListInitTest {
List<List<Integer>> list = new ArrayList<List<Integer>>();
{
for (int i = 0, p = 1; i < 3; i++) {
list.add(new ArrayList<Integer>());
for (int j = 0; j < 3; j++) {
list.get(i).add(p++);
}
}
}
public static void main(String[] args) throws Exception {
new ListInitTest();
}
public ListInitTest() {
for (List<Integer> li : list) {
for (int is : li) {
System.out.print(is + " ");
}
System.out.println();
}
}
}
4 5 6
7 8 9
リストと配列を絡めることもできる。長さが決まってるなら、通常の配列を使った方が実行速度が速いので、選択肢の1つとして考慮してみるのも良いだろう。構造的には配列の初期化とリストの初期化を混ぜあわせたものになる。隣接リストなどにも向いている気がする。
●配列化されたリストを初期化する : List<E>[]
public class ListInitTest {
@SuppressWarnings({ "rawtypes", "serial" })
List[] list = {
new ArrayList<Integer>(){{
add(1); add(2); add(3);
}},
new ArrayList<Integer>(){{
add(4); add(5); add(6);
}},
new ArrayList<Integer>(){{
add(7); add(8); add(9);
}},
};
public static void main(String[] args) throws Exception {
new ListInitTest();
}
public ListInitTest() {
for (List<Integer> li : list) {
for (int is : li) {
System.out.print(is + " ");
}
System.out.println();
}
}
}
4 5 6
7 8 9
もちろん同じように、初期化ブロックを使っても良い。
●初期化ブロックを使って、配列化されたリストを初期化する : List<E>[]
public class ListInitTest {
@SuppressWarnings("unchecked")
List<Integer>[] list = new List[3];
{
for (int i = 0, p = 1; i < list.length; i++) {
list[i] = new ArrayList<Integer>();
for (int j = 0; j < 3; j++) {
list[i].add(p++);
}
}
}
public static void main(String[] args) throws Exception {
new ListInitTest();
}
public ListInitTest() {
for (List<Integer> li : list) {
for (int is : li) {
System.out.print(is + " ");
}
System.out.println();
}
}
}
4 5 6
7 8 9
- - - - - - - - - - - - - - - - - -
■連想配列(Map) の初期化
ここまで見てれば、もう連想配列(Map)の初期化も想像がつくだろう。クラスで共通に使うなら静的な初期化ブロック「static」にするのも良い。
●連想配列(Map) の初期化 : Map<K, V>
public class MapInitTest {
@SuppressWarnings("serial")
Map<String, Integer> map = new TreeMap<String, Integer>() {
{
put("Candy", 6);
put("Eliza", 9);
put("Becky", 10);
put("Alice", 13);
put("Daisy", 99);
}
};
public static void main(String[] args) throws Exception {
new MapInitTest();
}
public MapInitTest() {
for (Map.Entry<String, Integer> e : map.entrySet()) {
System.out.println(e.getKey() + " = " + e.getValue());
}
}
}
Becky = 10
Candy = 6
Daisy = 99
Eliza = 9
基本的には他のオブジェクトも同じ考え方でできるので、色々やってみると良いだろう。
(関連記事)
【Java】2次元配列のソート
【Java】連想配列(Map)を foreach(for, forEach) で取り出す
【Java】連想配列(Map)を値でソートする
【Java】配列要素の反転(reverse)
【Android】【Java】SparseArray で foreach
- 関連記事
トラックバック
トラックバックURL
→http://fantom1x.blog130.fc2.com/tb.php/196-2b50c3a5
この記事にトラックバックする(FC2ブログユーザー)
| h o m e |