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)我希望在a(包括)和b(不包括)之间得到一个子串。但是,如果我打印,line我会在执行子字符串操作之前得到整个字符串。奇怪的是,如果我查看调试器(Eclipse),那么字符串的值是子字符串,但字符数组包含整个字符串。

例如,如果:

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对象是不可变的,编译器可以自由地共享底层数据。当您执行 asubstring()时,您将创建一个新的 String 引用对象,该对象指向原始字符串数组,但具有不同的起始偏移量和长度。

至于第一个例子,打印出的值,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"}


仅供参考,您所说的“数组”是一个使用数组的 ,但不是java“数组” ArrayList

于 2012-07-15T19:10:58.907 回答