为什么我不能在java for-each循环中使用现有变量?

时间:2016-03-04 13:51:01

标签: java for-loop foreach

我猜测它不起作用,因为在语法中第一个参数必须具有声明的类型。但是,如果我在一个带有参数的函数中使用for-each循环,就像我在这个例子中那样呢?变量p有一个声明的类型,我只想重用它。

public void addItem(Product p) {
  // ensure that we don't add any nulls to the item list
  if (p != null ) {
    int i = 0;

    for (p : items.keySet()) {
      i++;
    }

    items.put( p , i);
  }
}

有一个相关的问题,Java for loop syntax: "for (T obj : objects)"。那个询问for-each语法意味着什么。我知道这意味着什么,我只想重用一个现有的变量,而不是必须声明一个新变量。

3 个答案:

答案 0 :(得分:6)

Java语言规范(JLS)要求您为迭代器声明一个局部变量。

即。你需要

for (Product p : items.keySet()){

你不能从外部范围借用 p。摆脱困境的一个方法是使用像

这样的东西
for (Product inner_p : items.keySet()){`
    p = inner_p;
    /* continue as before*/

但是这绕过了JLS的意图,所以将代码重构为更优雅的形式可能会更好。

答案 1 :(得分:1)

您需要在其名称之前添加迭代对象的类型(集合的参数化类型)。

查看文档here(感谢Tom)。

所以:for([type] p : items.keySet())

例如,如果Map的密钥属于您的自定义类型Product

for(Product p : items.keySet())

此外,您可以省去迭代,并在此实例中将i设置为items.keySet().size()

答案 2 :(得分:1)

我想稍微重新构建代码,以演示您的预期语法可能意味着什么。换句话说,下面的代码在功能上等同于你的代码所做的,是否有可能这样说。

public void addItem(Product p) {
  // ensure that we don't add any nulls to the item list
  if (p != null ) {
    int i = 0;
    Product theProductIWantToInsert = p;

    for (Product p1 : items.keySet()) {
      theProductIWantToInsert = p1;
      i++;
    }

    items.put( theProductIWantToInsert, i);
  }
}

如果您可以按照建议重复使用p,那么它将逐一采用items中的所有值。在for循环结束时,p将保留Product列表中已存在的最后items的值,而不是您传入的值addItem() p方法。 for循环之后p for循环在items循环之前保持items值的唯一时间是addItem为空时。

最终,您在Product中只有0或1个值。在您第一次调用addItem()之前,您有0,那么您将永远拥有1,并且1将是您传递给imageView.setImageBitmap(bitmapArray.get(0)); 的第一个lapply()

完全不同于其他答案中表达的观点,JLS只是不允许这样做,我希望您了解您的代码执行您似乎想要做的事情的含义。这会很糟糕。