简体   繁体   English

连续迭代集合和数组的最佳方法

[英]best way to Iterate over a collection and array consecutively

Its a very trivial question and related to coding Style and I am just asking to make my coding style more readable这是一个非常微不足道的问题,与编码风格有关,我只是要求使我的编码风格更具可读性

Suppose I have a Collection like linkedList and an Array and I need to iterate over both simultaneously.假设我有一个像 linksList 和一个数组这样的集合,我需要同时迭代两者。
currently the best way I know is to get a iterator over list and define a index variable outside the iterator loop and increment the index variable simultaneously to access both next elements {list and array}.目前我知道的最好的方法是在列表上获取迭代器并在迭代器循环之外定义一个索引变量,并同时增加索引变量以访问下一个元素 {list 和 array}。
Please refer the example below请参考下面的例子

LinkedList<Integer> list = new LinkedList<Integer>();
Integer[] arr = new Array[25];
// lets suppose both have 25 elements.

// My Iteration method will be 
int index =0;

for (Integer val : list) {
  System.out.println(val);
  System.out.println(arr[index++]);
}


so is it the only way or is there any other way I can perform this iteration in more readable and more relatable manner, where I don't have to take index variable separately.那么它是唯一的方法还是有任何其他方法可以以更具可读性和更相关的方式执行此迭代,我不必单独使用索引变量。
I know it can be possible that array might have less or more elements than collection but I am only talking about the cases where they have equal and we need to iterate over Both of them.我知道数组可能有比集合更少或更多的元素,但我只是在谈论它们相等并且我们需要迭代它们的情况。

PS : anybody can write a code that a computer can understand, actual challenge is to write code which humans can understand easily. PS:任何人都可以编写计算机可以理解的代码,实际挑战是编写人类可以轻松理解的代码。

What you have is essentially fine: it's simple, and simple can be sufficient to make code readable.你所拥有的本质上很好:它很简单,简单就足以使代码可读。

The only thing I would caution about is the side effect of index++ inside arr[index++] : if, say, you want to use the same value multiple times in the loop body, you couldn't simply copy+paste.我唯一要注意的是arr[index++]index++的副作用:比如说,如果你想在循环体中多次使用相同的值,你不能简单地复制+粘贴。

Consider pulling out a variable as the first thing in the loop to store the "current" array element (which is essentially what the enhanced for loop does for the list element).考虑提取一个变量作为循环中的第一件事来存储“当前”数组元素(这本质上是增强的 for 循环对列表元素所做的)。

for (Integer val : list) {
  Integer fromArr = arr[index++];

  // ...
}

Just to point out an alternative without having a separate variable for the index, you can use ListIterator , which provides you with the index of the element.只是为了指出没有单独的索引变量的替代方法,您可以使用ListIterator ,它为您提供元素的索引。

// Assuming list and are have same number of elements.
for (ListIterator<Integer> it = list.listIterator();
    it.hasNext();) {
  // The ordering of these statements is important, because next() changes nextIndex().
  Integer fromArr = arr[it.nextIndex()];
  Integer val = it.next();

  // ...
}

ListIterator is not an especially widely-used class, though; ListIterator并不是一个特别广泛使用的类。 its use may in and of itself be confusing.它的使用本身可能会令人困惑。


One of the downsides of the ListIterator approach is that you have to use the it correctly: you shouldn't touch it inside the loop (after getting the values), you have to put the statements in the right order, etc. ListIterator方法的缺点之一是您必须正确使用it :您不应该在循环内触摸它(在获取值之后),您必须以正确的顺序放置语句等。

Another approach would be to create a library method analogous to Python's enumerate :另一种方法是创建一个类似于 Python 的enumerate的库方法:

static <T> Iterable<Map.Entry<Integer, T>> enumerate(Iterable<? extends T> iterable) {
  return () -> new Iterator<T>() {
    int index = 0;
    Iterator<? extends T> delegate = iterable.iterator();

    @Override public boolean hasNext() { return delegate.hasNext(); }

    @Override public Map.Entry<Integer, T> next() {
      return new AbstractMap.SimpleEntry<>(index++, delegate.next());
    }
  };
}

This returns an iterable of map entries, where the key is the index and the value is the corresponding value.这将返回一个可迭代的映射条目,其中键是索引,值是相应的值。

You could then use this in an enhanced for loop:然后,您可以在增强的 for 循环中使用它:

for (Map.Entry<Integer, Integer> entry : enumerate(list)) {
  Integer fromList = entry.getValue();
  Integer fromArr = arr[entry.getKey()];
}

One option is to have 2 iterators, but I don't think it is any clearer:一种选择是有 2 个迭代器,但我认为它没有更清楚:

for (Iterator<Integer> i1 = list.iterator(), i2 = Arrays.asList(arr).iterator();
    i1.hasNext() && i2.hasNext();) {
    System.out.println(i1.next());
    System.out.println(i2.next());
}

But it is more robust in that it finishes at the shorter of the 2 collections.但它更健壮,因为它以 2 个集合中较短的一个结束。

I tried to simplify and handle size wise collections where both need not be of the same size.我试图简化和处理大小明智的集合,其中两者不必具有相同的大小。 I believe this would work even if the sizes are not same and just one loop would suffice.我相信即使尺寸不同,这也会起作用,只需一个循环就足够了。 Code snippet below:下面的代码片段:

LinkedList<Integer> list = new LinkedList<Integer>();
Integer[] arr = new Array[25];
int maxLength= Math.max(list.size(),arr.size());
//Looping over the lengthy collection( could be Linkedlist or arraylist)
for(int i=0;i<maxLength;i++){
if(list.size()>i)
  System.out.println(list[i]);
if(arr.size()>i)
  System.out.println(arr[i]);
}

Hope this helps!希望这可以帮助! Thanks谢谢

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM