繁体   English   中英

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

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

这是一个非常微不足道的问题,与编码风格有关,我只是要求使我的编码风格更具可读性

假设我有一个像 linksList 和一个数组这样的集合,我需要同时迭代两者。
目前我知道的最好的方法是在列表上获取迭代器并在迭代器循环之外定义一个索引变量,并同时增加索引变量以访问下一个元素 {list 和 array}。
请参考下面的例子

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


那么它是唯一的方法还是有任何其他方法可以以更具可读性和更相关的方式执行此迭代,我不必单独使用索引变量。
我知道数组可能有比集合更少或更多的元素,但我只是在谈论它们相等并且我们需要迭代它们的情况。

PS:任何人都可以编写计算机可以理解的代码,实际挑战是编写人类可以轻松理解的代码。

你所拥有的本质上很好:它很简单,简单就足以使代码可读。

我唯一要注意的是arr[index++]index++的副作用:比如说,如果你想在循环体中多次使用相同的值,你不能简单地复制+粘贴。

考虑提取一个变量作为循环中的第一件事来存储“当前”数组元素(这本质上是增强的 for 循环对列表元素所做的)。

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

  // ...
}

只是为了指出没有单独的索引变量的替代方法,您可以使用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并不是一个特别广泛使用的类。 它的使用本身可能会令人困惑。


ListIterator方法的缺点之一是您必须正确使用it :您不应该在循环内触摸它(在获取值之后),您必须以正确的顺序放置语句等。

另一种方法是创建一个类似于 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());
    }
  };
}

这将返回一个可迭代的映射条目,其中键是索引,值是相应的值。

然后,您可以在增强的 for 循环中使用它:

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

一种选择是有 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());
}

但它更健壮,因为它以 2 个集合中较短的一个结束。

我试图简化和处理大小明智的集合,其中两者不必具有相同的大小。 我相信即使尺寸不同,这也会起作用,只需一个循环就足够了。 下面的代码片段:

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

希望这可以帮助! 谢谢

暂无
暂无

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

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