0

少し奇妙な問題が発生しました。文字列の基本的な解析を行うための次のコードがあります。

    for (int i = 0; i < lines.size(); i++) {
        String line = lines.get(i);

        //get time
        int firstWhiteSpace = line.indexOf(" ");
        String time = line.substring(0, firstWhiteSpace);

//problem is here vvvv
            line = line.substring(firstWhiteSpace + 1, line.length());
//problem is here ^^^^

        //get client
        int firstColon = line.indexOf(":");
        String client = line.substring(0, firstColon);
        line = line.substring(firstColon + 1, line.length());

        ChatMessage chatMessage = new ChatMessage();
        chatMessage.setTime(time);
        chatMessage.setClient(client);
        chatMessage.setMessage(line);

        messages.add(chatMessage);
    }

したがって、基本的には、 (包括的)と(排他的)line = line.substring(a, b)の間に行のサブストリングを取得することを期待します。ただし、印刷すると、部分文字列操作を実行する前に文字列全体を取得します。不思議なことに、デバッガー(Eclipse)を見ると、文字列の値は部分文字列ですが、文字配列には文字列全体が含まれています。abline

たとえば、次の場合:

line = "Hello World"

そして私はします:

line = line.substring(0, 5);

その場合、lineの値は次のようになります。

"Hello"

ただし、文字配列は次のとおりです。

[H, e, l, l, o, , W, o, r, l, d]

したがって、私は少し混乱しています。ばかげて愚かなことを見逃してしまったらお詫びします。これはかなり可能です。

完全なコード、それほど複雑ではないクラス:

パブリッククラスChatParser{プライベート静的TS3ParserSettings設定;

public static void main(String[] args) {
    ChatParser.setSettings("C:/Users/*****/javaWorkspace/TS3Parser/src/data/settings.txt");
    ChatParser.parseChat();
}

public static void parseChat() {
    ArrayList<String> lines = TextParser.parseTextLines(settings.getSetting("chatLogPath"));
    ArrayList<ChatMessage> messages = new ArrayList<ChatMessage>();

    for (int i = 0; i < lines.size(); i++) {
        String line = lines.get(i);

        //get time
        int firstWhiteSpace = line.indexOf(" ");
        String time = line.substring(0, firstWhiteSpace);
        line = line.substring(firstWhiteSpace + 1, line.length());

        //get client
        int firstColon = line.indexOf(":");
        String client = line.substring(0, firstColon);
        line = line.substring(firstColon + 1, line.length());

        ChatMessage chatMessage = new ChatMessage();
        chatMessage.setTime(time);
        chatMessage.setClient(client);
        chatMessage.setMessage(line);

        messages.add(chatMessage);
    }

    for (int i = 0; i < messages.size(); i++) {
        System.out.println("TIME = " + messages.get(i).getTime() + " CLIENT = " + messages.get(i).getClient() + " MESSAGE = " + messages.get(i).getMessage());
    }
}

public static void setSettings(String path) {
    settings = SettingsParser.parseSettings(path);
}
}
4

2 に答える 2

1

Stringオブジェクトは不変であるため、コンパイラは基礎となるデータを自由に共有できます。を実行するsubstring()と、元の文字列配列を指す新しい文字列参照オブジェクトが作成されますが、開始オフセットと長さが異なります。

最初の例については、 の値を出力するfirstWhiteSpaceと、すべてが明らかになると思います。

于 2012-07-15T18:47:31.327 に答える
0

問題は不変性とは関係ありません。オブジェクトのコレクション/配列がある場合、オブジェクトへの参照を保持するローカル変数の値を変更しても、コレクション/配列には影響しません。

このコードは次のことを示しています。

ArrayList<String> strings = Arrays.asList("foo", "bar");
String localVar = strings.get(0); // "foo"
localVar = "hello"; // this only affects localVar
// strings is still {"foo", "bar"}


参考までに、「配列」と呼ばれるものは、配列ArrayList使用する ですが、Java の「配列」ではありません。

于 2012-07-15T19:10:58.907 に答える