Java - 迭代列表中的每两个元素

时间:2013-04-16 09:44:14

标签: java iterator

在同时处理2个元素的同时迭代列表的最佳方法是什么?

示例:

List<String> strings = Arrays.asList("item 1", "item 2", "item 3", "item 4");
for(int i = 0; i < strings.size(); i++){
    String first = strings.get(i);
    String second = null;
    if(strings.size() > i + 1){
        second = strings.get(i + 1);
    }
    System.out.println("First [" + first + "] - Second [" + second + "]");
}

结果:

First [item 1] - Second [item 2]
First [item 2] - Second [item 3]
First [item 3] - Second [item 4]
First [item 4] - Second [null]

我想实现:

First [item 1] - Second [item 2]
First [item 3] - Second [item 4]

11 个答案:

答案 0 :(得分:13)

只需将i增加2:

for(int i = 0; i < strings.size(); i += 2) {

答案 1 :(得分:7)

您需要为第二个值修改和增加i,修改语句:

second = strings.get(i + 1);

second = strings.get(++i);

这也会增加i,因为这似乎是理想的行为。

所以你的代码是:

List<String> strings = Arrays.asList("item 1", "item 2", "item 3", "item 4");
for(int i = 0; i < strings.size(); i++){
    String first = strings.get(i);
    String second = null;
    if(strings.size() > i + 1){
        second = strings.get(++i); //Change here
    }
    System.out.println("First [" + first + "] - Second [" + second + "]");
}

答案 2 :(得分:5)

我使用Java8 BiConsumer创建了以下方法:

public static <T> void tupleIterator(Iterable<T> iterable, BiConsumer<T, T> consumer) {
    Iterator<T> it = iterable.iterator();
    if(!it.hasNext()) return;
    T first = it.next();

    while(it.hasNext()) {
        T next = it.next();
        consumer.accept(first, next);
        first = next;
    }
}

像这样使用它:

List<String> myIterable = Arrays.asList("1", "2", "3");
tupleIterator(myIterable, (obj1, obj2) -> {
    System.out.println(obj1 + " " + obj2);
});

这将输出:

1 2
2 3

答案 3 :(得分:2)

如果在每次迭代中将i增加2,该怎么办?应该做... 否则考虑在实际循环中增加i

答案 4 :(得分:2)

List<String> strings = Arrays.asList("item 1", "item 2", "item 3", "item 4");    
int i = 0;  
for(; i < strings.size() - 1; i+=2){  
    String first = strings.get(i);  
    String second =  strings.get(i + 1);  
    System.out.println("First [" + first + "] - Second [" + second + "]");  
}  
//For odd sized lists
if(i < strings.size()){         
    System.out.println("First [" + strings.get(i) + "]");  
}

答案 5 :(得分:2)

我们当然应该为一般情况提供解决方案; - )

public static void main(String[] args) {
    List<Integer> list = Arrays.asList(new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 });
    for (Pair<Integer> p : Pair.over(list)) {
        System.out.printf("%d, %d\n", p.first, p.second);
    }
}

static class Pair<T> {
    T first;

    T second;

    public Pair(T first, T second) {
        this.first = first;
        this.second = second;
    }

    public static <T> Iterable<Pair<T>> over(Collection<T> collection) {
        return new PairWise<T>(collection);
    }

    private static class PairWise<T> implements Iterable<Pair<T>>, Iterator<Pair<T>> {

        final Iterator<T> iterator;

        PairWise(Collection<T> collection) {
            super();
            this.iterator = collection.iterator();
        }

        @Override
        public Iterator<Pair<T>> iterator() {
            return this;
        }

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

        @Override
        public Pair<T> next() {
            T first = null;
            T second = null;
            if (iterator.hasNext())
                first = iterator.next();
            else
                throw new NoSuchElementException();
            if (iterator.hasNext())
                second = iterator.next();
            return new Pair<T>(first, second);
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }

    }
}

答案 6 :(得分:0)

for(int i = 0; i < strings.size(); i++){
    String first = strings.get(i++);
    String second = null;
    if(strings.size() > i){
        second = strings.get(i);
    }
    System.out.println("First [" + first + "] - Second [" + second + "]");
}

答案 7 :(得分:0)

List<String> strings = Arrays.asList("item 1", "item 2", "item 3", "item 4");
for(int i = 0; i < strings.size(); i++){
    if(i½2 = 0){
        String first = strings.get(i);
        System.out.print("First [" + first + "] ");
    }else{
         String second = strings.get(i + 1);
         System.out.println("- Second [" + second + "]");
    }
}

答案 8 :(得分:0)

为了提高性能,我建议你只计算一个列表的大小,而不是在每个新循环中创建一个新的字符串。

List<String> strings = Arrays.asList("item 1", "item 2", "item 3", "item 4");
int length = strings.size();
String first, second = null;
for(int i = 0; i < length; i += 2){
    ...
}

答案 9 :(得分:0)

您可以避免使用Iterator建立索引;这适用于任何Iterable,而不仅仅是列表。只需获取一个迭代器,并在每次循环迭代时将其递增两次:

List<String> strings = Arrays.asList("item 1", "item 2", "item 3", "item 4");
Iterator<String> stringsIterator = strings.iterator();
while (stringsIterator.hasNext()) {
  String first = stringsIterator.next();
  String second = stringsIterator.next();
  System.out.println("First [" + first + "] - Second [" + second + "]");
}

这假设一个偶数长度的列表,如果它是奇数长度,则在最后一次传递时抛出NoSuchElementException。您可以通过各种方式处理此问题:

  • 使用try - catch;
  • 有一个保护条款,可以预先检查长度是否均匀;
  • 在获得第二个元素之前检查。

检查第二个元素:

List<String> strings = Arrays.asList("item 1", "item 2", "item 3");
Iterator<String> stringsIterator = strings.iterator();
while (stringsIterator.hasNext()) {
  String first = stringsIterator.next();
  String second = stringIterator.hasNext() ? stringIterator.next() : null;
  System.out.println("First [" + first + "] - Second [" + second + "]");
}

迭代器让一些人感到困惑,所以你也可以使用for-each循环和分支以及辅助触发器变​​量进行奇偶校验。这更糟糕,因为它使循环的逻辑更加复杂以简化迭代:而不是每次通过循环执行一次,按顺序执行并且没有分支,您必须经历两次并在心理上分支。请注意,如果它是奇数长度,则会跳过最后一个元素;如果想要处理这些案件,可以在之后添加isFirst的支票。

List<String> strings = Arrays.asList("item 1", "item 2", "item 3", "item 4");
boolean isFirst = true;
String first = null;
String second = null;
for (String string : strings) {
  if (isFirst) {
    first = string;
    isFirst = false;
  } else {
    second = string;
    isFirst = true;
    System.out.println("First [" + first + "] - Second [" + second + "]");
  }
}

最后,请注意所有这些迭代器和辅助变量都有超出范围(它们仅用于循环本身,因此它们污染了本地环境):它们可以用块包装以限制范围,尽管通常是结果嵌套被认为比超出范围更糟糕:

List<String> strings = Arrays.asList("item 1", "item 2", "item 3", "item 4");
{
  Iterator<String> stringsIterator = strings.iterator();
  while (stringsIterator.hasNext()) {
    String first = stringsIterator.next();
    String second = stringsIterator.next();
    System.out.println("First [" + first + "] - Second [" + second + "]");
  }
}

答案 10 :(得分:0)

现在在Java 8中,使用https://github.com/wapatesh/fig

你可以写:

seq.forEachSlice(2, (values)->{
    // [1,2]  [3, 4]
});