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

时间:2013-09-10 17:35:31

标签: 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));
}

5 个答案:

答案 0 :(得分:6)

尽管luis.espinal回答,但性能方面更好,我认为您还应该查看Iterator's ,因为它们会为您提供更大的灵活性来回读 - 和 - 类推。

这意味着您可以轻松地将FLAMESFLAMES写为FLAMESSEMALF等等......

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
}

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

               using modulo: 51ms
            using iterators: 95ms
using guava cycle iterators: 453ms

修改 循环迭代器,正如lbalazscs很好地说,它更优雅。它们付出了代价,番石榴的实施速度慢了4倍。你可以推行自己的实施,很难。

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

答案 1 :(得分:5)

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

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

答案 2 :(得分:4)

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

当循环从0迭代到5时,映射很简单。当循环迭代第6次时,你需要将它映射回数组索引0,当它迭代到第7次时,你将它映射到数组索引1,依此类推。

==NaïveWay==

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));
}

==更合适的方式==

然后你可以通过实现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));
}

==如何做==

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

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

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

更重要的是,在开始编码之前先在纸上进行处理。这将为您解决这些类型的基本问题带来很长的路要走。

答案 3 :(得分:2)

您可以尝试以下方法: -

char res;
int ctr = 10
char[] flames = {'F','L','A','M','E','S'};
int n = flames.length();
for(int z = 0; z < ctr-1; z++){
    res = flames[z %n];
    jLabel1.setText(String.valueOf(res));
}

答案 4 :(得分:1)

我将如何做到这一点:

String flames = "FLAMES";
int ctr = 10;

textLoop(flames.toCharArray(), jLabel1, ctr);

textLoop方法:

void textLoop(Iterable<Character> text, JLabel jLabel, int count){
    int idx = 0;
    while(true)
        for(char ch: text){
            jLabel.setText(String.valueOf(ch));
            if(++idx < count) return;
        }
}

编辑:在代码中发现了一个错误(idx需要在循环外初始化)。现在已经修好了。我也将它重构为一个独立的功能。