Java: Interleave two integer based arraylists -> good approach?

后端 未结 5 635
萌比男神i
萌比男神i 2021-01-28 23:18

Homework: Looking for better strategy, or approach rather than complete code.

I\'v got two arrayLists of integers under two conditions:

  1. th
5条回答
  •  清酒与你
    2021-01-28 23:57

    Here's another way of thinking about this problem, and a way that would just as easily extend to 3 lists.

    First, recognize that the hard part to solve here is iteration, not creating the new list. Creating a new list from an iterable is trivial.

    So imagine we have a method like this:

    public  Iterable interleave(Iterable... lists) {
        return new Iterable() {
           @Override
           public Iterator iterator() {
               return new InterleavingIterator(lists);
           }
        };
    }
    

    What we need to make is an Iterator that cycles through each iterator one at a time. That's the perfect job for a queue (fifo)! Your iterator could look something like this:

    class InterleavingIterator implements Iterator {
    
        private final Queue> iterators = new LinkedList<>();
    
        public InterleavingIterator(Iterable> iteratables) {
            for ( Iterable iterable : iterables ) {
               Iterator iterator = iterable.iterator();
               if ( iterator.hasNext() ) {
                  this.iterators.add(iterator);
               }
            }
        }
    
        public boolean hasNext() {
            return !iterators.isEmpty();
        }
    
        public T next() {
            Iterator nextIterator = iterators.poll();
            T result = nextIterator.next();
            if ( nextIterator.hasNext() ) {
               iterators.add(nextIterator);
            }
            return result;
        }
    }
    

    In short, every time the next element is requested, the iterator at the top of the queue is popped, the result of next() is returned, and if the iterator still has elements (hasNext()) it is put to the back of the queue.

    This works exactly the same for any number of lists, and doesn't need any icky condition checking.

    To create a new list with it, you could just do:

    List combined = new ArrayList(interleave(list1, list2));
    

提交回复
热议问题