ここから本文です

[Java]構造体クラスの中でArrayListを使いたい

yat********さん

2013/12/1323:57:03

[Java]構造体クラスの中でArrayListを使いたい

こんにちは。
Javaでプログラミングをしてます。
Javaは構造体がないので、代わりにクラスで構造体っぽいものを作成してデータを扱いたいと考えています。
(以下、適切ではないですが簡単のためこのデータ構造を構造体と呼びます)
その中(構造体クラスの中)でArrayListを使用したいと思っています。

構造体クラスのクラス名をKozoとして、メインクラスの中で
public static Kozo[] A = new Kozo[10];
という感じで10個の構造体を定義しています。
(A[0] = new Kozo();という形で、全構造体の初期化も行っています)
また、Kozoクラスの中では
public static ArrayList<Integer> B = new ArrayList<Integer>();
という感じで、ArrayListを定義しています。

問題は、たとえば構造体Kozo[0]のリストBに1,2を入れ
Kozo[1]のリストBには3,4だけを入れたつもりだったのに、実際は10個の構造体すべてのリストの中身が
1,2,3,4になってしまうのです。リストの中身が全構造体で共有されているイメージです。
リストではないもの(String型のものなど)は各構造体できちんと別々の中身を入れることが出来ているのですが、
ArrayListの時だけうまくいきません。
ArrayListの時だけ、全ての構造体が同じアドレスを指して1つの構造体を扱っているような動きになるのです。
どこが原因として考えられるでしょうか?初期化などはこれで大丈夫だと思ったのですが・・・。
そもそも構造体クラスでArrayListを使ったのがまずいのでしょうか。
(何度か確認しましたが、データを追加する部分にバグはないと思います。)

ソースが貼れないので分かりにくくて恐縮ですが、考えうる原因を教えてください。。

閲覧数:
2,022
回答数:
2
お礼:
25枚

違反報告

ベストアンサーに選ばれた回答

プロフィール画像

カテゴリマスター

cd6********さん

2013/12/1402:22:30

ArrayList の修飾子に static が付いているからです。
static 修飾子はクラスのインスタンスすべてに共有されますから。

質問した人からのコメント

2013/12/14 09:17:53

驚く おふたりともありがとうございました!!大正解です。。
ArrayListだけstaticで、うまく行っていた変数はprivateにしていました。
修飾子の重要さがよく分からずインスタンスすべてに共有されることも恥ずかしながらあまり理解していませんでした。よく調べてみます。
お二人のアドバイス両方勉強になりましたが、回答の早かった方を選ばせていただきます。keicha_hrsさん簡単なソースも付けて丁寧に説明頂きありがとうございました。

ベストアンサー以外の回答

1〜1件/1件中

プロフィール画像

カテゴリマスター

kei********さん

2013/12/1403:39:27

要するにこういうことしてるってことでしょうか。簡易的に配列の要素数は2つにしていますが。

public class Main {
public static void main(String[] args) {

Kozo[] C = new Kozo[2];
C[0] = new Kozo();
C[1] = new Kozo();

C[0].B.add(12);
C[1].B.add(34);
Kozo.B.add(56);

System.out.printf("%d,%d,%d\n", Kozo.B.get(0), Kozo.B.get(1), Kozo.B.get(2));
System.out.printf("%d,%d,%d\n", C[0].B.get(0), C[0].B.get(1), C[0].B.get(2));
System.out.printf("%d,%d,%d\n", C[1].B.get(0), C[1].B.get(1), C[1].B.get(2));
}
}

class Kozo {
public static ArrayList<Integer> B = new ArrayList<Integer>();
}

これを実行するとどうなるでしょう。3行すべて「12,34,56」と表示されます。

クラスで直接宣言した変数をフィールドと言い、それにstaticを付けたものをstaticフィールドとか言ったりします(いろいろ言い方があるけど)。staticフィールドはインスタンスとは関係なくクラスに結び付けられる変数となります。ですから、そのクラスを何個インスタンス化したところで、Bの実体は唯一無二です。

ですから、上のコードで

C[0].B.add(12);
C[1].B.add(34);
Kozo.B.add(56);

とかやっていますが、これらでアクセスしている対象は実は全部同じです。だから「10個の構造体すべてのリストの中身が全て同じ」になってしまうのは当然の結果なわけです。C[0].B.add(12)とかやるのは本来は反則なので(エラーではないが)、あくまで例として。

staticを付けないフィールドはインスタンスフィールドとなり、インスタンスが保持する値となります。結論としてはインスタンスフィールドにすればいいってことですね。

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる