Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/svn/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java “理解为什么”;需要数组,但找到字符串";出现错误_Java - Fatal编程技术网

Java “理解为什么”;需要数组,但找到字符串";出现错误

Java “理解为什么”;需要数组,但找到字符串";出现错误,java,Java,在您的类中,很可能有一个名为kgram的字符串字段。在buildModel方法中,有一个局部变量kgram,它是一个字符串数组。但是在getRandomKgram方法中,您没有引用该变量,而是引用了类的kgram字段。在您的代码中,在这一部分的拐角处潜伏着一个潜在的NullPointerException: MarkovModel.java:104: error: array required, but String found return return kgram[kgra

在您的类中,很可能有一个名为
kgram
的字符串字段。在
buildModel
方法中,有一个局部变量
kgram
,它是一个字符串数组。但是在
getRandomKgram
方法中,您没有引用该变量,而是引用了类的
kgram
字段。

在您的代码中,在这一部分的拐角处潜伏着一个潜在的NullPointerException:

MarkovModel.java:104: error: array required, but String found return   
      return kgram[kgramChooser.nextInt(size)];
因为它已经被for循环中的求值表达式覆盖:

if (i < sourceText.length() - K) {
        charAft = sourceText.charAt(i + K);
}
它返回
firstKgram
值,但在方法中:

public String getFirstKgram() {
  return firstKgram;
}
您根本不设置此
firstKgram
值。这是你想要的行为吗

我无法确定getter方法中对kgramChooser数据类型的引用:

private void buildModel(int K, String sourceText) 
因为在提供的代码块中未指定数据类型。如果没有合适的代码供我们查看,猜测kgramChooser.nextInt(size)的功能是不可能的

您可能已经将
buildModel(int K,String sourceText)
方法中的本地数据类型与对象成员字段
String[]kgram
String firstKgram
Random kgramChooser
Random charChooser
混在一起了。如果是这种情况,请删除每行开头的数据类型,以便引用对象成员字段

因此,该代码:

public String getRandomKgram() {
  return kgram[kgramChooser.nextInt(size)];
}
String[] kgram = model.keySet().toArray(new String[0]);
String firstKgram = sourceText.substring(0, K);
Random kgramChooser = new Random();
Random charChooser = new Random();
此代码的更改:

public String getRandomKgram() {
  return kgram[kgramChooser.nextInt(size)];
}
String[] kgram = model.keySet().toArray(new String[0]);
String firstKgram = sourceText.substring(0, K);
Random kgramChooser = new Random();
Random charChooser = new Random();
假设引用的数据类型实际上是对象中的成员字段

更新:

在buildModel()方法中添加额外的空指针检查,如下所示:

kgram = model.keySet().toArray(new String[0]);
firstKgram = sourceText.substring(0, K);
kgramChooser = new Random();
charChooser = new Random();
您不必这样做,但它确实是更好的编程,因为您在构造函数中拥有映射作为对象实际持有的完整概述

还要将私有成员字段
model
从HashMap更改为Map,因为您应该始终针对接口而不是实现进行编程。 因此:

HashMap模型;
变成:

HashMap<String, String> model;
Map模型;
通过阅读Joshua Bloch的一本名为《高效Java,第二版》的好书,您可以提高编码技能

这将使您免于在StackOverflow上的尴尬时刻;)

如果你按照我上面提到的指示去做,你会找到你正在寻找的解决方案

顺便说一句:别忘了投票,选择最适合你问题的答案


祝你好运

至少有三个变量(两个局部变量和一个属性)具有不同的类型,但名称为
kgram
。这是非常令人困惑的。正如@macmoonshine已经说过的,您有几个变量称为
kgram
。这会抛出错误。如果您为每个变量使用唯一的名称,它应该会起作用。您可以将行号作为well@macmoonshine当你引用一个属性时,你指的是什么?正如我所提到的,我在编码方面是个业余爱好者,还没有完全掌握编码本身。你的类的一个字段或实例变量。事实上,我在类中将
kgram
声明为字符串。你的意思是将字符串数组重命名为其他东西来解决这个问题?我添加了完整的代码,谢谢你提供了详细的回答。
private void buildModel(int K, String sourceText) {
  if (sourceText == null) throw new NullPointerException("sourceText parameter is NULL literal");  

  if(K < 0 || sourceText.length() < K) {
     throw new IOException();
  }

  ...
public MarkovModel(int K, File sourceText) {
      model = new HashMap<String, String>();
HashMap<String, String> model;
Map<String, String> model;