为什么我一直收到java.lang.StringIndexOutOfBoundsException

时间:2016-10-15 02:36:14

标签: string loops substring indexoutofboundsexception

我正在尝试编写一个带有字符串的程序,并从中删除另一个字符串的所有实例。例如: <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=true"></script> <script src="https:////cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <div id="map-canvas"></div>会打印("Remove them all!", "em")。但是,当我执行此操作时,它会给我"Rove th all!"

java.lang.StringIndexOutOfBoundsException

2 个答案:

答案 0 :(得分:0)

您的代码似乎有几个问题。首先,您不能使用==来检查字符串相等性,您必须使用String.equals()方法。 Read here

其次,您的for循环从0迭代到oldPhrase.length(),但尝试将此长度值用于索引将导致异常发生。在java中,字符串具有从零开始的索引,因此索引从0开始并以oldPhrase.length()-1结束。

第三,你的逻辑似乎被打破了。 substring(int, int)方法的参数为beginIndexendIndex。所以:

newPhrase = newPhrase + oldPhrase.substring((removal.length() + 2 + i), oldPhrase.length());

oldPhrase 的一部分连结到newPhrase 将按照您的意愿进行操作。

这是我做的方式。这个想法更简单,也更清晰。我已添加评论以明确说明。

Repl.it

上实时测试代码
public static String removeAll(String oldPhrase, String removal) {

    // if removal is not found return the original string
    if(oldPhrase.indexOf(removal) == -1) {
        return oldPhrase;
    }

    int removalLength = removal.length(); // storing the length so as not to call .length() again and again

    for(int i = 0; i < oldPhrase.length(); i++) { // note that <= will cause the exception too
        int idxOfRemoval = oldPhrase.indexOf(removal);

        if(idxOfRemoval == i) { // removal is found at the current index, i.e. at index i
            // take substring from beginning to index of removal +
            // substring from the end of removal to end of original string
            oldPhrase = oldPhrase.substring(0, idxOfRemoval) + oldPhrase.substring(idxOfRemoval+removalLength);
        }
    }
    return(oldPhrase);
}

public static void main(String[] args) {
    System.out.println(removeAll("AaAaAa", "a"));
}

输出:

AAA

答案 1 :(得分:0)

解释java.lang.StringIndexOutOfBoundsException的最简单方法是在你的循环中:

for(int i = 0; i <= oldPhrase.length(); i++){...}

由于i将等于oldPhrase.length(),因此您在获取子字符串时遇到问题:

oldPhrase.substring(i, (removal.length() + i))

所以你最终得到了

oldPhrase.substring(oldPhrase.length(), (removal.length() + oldPhrase.length()))

这是一个问题,因为字符串中的最高索引是length - 1,并且您正试图访问length处的索引。

执行removeAll的强力方法是迭代你的字符串(正如你所做的那样),然后检查i处的每个字符,如果removal从那里开始,那么你想要返回的字符串是

sub(0,i) + removeAll(the rest off your string starting at i+removal.length)

public static String removeAll(String oldPhrase,String removal) {
    int rem = removal.length();
    int n = oldPhrase.length();
    // if length of oldPhrase is shorter than removal
    // then there nothing you need to remove
    if (n < rem) return oldPhrase;

    // iterate over your string
    for (int i = 0; i <= n - rem; i++) {
        int j;
        // check if there is a substring, removal, starting at i
        for (j = 0; j < rem; j++) {
            if (oldPhrase.charAt(i+j) != removal.charAt(j))
                break;
        }
        // if there is...
        if (j == rem) {
            // return stuff before substring you want to remove +
            //        removeAll(the stuff after substring you want to remove)
            return  oldPhrase.substring(0,i) + removeAll(oldPhrase.substring(i+rem,n),removal);
        }
    }
    return oldPhrase;
}

public static void main(String[] args) {
    System.out.println(removeAll("AaAaAa", "a"));
}

输出:

AAA