到达数组中的最后一个索引后返回第一个索引
在for循环中的数组到达最后一个索引后,我得到一个exception,说索引超出范围。 我想要的是它回到第一个索引,直到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)); }
您需要使用仅限于数组大小的索引。 更准确地说,从根本上说,你需要将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)); }
==更合适的方式==
然后你可以通过实现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)); }
处理这样的问题时,请考虑函数映射,从域(在本例中为for循环迭代)到Range(有效数组索引)。
更重要的是,在开始编码之前,先在纸上进行处理。 这将为您解决这些类型的元素问题带来很长的路要走。
虽然luis.espinal答案,性能方面,更好,我认为你也应该看看迭代器,因为它们会给你更大的灵活性来回读取。
这意味着你可以像FLAMESSEMALF
一样容易地写FLAMESFLAMES
……
int ctr = 10; List flames = Arrays.asList('F','L','A','M','E','S'); Iterator it = flames.iterator(); for(int z=0; z
出于好奇心做这个循环1M次(平均100个样本的结果)需要:
using modulo: 51ms using iterators: 95ms using guava cycle iterators: 453ms
编辑:循环迭代器,因为lbalazscs很好地把它,更优雅。 它们付出了代价,番石榴的实施速度慢了4倍。 你可以推出自己的实施,很难。
// guava example of cycle iterators Iterator iterator = Iterators.cycle(flames); for (int z = 0; z < ctr - 1; z++) { res = iterator.next(); }
您应该使用%
来强制索引保持在flames.length
内,以便它们生成有效的索引
int len = flames.length; for(int z = 0; z < ctr-1; z++){ res = (flames[z % len]); jLabel1.setText(String.valueOf(res)); }
您可以尝试以下方法: –
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)); }
我是这样做的:
String flames = "FLAMES"; int ctr = 10; textLoop(flames.toCharArray(), jLabel1, ctr);
textLoop方法:
void textLoop(Iterable text, JLabel jLabel, int count){ int idx = 0; while(true) for(char ch: text){ jLabel.setText(String.valueOf(ch)); if(++idx < count) return; } }
编辑:在代码中发现了一个错误( idx
需要在循环外初始化)。 现在已经修好了。 我还将它重构为一个单独的函数。