【问题标题】:Error in method - using Iterator to interweave a List方法错误 - 使用迭代器交织列表
【发布时间】:2015-12-19 14:34:54
【问题描述】:

我创建了一个方法,该方法应该交织两个列表对象并返回新的交织列表。

即如果 aList 是 [A,C,E,G] 并且 bList 是 [B, D, F],则该方法将返回一个包含 [A, B, C, D, E, F, G] 的列表

没有编译器错误,当我运行程序时,返回的列表为空。我发现程序没有进入 for 循环,因为由于某种原因,当我创建 newList 它的大小为 0。

代码如下:

    public static <E> List<E> interweave(List<E> a, List<E> b){
    List<E> newList = new ArrayList<E>(a.size() + b.size());

    Iterator<E> itrA = a.iterator();
    Iterator<E> itrB = b.iterator();

    for(int i = 0; i < newList.size(); i++){
        if(i%2 == 0)
            newList.add(i, itrA.next());
        else
            newList.add(i, itrB.next());
    }

    return newList;
}

【问题讨论】:

  • 构造函数new ArrayList(size) 确实分配了一个具有您定义的大小的新数组。但是ArrayList#size 不返回数组的长度,它返回一个变量size,它在操作List 后发生了变化。创建新的ArrayList后,大小还是0。
  • 谢谢你!这正是我需要知道的!因此,当我使用 new ArrayList() 然后在 for 循环中使用 a.size() + b.size() 的值时,它可以完美运行。

标签: java list iterator


【解决方案1】:

可以动态组合列表:

static class InterWeave<T> implements Iterable<T> {

    // The lists to be interwoven.
    final Iterable<T>[] lists;

    public InterWeave(Iterable<T>... lists) {
        this.lists = lists;
    }

    @Override
    public Iterator<T> iterator() {
        return new WeaveIterator();

    }

    private class WeaveIterator implements Iterator<T> {

        // Which list to offer next.
        int whichList = 0;
        // The Iterators of those lists.
        final List<Iterator<T>> iterators = new ArrayList(lists.length);
        // The current iterator.
        Iterator<T> i;
        // The next to deliver - null menas not primed yet.
        T next = null;

        public WeaveIterator() {
            // Take some iterators.
            for (Iterable<T> l : lists) {
                if (l != null) {
                    iterators.add(l.iterator());
                }
            }
        }

        @Override
        public boolean hasNext() {
            // Have we already prepared one?
            if (next == null) {
                // Grab the next iterator and step on.
                i = iterators.get(whichList++);
                // detect that we're back at start.
                Iterator<T> start = i;
                // Cycle around the iterators.
                whichList %= iterators.size();
                while (!i.hasNext()) {
                    // Get next one.
                    i = iterators.get(whichList++);
                    whichList %= iterators.size();
                    if (i == start) {
                        // Stop here if we've gone all the way around.
                        break;
                    }
                }
                if (i.hasNext()) {
                    next = i.next();
                }
            }
            return next != null;
        }

        @Override
        public T next() {
            if (hasNext()) {
                T n = next;
                // Mark it used.
                next = null;
                return n;
            } else {
                throw new NoSuchElementException();
            }
        }

    }

}

public void test() {
    List<String> a = Arrays.asList(new String[]{"A", "C", "E", "G"});
    List<String> b = Arrays.asList(new String[]{"B", "D", "F"});
    for (String s : new InterWeave<String>(a, b)) {
        System.out.println(s);
    }
}

【讨论】:

    【解决方案2】:

    我相信这可以用更简单的方式完成,使用while(iterator.hasNext()) idiom:

    itrA = a.iterator();
    itrB = b.iterator(); 
    
    while (itrA.hasNext() || itrB.hasNext()) {
      if (itrA.hasNext())
          newList.add(itrA.next());
      if (itrB.hasNext())
          newList.add(itrB.next());
    }
    

    【讨论】:

    • 简单且最佳的解决方案。 +1。
    • 谢谢你!这是完成工作的一种更简单的方法。此外,当我使用new ArrayList() 然后在for 循环中使用a.size() + b.size() 的值时,它可以完美运行。
    • 为简单起见加一个。
    猜你喜欢
    • 2013-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-19
    相关资源
    最近更新 更多