我有一个字符串
statdata = "Health 433 (+78) Attack damage 52.3 (+3.9) Health regen. 6.95 (+0.5) Attack speed 0.64 (+3.7%) Mana 230 (+70) Armor 18 (+3.2) Mana regen. 6.9 (+0.6) Magic res. 30 (+0) Range 150 (Melee) Mov. speed 350";
我正在使用子字符串和indexOf从字符串中提取数据并将其解析为双精度数。这是我的班级:
package Engine;
import WebScraper.getWikiStats;
public class MathParse {
public static double returnStat;
public static int indexh;
public static String statdata;
public static getWikiStats getStats = new getWikiStats();
public double stringToDouble(String s){
s.replaceAll("[^\\d.]", ""); //Remove all characters that aren't a number or a decimal
double d = Integer.parseInt(s);
return d;
}
public double parseStatData(String stat, String champion){
statdata = "Health 433 (+78) Attack damage 52.3 (+3.9) Health regen. 6.95 (+0.5) Attack speed 0.64 (+3.7%) Mana 230 (+70) Armor 18 (+3.2) Mana regen. 6.9 (+0.6) Magic res. 30 (+0) Range 150 (Melee) Mov. speed 350";
System.out.println(statdata);
if(stat.equalsIgnoreCase("health")){
returnStat = stringToDouble(statdata.substring(statdata.indexOf("Health") + 7, 3));
}else if(stat.equalsIgnoreCase("healthpl")){
returnStat = stringToDouble(statdata.substring(statdata.indexOf("Health") + 10, 3));
}else if(stat.equalsIgnoreCase("mana")){
returnStat = stringToDouble(statdata.substring(statdata.indexOf("Mana") + 5, 3));
}else if(stat.equalsIgnoreCase("manapl")){
returnStat = stringToDouble(statdata.substring(statdata.indexOf("Mana") + 8, 2));
}else if(stat.equalsIgnoreCase("healthr")){
returnStat = stringToDouble(statdata.substring(statdata.indexOf("Health regen.") + 14, 4));
}else if(stat.equalsIgnoreCase("healthrpl")){
returnStat = stringToDouble(statdata.substring(statdata.indexOf("Health regen.") + 18, 10));
}else if(stat.equalsIgnoreCase("manar")){
returnStat = stringToDouble(statdata.substring(statdata.indexOf("Mana regen.") + 12, 4));
}else if(stat.equalsIgnoreCase("manarpl")){
returnStat = stringToDouble(statdata.substring(statdata.indexOf("Mana regen.") + 16, 10));
}else if(stat.equalsIgnoreCase("range")){
returnStat = stringToDouble(statdata.substring(statdata.indexOf("Range") + 6, 3));
}else if(stat.equalsIgnoreCase("ad")){
returnStat = stringToDouble(statdata.substring(statdata.indexOf("Attack damage") + 14, 5));
}else if(stat.equalsIgnoreCase("adpl")){
returnStat = stringToDouble(statdata.substring(statdata.indexOf("Attack damage") + 19, 8));
}else if(stat.equalsIgnoreCase("as")){
returnStat = stringToDouble(statdata.substring(statdata.indexOf("Attack speed") + 13, 5));
}else if(stat.equalsIgnoreCase("aspl")){
returnStat = stringToDouble(statdata.substring(statdata.indexOf("Attack speed") + 19, 4));
}else if(stat.equalsIgnoreCase("armor")){
returnStat = stringToDouble(statdata.substring(statdata.indexOf("Armor") + 6, 4));
}else if(stat.equalsIgnoreCase("armorpl")){
returnStat = stringToDouble(statdata.substring(statdata.indexOf("Armor") + 11, 5));
}else if(stat.equalsIgnoreCase("mr")){
returnStat = stringToDouble(statdata.substring(statdata.indexOf("Magic res.") + 11, 4));
}else if(stat.equalsIgnoreCase("mrpl")){
returnStat = stringToDouble(statdata.substring(statdata.indexOf("Magic res.") + 16, 5));
}else if(stat.equalsIgnoreCase("ms")){
returnStat = stringToDouble(statdata.substring(statdata.indexOf("Mov. Speed") + 11, 3));
}else{
returnStat = 0;
}
return returnStat;
}
}
以下是我使用parseStatData方法时遇到的错误:
"main" java.lang.StringIndexOutOfBoundsException: String index out of range: -4
at java.lang.String.substring(Unknown Source)
at Engine.MathParse.parseStatData(MathParse.java:18)
at Champions.champTemplate.showStats(champTemplate.java:27)
at Main.TheoryCrafting.theoryLoop(TheoryCrafting.java:29)
at Main.MainClass.checkCommand(MainClass.java:32)
at Main.MainClass.start(MainClass.java:22)
at Main.MainClass.main(MainClass.java:10)
我不知道出了什么问题,我真的很感激帮助。
答案 0 :(得分:1)
String#substring()意味着抛出IndexOutOfBoundsException
。
实际上,子字符串打算采用最低的起始索引,并且一直向上但不包括您提供的最高索引值。它的范围为[a,b)。
如果是> b,那么你会选择一个非常奇怪的范围 - 而且Java选择在这种情况下出错。
罪魁祸首 [可能全部]是您的substring
陈述:
statdata.substring(statdata.indexOf("Health") + 7, 3);
除非"Health"
的索引为负数,否则您将始终超越此子字符串的范围。
或许您想要反转订单:
statdata.substring(3, statdata.indexOf("Health") + 7);
...虽然,这可能是解决更大问题的绷带解决方案 - 您试图用子串解析一个巨大的字符串,并且从长远来看这是不可维护的。 / p>
两个解决方案 - 一个天真,一个稍微好于天真 - 使用String[]
或Map<String, String>
来保存您的数据。
这是使用Map的解决方案:
Map<String, String> statData = new HashMap<>();
statData.put("Health", "433 (+78)");
statData.put("Attack damage", "52.3 (+3.9)");
// and so forth