Java 检查字符串[]中的项目是否出现在流中

Java 检查字符串[]中的项目是否出现在流中,java,Java,我目前正在为我正在创建的语言编写一个解析器,它需要检查流的当前部分是否符合传递数组中的一个项。代码的简短版本为: public abstract class Parser { private StringReader reader; //This is a BufferedReader with rollback //A single string lookahead method public boolean lookahead(String toMatch, boo

我目前正在为我正在创建的语言编写一个解析器,它需要检查流的当前部分是否符合传递数组中的一个项。代码的简短版本为:

public abstract class Parser {
    private StringReader reader; //This is a BufferedReader with rollback

    //A single string lookahead method
    public boolean lookahead(String toMatch, boolean rollback) throws ParseException {
        char c;
        //Mark the current position in the stream, so we can come back to it if needed
        MarkToken currentMark = reader.mark();

        //Iterate through the toMatch and check if each character matches
        for(int i = 0; i < toMatch.length(); ++i) {
            c = reader.nextChar();

            if(toMatch.charAt(i) != c) {
                break;
            }
        }

        //Get the current image
        String got = reader.currentImage(currentMark);

        //If we don't have a match, rollback if necessary and return false
        if(!got.equals(toMatch)) {
            if(rollback) {
                reader.rollBack();
            }

            return false;
        }

        return true;
    }

    //The String[] lookahead method
    public int lookahead(String[] toMatch, boolean rollback) throws ParseException {
        if(toMatch.length == 1) {
            //If there is only one element in toMatch, send it to a cheaper function
            if(lookahead(toMatch[0]))
                return 0;
            else return 1;
        } else {
            int maxLength = toMatch[0].length();
            //We use this variable to keep track of how many valid choices are left
            int choicesLeft = toMatch.length;
            int i, j;
            char current;
            //Mark the current position in the stream, so we can come back to it if needed
            MarkToken mark = s().mark();

            //Get the length of the longest string in toMatch
            for(i = 1; i < toMatch.length; ++i) {
                maxLength = Math.max(maxLength, toMatch[i].length());
            }

            //Go up to the length of the longest string
            for(i = 0; i < maxLength; ++i) {
                //Get the next character from the stream
                current = reader.nextChar();

                //If we've reached the end of the stream:
                if(current == -1 || current == '\uffff') {
                    //Get back a character in the stream
                    reader.rollbackChar();

                    //And check to see if we have a match
                    return ArrayUtils.indexOf(toMatch, reader.currentImage(mark));
                }

                //Go through each item in toMatch
                for(j = 0; j < toMatch.length; ++j) {
                    if(toMatch[j] != null) {
                        //Check to see if the character matches or not
                        if(toMatch[j].charAt(i) != current) {
                            //We null an item in toMatch if it doesn't apply any more
                            toMatch[j] = null;
                            --choicesLeft;
                        }
                    }
                }

                //If we only have one choice left, see if there is a match (will return -1 if not)
                if(choicesLeft == 1) {
                    return ArrayUtils.indexOf(toMatch, reader.currentImage(mark));
                }
            }

            //If there is no 
            if(rollback) {
                reader.rollBackTo(mark);
            }
        }

        return -1;
    }
}
将调用此函数以检查流是否包含某些符号..*$@/''等等,然后贪婪地吃掉它们

我只会一次提供最多10-15个项目的数组,因此从数组中删除项目可能不是最佳优化


有没有更有效的方法,我应该使用的某些方法或循环?

这在很大程度上取决于现在效率低下的方法。如果读卡器速度慢,可以一次比较数组中的所有元素,每次比较一个字符。如果您正在进行数千次检查,并且希望加快检查速度,请将数据从读取器中分块取出,然后检查这些分块。您目前的绩效状况如何?您所需的效率和场景的瓶颈在哪里?如果您不能回答这个问题,那么您还没有准备好提出如何使此代码具有更好的性能的问题?我写了这篇文章后意识到,如果流比任何一个选项都长,那么方法将返回-1。我想你唯一能绕过这个问题的方法就是,如果你到了那个阶段,你会发回最长的比赛吗?我会先让代码工作你有没有让代码正常工作过?