2010-07-24 5 views
7

Java에서 컬렉션 컬렉션에 대한 반복자를 디자인합니다. 반복자는 중첩을 숨겨서 단일 컬렉션으로 작업하는 것처럼 모든 컬렉션에 속한 모든 요소를 ​​반복 할 수 있습니다.인터뷰 : 컬렉션 집합에 대한 반복자 디자인

+0

* 디자인 *에는 무엇이 있습니까? 프로토 타입? 구현? –

+0

둘 다, 인터페이스 란 무엇이며 어떻게 구현합니까? –

+2

이것이 취업 면접 일 경우, 왜 그냥 _doing_하는 대신 게시 하시겠습니까? – Jasper

답변

1

다음은 가능한 구현입니다. 바로 옆에() hasNext()를 가지고) (제거하는, 난 당신이 주변에 갈 필요가 생각 : 당신이 일을해야 모두가 자바 반복자 인 경우

public class MultiIterator <T> implements Iterator<T>{ 

    private Iterator<? extends Collection<T>> it; 
    private Iterator<T> innerIt; 
    private T next; 
    private boolean hasNext = true; 

    public MultiIterator(Collection<? extends Collection<T>> collections) { 
     it = collections.iterator();  
     prepareNext(); 
    } 

    private void prepareNext() { 
     do { 
      if (innerIt == null || !innerIt.hasNext()) { 
       if (!it.hasNext()) { 
        hasNext = false; 
        return; 
       } else 
        innerIt = it.next().iterator(); 
      } 
     } while (!innerIt.hasNext()); 

     next = innerIt.next(); 
    } 

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

    @Override 
    public T next() { 
     if (!hasNext) 
      throw new NoSuchElementException(); 
     T res = next; 
     prepareNext(); 
     return res; 
    } 

    @Override 
    public void remove() { 
     //TODO 
    } 

} 
+1

솔루션은 주어진 컬렉션 모음에서 null을 고려하지 않습니다. 수정 : prepareNext()에서 내부 루프는 it.next(). iterator()를 수행하기 전에 it.next()가 null이 아닌 값이 될 때까지 계속되어야하며 null이 아닌 컬렉션 객체가 남아 있지 않으면 제거해야합니다. 우리가 사용할. – Kowshik

0

먼저 java.util의 반복기 구현을 살펴보십시오. 거기에서 LinkedList의

http://www.docjar.com/html/api/java/util/LinkedList.java.html

당신의 작업입니다 단지 계정으로이 컬렉션을 반복된다는 사실을 소요 하나의 반복자를 구현하기 쉬운.

감사합니다.

+0

왜 이것을 다운 그레이드 했습니까? –

0

: 나는 구현되지 않은 삭제()를 왼쪽합니다 그것.

"배열"은 같지만 데이터 유형이 다르므로 2D 배열을 처리합니다. 즉, 외부 루프와 내부 루프를 처리합니다. 처리 할 때 새 컬렉션으로 전송합니다.

어쩌면 개인 방법 :

private void convertToSingleCollection() 
    { 


     while("column") 
     { 
      //convert the "column" to an arra 


      for("Row") 
      { 
      //add to newCollection here 
      } 

      //remove the processed column from CollectionOFcollection 
     } 
    } 
    //call the above method in your constructor 


    public iterator<T> Iterator() 
    { 
     newCollection.iterator(); 
    } 

    public boolean hasNext() 
    { 
     return Iterator().hasNext() 
    } 

    public T next() 
    { 
     if(!hasNext()) 
     { 
     //exception message or message 
     } 
     else 
      //return "next" 
    } 

도움이 되었기를 바랍니다. 다른 문제를 해결할 방법이 있어야합니다.

1

this post에서 두 가지 구현을 볼 수 있습니다. 유일한 차이점은 컬렉션 모음 대신 반복자를 반복하는 것입니다.

이 차이점은 라운드 로빈 방식으로 요소를 반복해야한다는 요구 사항 (OP에서 요청한 내용이 인이 질문)과 함께 반복기를 목록에 복사하는 오버 헤드가 추가됩니다.

첫 번째 방법은 게으른 : 그것은이 요소가 요청하는 경우에만 요소를 반복 할 것이다, 우리가 지불해야하는 '가격은'더 에지의 경우 처리해야하기 때문에 코드가 더 복잡하다는 것이다 :

import java.util.Iterator; 
import java.util.LinkedList; 
import java.util.List; 
import java.util.NoSuchElementException;  

public class MultiIterator<E> implements Iterator { 

    List<Iterator<E>> iterators = new LinkedList<>(); 
    Iterator<E> current = null; 

    public MultiIterator(Iterator<Iterator<E>> iterator) { 
     // copy the iterators into a list 
     while (iterator.hasNext()) { 
      iterators.add(iterator.next()); 
     } 
    } 

    @Override 
    public boolean hasNext() { 
     boolean result = false; 
     if (iterators.isEmpty() && (current == null || !current.hasNext())) { 
      return false; 
     } 

     if (current == null) { 
      current = iterators.remove(0); 
     } 

     while (!current.hasNext() && !iterators.isEmpty()) { 
      current = iterators.remove(0); 
     } 

     if (current.hasNext()) { 
      result = true; 
     } 
     return result; 
    } 

    @Override 
    public E next() { 
     if (current == null) { 
      try { 
       current = iterators.remove(0); 
      } catch (IndexOutOfBoundsException e) { 
       throw new NoSuchElementException(); 
      } 
     } 
     E result = current.next(); // if this method was called without checking 'hasNext' this line might raise NoSuchElementException which is fine 
     iterators.add(current); 
     current = iterators.remove(0); 
     return result; 
    } 

    // test 
    public static void main(String[] args) { 
     List<Integer> a = new LinkedList<>(); 
     a.add(1); 
     a.add(7); 
     a.add(13); 
     a.add(17); 
     List<Integer> b = new LinkedList<>(); 
     b.add(2); 
     b.add(8); 
     b.add(14); 
     b.add(18); 
     List<Integer> c = new LinkedList<>(); 
     c.add(3); 
     c.add(9); 
     List<Integer> d = new LinkedList<>(); 
     d.add(4); 
     d.add(10); 
     d.add(15); 
     List<Integer> e = new LinkedList<>(); 
     e.add(5); 
     e.add(11); 
     List<Integer> f = new LinkedList<>(); 
     f.add(6); 
     f.add(12); 
     f.add(16); 
     f.add(19); 
     List<Iterator<Integer>> iterators = new LinkedList<>(); 
     iterators.add(a.iterator()); 
     iterators.add(b.iterator()); 
     iterators.add(c.iterator()); 
     iterators.add(d.iterator()); 
     iterators.add(e.iterator()); 
     iterators.add(f.iterator()); 
     MultiIterator<Integer> it = new MultiIterator<>(iterators.iterator()); 
     while (it.hasNext()) { 
      System.out.print(it.next() + ","); // prints: 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19, 
     } 
    } 
} 

및 제 (리스트로 요구 된 순서로 모든 반복자 모든 요소 '그리 디'복사하고 그리스트 반복자 반환)

import java.util.Iterator; 
import java.util.LinkedList; 
import java.util.List; 

public class MultiIterator<E> { 

    Iterator<Iterator<E>> iterator = null; 
    List<E> elements = new LinkedList<>(); 

    private MultiIterator(Iterator<Iterator<E>> iterator) { 
     this.iterator = iterator; 
    } 

    private void copyElementsInOrder() { 
     List<Iterator<E>> iterators = new LinkedList<>(); 
     // copy the iterators into a list 
     while (iterator.hasNext()) { 
      iterators.add(iterator.next()); 
     } 
     // go over the list, round-robin, and grab one 
     // element from each sub-iterator and add it to *elements* 
     // empty sub-iterators will get dropped off the list 
     while (!iterators.isEmpty()) { 
      Iterator<E> subIterator = iterators.remove(0); 
      if (subIterator.hasNext()) { 
       elements.add(subIterator.next()); 
       iterators.add(subIterator); 
      } 
     } 
    } 

    public static <E> Iterator<E> iterator(Iterator<Iterator<E>> iterator) { 
     MultiIterator<E> instance = new MultiIterator<>(iterator); 
     instance.copyElementsInOrder(); 
     return instance.elements.iterator(); 
    } 

    // test 
    public static void main(String[] args) { 
     List<Integer> a = new LinkedList<>(); 
     a.add(1); 
     a.add(7); 
     a.add(13); 
     a.add(17); 
     List<Integer> b = new LinkedList<>(); 
     b.add(2); 
     b.add(8); 
     b.add(14); 
     b.add(18); 
     List<Integer> c = new LinkedList<>(); 
     c.add(3); 
     c.add(9); 
     List<Integer> d = new LinkedList<>(); 
     d.add(4); 
     d.add(10); 
     d.add(15); 
     List<Integer> e = new LinkedList<>(); 
     e.add(5); 
     e.add(11); 
     List<Integer> f = new LinkedList<>(); 
     f.add(6); 
     f.add(12); 
     f.add(16); 
     f.add(19); 
     List<Iterator<Integer>> iterators = new LinkedList<>(); 
     iterators.add(a.iterator()); 
     iterators.add(b.iterator()); 
     iterators.add(c.iterator()); 
     iterators.add(d.iterator()); 
     iterators.add(e.iterator()); 
     iterators.add(f.iterator()); 
     Iterator<Integer> it = MultiIterator.<Integer>iterator(iterators.iterator()); 
     while (it.hasNext()) { 
      System.out.print(it.next() + ","); // prints: 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19, 
     } 
    } 
} 

는 I 단순한 '검사'포함 MultiIterator를 사용하는 방법을 보여주기 위해 코드를 작성해야합니다. 라인에서 볼 수있는 것처럼 사소한 (Generics 사용으로 인해) :

Iterator<Integer> it = MultiIterator.<Integer>iterator(iterators.iterator());