2013-07-03 31 views
5

Có thành ngữ Java cho phép lặp theo cặp đôi thông qua các phần tử của một sắp xếp Collection không? Theo đó tôi có nghĩa là mỗi lần lặp lại có quyền truy cập vào một phần tử của bộ sưu tập và phần tử tiếp theo của bộ sưu tập?Thành ngữ cho phép lặp lại theo cặp thông qua bộ sưu tập được sắp xếp

Đối với sắp xếp List s (và mảng), nó có thể được thực hiện bằng một chỉ số vào bộ sưu tập:

final int n = list.size(); 
assert 2 <= n; 
for (int i = 0; i < n - 1; ++i) { 
    final Thing thing1 = list.get(i); 
    final Thing thing2 = list.get(i+1); 
    operateOnAdjacentPair(thing1, thing2); 
} 

Nhưng những gì về SortedSet? (đối với SortedMap bạn có thể sử dụng số entrySet(), tương đương với trường hợp SortedSet).


Vì vậy, ví dụ, nếu thiết lập được sắp xếp của bạn chứa các giá trị {1, 2, 3, 4}, sự lặp đi lặp lại sẽ là cho các cặp (1, 2), (2, 3), (3 , 4), theo thứ tự đó.

Trả lời

3

Bạn chỉ có thể thực hiện nó theo cách sau (và áp dụng chiến lược tương tự như đối với các khoản thu khác):

Iterator<Thing> iter = set.iterator(); 
Thing previous = iter.hasNext() ? iter.next() : null; 
while (iter.hasNext()) { 
    final Thing current = iter.next(); 
    operateOnAdjacentPair(previous, current); 
    previous = current; 
} 
5
Iterator<Thing> thingerator = coll.iterator(); 
if (thingerator.hasNext()) { 
    Thing thing1 = thingerator.next(); 
    while (thingerator.hasNext()) { 
     final Thing thing2 = thingerator.next(); 
     doStuffToThings(thing1, thing2); 

     thing1 = thing2; 
    } 
} 
+0

Tôi tin rằng đề xuất của bạn chỉ lặp lại một nửa số cặp vì mỗi lần lặp lại được tiến hành bởi 2 phần tử. – Raedwald

+0

@Raedwald Điều này là bước qua (1,2) (3,4) ... giống như bạn đã chỉ ra trong câu hỏi. – allprog

+0

Không, hãy xem ví dụ tôi đã cung cấp cho 'Danh sách'. – Raedwald

0

Đối Set s (và các bộ sưu tập không lập chỉ mục khác), bạn sẽ cần phải sử dụng họ Iterator s như trả về bởi phương pháp iterator() của Collection:

Iterator<Thing> iter = set.iterator(); 
Thing thing1 = iter.next(); // might want to check if this exists 
while (iter.hasNext()) { 
    Thing thing2 = iter.next(); 
    operateOnAdjacentPair(thing1, thing2); 
    thing1 = thing2; 
} 

Bạn có thể làm tương tự cho Map s , sử dụng số Iterator trong số entrySet() s của mình.


Bây giờ tôi hiểu câu hỏi của bạn tốt hơn, bạn cũng có thể thử này:

Iterator<Thing> iter1 = set.iterator(), iter2 = set.iterator(); 

if (iter2.hasNext()) 
    iter2.next(); // burn first element 

while (iter2.hasNext()) { 
    final Thing thing1 = iter1.next(); 
    final Thing thing2 = iter2.next(); 
    operateOnAdjacentPair(thing1, thing2); 
} 
+0

Tôi tin rằng đề xuất của bạn chỉ lặp lại một nửa số cặp, bởi vì mỗi lần lặp lại được tiến hành bởi 2 phần tử. – Raedwald

+0

@Raedwald Có bạn nói đúng, tôi hiểu lầm ví dụ của bạn. Nên được tất cả các thiết lập ngay bây giờ. Tôi cũng đã thêm một giải pháp thay thế khác, bây giờ tôi hiểu những gì bạn đang thực sự cố gắng làm. – arshajii

1

Viết triển khai Iterator, ví dụ: (chỉ cần viết ra khỏi đầu của tôi, vì vậy mã có thể không hoạt động như cũ)

public class PairwiseIterator<T> implements Iterator<List<T>> { 
    private final Iterator<T> elements; 
    private T last; 

    public PairwiseIterator(Collection<T> elements) { 
     this.elements = elements.iterator(); 
     last = elements.hasNext() ? elements.next() : null; 
    } 

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

    @Override 
    public List<T> next() { 
     List<T> result = ImmutableList.of(last, elements.next()); 
     last = result.get(1); 
     return result; 
    } 

    @Override 
    public void remove() { 
     throw new UnsupportedOperationException("Remove not allowed with this iterator"); 
    } 

    public static <U> Iterable<List<U>> iterable(final Collection<U> elements) { 
     return new Iterable() { 
      public Iterator<U> iterator() { 
       return new PairwiseIterator(elements); 
      } 
     } 
    } 
} 

Tôi có thể không có loại chính xác, nhưng phương pháp 'lặp lại' giúp dễ sử dụng trong cấu trúc foreach :

for(List<String> pair : PairwiseIterator.iterable(orderedSetOfStrings)) { 
    // ... do what you need to ... 
} 
Các vấn đề liên quan