2

次のコードに問題があります。

まず第一に、私は内部クラスを持っています:

public class TraceMessage{
        private String messageType;
        private String tracedIdentifier;
        private List<String> content;



        TraceMessage(){
            content = new ArrayList<String>();
            messageType="";
            tracedIdentifier="";
        }

        TraceMessage(String messageType, String identifier ,List<String> content){
            this.messageType = messageType;
            this.tracedIdentifier = identifier;   
            this.content = content;
        }

3 属性のゲッターとセッターがあります。私の問題は次のとおりです。

このメッセージのリストがあります:

private List<TraceMessage> messages = new ArrayList<TraceMessage>();

そして、私はこれに新しい要素を追加しようとしています:

messages.add(new TraceMessage(temp.messageType,temp.tracedIdentifier,temp.content));

ここで、temp は TraceMessage オブジェクトです。

そのため、そのようなメッセージ型オブジェクトをリストに追加すると、値は問題なく、コンストラクターに出力しても、適切な値が表示されます。しかし後でそのリストを使用しようとすると、リストのすべての要素が同じ内容(最後のもの)になります。何が問題なのですか?

メッセージを追加する完全な部分は次のとおりです。

String fileName="tracefile.MTR";
        BufferedReader br = new BufferedReader(new FileReader(fileName));
        try {   
            String line;
            TraceMessage temp = new TraceMessage();
            while ((line=br.readLine()) != null) {
                if(line.contains("MSCi")){
                     temp.content.clear();
                     temp.content.add(line);
                }
                else if(line.contains("CALL PHASE")){
                     temp.messageType = line.substring(60);
                     temp.content.add(line);
                }

                else if(line.contains("CALL ID")){
                     temp.tracedIdentifier = line.substring(22);
                     temp.content.add(line);
                }
                else if(line.contains("END OF REPORT")){
                    temp.content.add(line); 
                    messages.add(new TraceMessage(temp.messageType,temp.tracedIdentifier,temp.content));          
                }
                else{
                    temp.content.add(line);
                }


            }   

        } finally {
            br.close();



        } 
4

3 に答える 3

0

リストのコピーを取得するように2番目のコンストラクターを書き直します

TraceMessage(String messageType, String identifier ,List<String> content){
    this.messageType = messageType;
    this.tracedIdentifier = identifier;   
    this.content = new ArrayList<String>(content);
}

これにより、ループtemp.contentで再利用していることがコピーされます。whileインスタンスは、クラス外で実行されるコンテンツ コレクションに対する操作から保護されます。

于 2013-07-02T06:57:11.057 に答える
0

コードを次のように変更します。

...
try {   
    String line;

    List<String> content = new ArrayList<String>();
    String messageType = "";
    String tracedIdentifier = "";

    while ((line=br.readLine()) != null) {
        if (line.contains("MSCi")){
            content.clear();
            content.add(line);
        }
        else if (line.contains("CALL PHASE")) {
            messageType = line.substring(60);
            content.add(line);
        }
        else if (line.contains("CALL ID")) {
            tracedIdentifier = line.substring(22);
            content.add(line);
        }
        else if (line.contains("END OF REPORT")) {
            content.add(line); 
            messages.add(new TraceMessage(messageType, tracedIdentifier, content);          
        }
        else {
            content.add(line);
        }
    }   
} finally {
    br.close();
}

オブジェクトを使用する代わりに、temp(while ループの外で) 外部変数に属性を保存し、それらの変数を使用して新しいオブジェクトをmessagesリストに追加します。

于 2013-07-02T07:17:21.287 に答える
0

TraceMessage temp = new TraceMessage(); while ループの中に入れる

変更するmessages.add(new TraceMessage(temp.messageType,temp.tracedIdentifier,temp.content));

messages.add(temp);

それができなくてもOK

messages.add(new TraceMessage(temp.messageType,temp.tracedIdentifier,temp.content)); と 置き換えますmessages.add(temp); messages = new TraceMessage();

于 2013-07-02T07:01:11.913 に答える