到达阵列中的最后一个索引后返回第一个索引

pch*_*han 9 java arrays

在for循环中的数组到达最后一个索引后,我得到一个异常,说索引超出范围.我想要的是它回到第一个索引,直到z等于ctr.我怎样才能做到这一点?

我的代码:

char res;
int ctr = 10
char[] flames = {'F','L','A','M','E','S'};

for(int z = 0; z < ctr-1; z++){
    res = (flames[z]);
    jLabel1.setText(String.valueOf(res));
}
Run Code Online (Sandbox Code Playgroud)

lui*_*nal 7

您需要使用限于数组大小的索引。更准确地说,更深奥地说,您需要将 for 循环迭代 {0..9} 映射到火焰数组 {0.. flames.length()-1}的有效索引,在这种情况下,它们与{0.. } 相同。 5}。

当循环从 0 迭代到 5 时,映射是微不足道的。当循环迭代第 6 次时,您需要将其映射回数组索引 0,当循环迭代到第 7 次时,将其映射到数组索引 1,依此类推。

== 天真的方法 ==

for(int z = 0, j = 0; z < ctr-1; z++, j++)
{
      if ( j >= flames.length() )
      {
         j = 0; // reset back to the beginning
      }
      res = (flames[j]);
      jLabel1.setText(String.valueOf(res));
}
Run Code Online (Sandbox Code Playgroud)

== 更合适的方式 ==

然后你可以通过实现flames.length()是一个不变量来改进它,你可以将它移出 for 循环。

final int n = flames.length();
for(int z = 0, j = 0; z < ctr-1; z++, j++)
{
      if ( j >= n )
      {
         j = 0; // reset back to the beginning
      }
      res = (flames[j]);
      jLabel1.setText(String.valueOf(res));
}
Run Code Online (Sandbox Code Playgroud)

== 怎么做 ==

现在,如果您注意的话,您会发现我们只是在对索引进行模运算。因此,如果我们使用模块化 (%) 运算符,我们可以简化您的代码:

final int n = flames.length();
for(int z = 0; z < ctr-1; z++)
{
      res = (flames[z % n]);
      jLabel1.setText(String.valueOf(res));
}
Run Code Online (Sandbox Code Playgroud)

在处理此类问题时,请考虑函数映射,从域(在本例中为 for 循环迭代)到范围(有效的数组索引)。

更重要的是,在你开始编码之前就在纸上解决它。这将使您在解决这些基本问题方面走得很远。


Fra*_*kie 6

虽然luis.espinal答案,性能方面,更好,我认为你也应该看看迭代器,因为它们会给你更大的灵活性来回读取.

这意味着你可以很容易写FLAMESFLAMESFLAMESSEMALF,等等.

int ctr = 10;
List<Character> flames = Arrays.asList('F','L','A','M','E','S');
Iterator it = flames.iterator();

for(int z=0; z<ctr-1; z++) {
    if(!it.hasNext()) // if you are at the end of the list reset iterator
        it = flames.iterator();

    System.out.println(it.next().toString()); // use the element
}
Run Code Online (Sandbox Code Playgroud)

出于好奇心做这个循环1M次(平均100个样本的结果)需要:

               using modulo: 51ms
            using iterators: 95ms
using guava cycle iterators: 453ms
Run Code Online (Sandbox Code Playgroud)

编辑: 循环迭代器,因为lbalazscs很好地把它,更优雅.它们付出了代价,番石榴的实施速度慢了4倍.你可以推出自己的实现,很难.

// guava example of cycle iterators
Iterator<Character> iterator = Iterators.cycle(flames);
for (int z = 0; z < ctr - 1; z++) {
    res = iterator.next();
}
Run Code Online (Sandbox Code Playgroud)


san*_*hat 5

您应该使用%强制索引保持在其中,flames.length以便它们生成有效的索引

int len = flames.length;
for(int z = 0; z < ctr-1; z++){
      res = (flames[z % len]);
      jLabel1.setText(String.valueOf(res));
}
Run Code Online (Sandbox Code Playgroud)