Java 字符串索引超出范围:-5
我在测试runQuery时遇到了一个问题,问题是字符串索引超出范围:-5,我找不到解决方案Java 字符串索引超出范围:-5,java,Java,我在测试runQuery时遇到了一个问题,问题是字符串索引超出范围:-5,我找不到解决方案 @Test void testRunQuery() throws FileNotFoundException, IOException, InterruptedException { final Answer answer = new Answer(); String[] args = new String[5]; final String year = "yyyy ";
@Test
void testRunQuery() throws FileNotFoundException, IOException, InterruptedException {
final Answer answer = new Answer();
String[] args = new String[5];
final String year = "yyyy ";
final String month = "mm ";
final String day = "dd ";
final String limit = "limit ";
args[0] = year.substring(5);
args[1] = month.substring(3);
args[2] = day.substring(3);
args[3] = null;
args[4] = limit.substring(6);
Job result = answer.runQuery(args);
assertNotNull(result);
}
这是我进行查询的runQuery
public Job runQuery(final String[] args) throws InterruptedException {
// Use standard SQL syntax for queries.
// See: https://cloud.google.com/bigquery/sql-reference/
// Variabili per le query
final Integer yyyy=Integer.valueOf(args[ZERO].substring(FIVE)),
mm=Integer.valueOf(args[ONE].substring(THREE)),
dd=Integer.valueOf(args[TWO].substring(THREE)),
limit=Integer.valueOf(args[FOUR].substring(SIX));
final QueryJobConfiguration queryConfig = QueryJobConfiguration.newBuilder(
"SELECT DISTINCT owner_user_id "
+ "FROM `bigquery-public-data.stackoverflow.posts_answers` "
+ "WHERE extract(year from creation_date) = @yyyy "
+ "AND extract(month from creation_date) = @mm "
+ "AND extract(day from creation_date) = @dd "
+ "AND owner_user_id is not null "
+ "AND owner_user_id > 0 "
+ "ORDER BY owner_user_id ASC LIMIT @limit ")
.addNamedParameter("yyyy", QueryParameterValue.int64(yyyy))
.addNamedParameter("mm", QueryParameterValue.int64(mm))
.addNamedParameter("dd", QueryParameterValue.int64(dd))
.addNamedParameter("limit", QueryParameterValue.int64(limit))
.setUseLegacySql(false).build();
// Create a job ID so that we can safely retry.
final JobId jobId = JobId.of(UUID.randomUUID().toString());
Job queryJob=bigquery.create(JobInfo.newBuilder(queryConfig).setJobId(jobId).build());
// Wait for the query to complete.
queryJob = queryJob.waitFor();
// Check for errors
if (queryJob == null) {
throw new RuntimeException("Job no longer exists");
} else if (queryJob.getStatus().getError() != null) {
// You can also look at queryJob.getStatus().getExecutionErrors() for all
// errors, not just the latest one.
throw new RuntimeException(queryJob.getStatus().getError().toString());
}
return queryJob;
}
首先定义一个变量
final String year = "yyyy ";
然后使用子字符串
args[0] = year.substring(5);
args[0]现在是一个空字符串值(args[0]等于“”)
然后您将再次尝试对其进行子串
final Integer yyyy=Integer.valueOf(args[ZERO].substring(FIVE)),
这将不起作用,因为args[0]是空字符串
您应该只在函数内部或调用函数之前使用一次子字符串。您误解了Java的
String.substring
函数的参数
简言之,您似乎认为参数采用子字符串的长度。它并没有——而是指定了“开始索引”——即,在提供的字符串中开始复制的位置
所以当你说:
final String year = "yyyy ";
args[0] = year.substring(5);
实际上,您并没有将args[0]设置为5个字符的字符串。相反,您将其设置为从位置5开始的字符串“yyy”的一部分-换句话说,您将其设置为空字符串
所以当你后来说
final Integer yyyy=Integer.valueOf(args[ZERO].substring(FIVE)),
假设将0设置为0,将5设置为5,这将失败,因为您将args[0]设置为空字符串“”,并且无法从“”获取从位置5开始的子字符串
总之,如果你有
String myString = "smiles";
System.out.println("substring(0, 4) = <" + myString.substring(0, 4) + ">");
System.out.println("substring(2, 4) = <" + myString.substring(2, 4) + ">");
System.out.println("substring(4) = <" + myString.substring(4) + ">");
String myString=“smiles”;
System.out.println(“子字符串(0,4)=”);
System.out.println(“子字符串(2,4)=”);
System.out.println(“子字符串(4)=”);
输出将是:
substring(0, 4) = <smil>
substring(2, 4) = <il>
substring(4) = <es>
子串(0,4)=
子串(2,4)=
子串(4)=
简言之,去掉测试和主代码中的“.substring”调用。
查看规范,显示定义的常量。特别是常数
5
好吧,我发现问题。。。谢谢!
substring(0, 4) = <smil>
substring(2, 4) = <il>
substring(4) = <es>