Java 用于循环中断而不是重复

Java 用于循环中断而不是重复,java,Java,我正在编写代码来创建java模板库。我正在编写一段特定的代码,其中读者将读取模板的文本并拉出占位符(${placeholder})。到目前为止,当Jtesting时,它似乎只使用一个占位符,但当我尝试多个占位符时,代码似乎不会循环并读取模板的其余部分 以我的生命来说,我无法理解为什么代码会失败 我已经调试了代码,我所能看到的是,当它存储第一个占位符时,它没有循环返回,而是退出 代码如下: import java.io.IOException; import java.io.Reader; pu

我正在编写代码来创建java模板库。我正在编写一段特定的代码,其中读者将读取模板的文本并拉出占位符(${placeholder})。到目前为止,当Jtesting时,它似乎只使用一个占位符,但当我尝试多个占位符时,代码似乎不会循环并读取模板的其余部分

以我的生命来说,我无法理解为什么代码会失败

我已经调试了代码,我所能看到的是,当它存储第一个占位符时,它没有循环返回,而是退出

代码如下:

import java.io.IOException;
import java.io.Reader;

public class placeholderFinder {
    private Reader reader;

    public placeholderFinder(Reader reader) {
        this.reader = reader;
    }

    public static final int NORMALTEXT = 0;
    public static final int PLACEHOLDERTEXT = 1;

    private int state = NORMALTEXT;
    private StringBuilder placeholder = new StringBuilder();

    public String nextPlaceholderFinder() throws IOException {
        for (int p = reader.read(); p != -1; p = reader.read()) {
            if (p == '$') {
                if (state == NORMALTEXT) {
                    state = PLACEHOLDERTEXT; 
                    placeholder.append((char) p);
                } 
            } else if (state == PLACEHOLDERTEXT) {
                        placeholder.append((char) p);
                    }

            if (p == '}') {
                    if (state == PLACEHOLDERTEXT) {
                        state = NORMALTEXT;
                        String placeholderStore = placeholder.toString();
                        placeholder.setLength(0);
                        return placeholderStore;

                    }

                }

            }

        return null;

    }

}
还有Jtest

@Test
void testWithPlaceholders() throws IOException {
    Reader reader = new StringReader("a ${name} ${date}");
    placeholderFinder finder = new placeholderFinder(reader);
    String expectedresult = "${name}${date}";
    String actualcode = finder.nextPlaceholderFinder();
    assertEquals(expectedresult, actualcode);

之所以只找到一个占位符(如
${name}
),是因为一旦找到
}
符号,您就会发出返回语句。 在这方面:

return placeholderStore;
尝试将第一个占位符的临时结果放入列表,如下所示:

List<String> results = new ArrayList<String>();
当您阅读了全文(无论其中实际包含什么内容)后,您将返回此结果列表(并更改方法的返回类型)。或者再次加入列表:

String.join("", results);

当前解决方案在找到第一个占位符后返回,您可以将其更改为在返回前遍历
读取器中的所有字符。以下是一个示例:

public String nextPlaceholderFinder() throws IOException {
    for (int p = reader.read(); p != -1; p = reader.read()) {
        if (p == '$') {
            if (state == NORMALTEXT) {
                state = PLACEHOLDERTEXT; 
                placeholder.append((char) p);
            } 
        } else if (state == PLACEHOLDERTEXT) {
            placeholder.append((char) p);
        }
        if (p == '}') {
            if (state == PLACEHOLDERTEXT) {
                state = NORMALTEXT;
            }
        }
    }
    return placeholder.toString();
}

问题是,当在
$
之后遇到
}
时,您从循环返回。您的期望是错误的。请为每个占位符调用此函数一次,而不是为所有占位符调用此函数一次。因此,第一次您将获得${name},第二次您将获得${date}好的……有什么建议吗,因为我还不太熟悉这些java语言。谢谢。我会试一试的
public String nextPlaceholderFinder() throws IOException {
    for (int p = reader.read(); p != -1; p = reader.read()) {
        if (p == '$') {
            if (state == NORMALTEXT) {
                state = PLACEHOLDERTEXT; 
                placeholder.append((char) p);
            } 
        } else if (state == PLACEHOLDERTEXT) {
            placeholder.append((char) p);
        }
        if (p == '}') {
            if (state == PLACEHOLDERTEXT) {
                state = NORMALTEXT;
            }
        }
    }
    return placeholder.toString();
}