Java 到达数组中的最后一个索引后返回到第一个索引
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18725428/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Going back to the first index after reaching the last one in an array
提问by pchan
After my array in the for loop reaches the last index, I get an exception saying that the index is out of bounds. What I wanted is for it to go back to the first index until z
is equal to ctr
. How can I do that?
在 for 循环中的数组到达最后一个索引后,我收到一个异常,指出该索引越界。我想要的是让它回到第一个索引,直到z
等于ctr
. 我怎样才能做到这一点?
My code:
我的代码:
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));
}
采纳答案by luis.espinal
You need to use an index that is limited to the size of the array. More precisely, and esoterically speaking, you need to map the for-loop iterations {0..9} to the valid indexes for the flame array {0..flames.length()-1
}, which are the same, in this case, to {0..5}.
您需要使用限于数组大小的索引。更准确地说,更深奥地说,您需要将 for 循环迭代 {0..9} 映射到火焰数组 {0.. flames.length()-1
}的有效索引,在这种情况下,它们与 {0.. 5}。
When the loop iterates from 0 to 5, the mapping is trivial. When the loop iterates a 6th time, then you need to map it back to array index 0, when it iterates to the 7th time, you map it to array index 1, and so on.
当循环从 0 迭代到 5 时,映射是微不足道的。当循环迭代第 6 次时,您需要将其映射回数组索引 0,当循环迭代到第 7 次时,将其映射回数组索引 1,依此类推。
== Na?ve Way ==
== 天真的方式 ==
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));
}
== A More Appropriate Way ==
== 更合适的方式 ==
Then you can refine this by realizing flames.length()
is an invariant, which you move out of a for-loop.
然后你可以通过实现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));
}
== How To Do It ==
== 怎么做 ==
Now, if you are paying attention, you can see we are simply doing modular arithmetic on the index. So, if we use the modular (%) operator, we can simplify your code:
现在,如果您注意的话,您会发现我们只是在对索引进行模运算。因此,如果我们使用模块化 (%) 运算符,我们可以简化您的代码:
final int n = flames.length();
for(int z = 0; z < ctr-1; z++)
{
res = (flames[z % n]);
jLabel1.setText(String.valueOf(res));
}
When working with problems like this, think about function mappings, from a Domain (in this case, for loop iterations) to a Range (valid array indices).
处理此类问题时,请考虑函数映射,从域(在本例中为 for 循环迭代)到范围(有效数组索引)。
More importantly, work it out on paper before you even begin to code. That will take you a long way towards solving these type of elemental problems.
更重要的是,在你开始编码之前就在纸上解决它。这将使您在解决这些基本问题方面走得很远。
回答by sanbhat
You should use %
to force the index stay within flames.length
so that they make valid index
您应该使用%
强制索引保持在其中,flames.length
以便它们生成有效索引
int len = flames.length;
for(int z = 0; z < ctr-1; z++){
res = (flames[z % len]);
jLabel1.setText(String.valueOf(res));
}
回答by Rahul Tripathi
You can try the following:-
您可以尝试以下操作:-
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));
}
回答by Frankie
While luis.espinalanswer, performance-wise, is better I think you should also take a look into Iterator'sas they will give you greater flexibility reading back-and-forth.
虽然luis.espinal 的答案在性能方面更好,但我认为您还应该查看Iterator 的答案,因为它们将为您提供更大的来回阅读灵活性。
Meaning that you could just as easy write FLAMESFLAMES
as FLAMESSEMALF
, etc...
这意味着您可以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
}
Out of curiosity doing this loop 1M times (avg result from 100 samples) takes:
出于好奇,执行此循环 1M 次(100 个样本的平均结果)需要:
using modulo: 51ms
using iterators: 95ms
using guava cycle iterators: 453ms
Edit:Cycle iterators, as lbalazscsnicely put it, are even more elegant. They come at a price, and Guava implementation is 4 times slower. You could roll your own implementation, tough.
编辑:循环迭代器,正如lbalazscs所说的那样,更加优雅。它们是有代价的,而 Guava 的实现速度要慢 4 倍。你可以推出自己的实现,很难。
// guava example of cycle iterators
Iterator<Character> iterator = Iterators.cycle(flames);
for (int z = 0; z < ctr - 1; z++) {
res = iterator.next();
}
回答by AJMansfield
Here is how I would do this:
这是我将如何做到这一点:
String flames = "FLAMES";
int ctr = 10;
textLoop(flames.toCharArray(), jLabel1, ctr);
The textLoop method:
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;
}
}
EDIT: found a bug in the code (idx
needed to be initialized outside the loop). It's fixed now. I've also refactored it into a seperate function.
编辑:在代码中发现一个错误(idx
需要在循环外初始化)。现在已经修好了。我还将它重构为一个单独的函数。