2012-07-10 8 views
7

Tôi đang trong quá trình viết một công việc MR. Nhưng tôi bị mắc kẹt với một vấn đề liên quan đến một đối tượng Iterable. Tôi cần phải tìm kích thước của nó. Tôi đưa nó vào một đối tượng List, nhưng đó là sai. (Danh sách có thể được cast thành Iterable, nhưng không thể đảo ngược.) Có một cách khác, tức là bằng cách sử dụng Iterator cho đối tượng và tăng bộ đếm cho mỗi giá trị. Nhưng đó không phải là một giải pháp tối ưu. Ai có thể đề xuất một cách tốt hơn ?.Làm thế nào để tìm kích thước của một đối tượng Iterable?

Hãy giúp tôi. Cảm ơn trước.

+0

Vui lòng viết mã của bạn ở đây để chúng tôi có thể kiểm tra. –

+0

Câu hỏi này không thực sự cảm thấy giống như một bản sao của một liên kết trong chỉnh sửa – shieldgenerator7

Trả lời

15

Giao diện Collection cung cấp phương thức size() và mở rộng Iterable. Nếu iterator của bạn xảy ra đến từ một bộ sưu tập, bạn có thể yêu cầu nó cho kích thước của nó, nếu không bạn đang ra khỏi may mắn, bạn chỉ cần có để iterate cho đến cuối.

Dưới đây là một hack mà thực hiện điều này:

public int size(Iterable<?> it) { 
    if (it instanceof Collection) 
    return ((Collection<?>)it).size(); 

    // else iterate 

    int i = 0; 
    for (Object obj : it) i++; 
    return i; 
} 
0

Iterator không có một kích thước() vào nó, nhưng một số các bộ sưu tập từ đó Iterator đã được bắt nguồn có kích thước(), như java. util.LinkedList.size(). Vì vậy, bạn có thể phải lặp lại trong một số trường hợp.

+0

Vấn đề là với chức năng giảm tốc: protected void thức giảm (Văn bản chính thức, \t \t \t \t thức Iterable giá trị, thức bối cảnh bối cảnh) \t \t \t \t ném IOException, InterruptedException { ...... } Đây là "giá trị" là đối tượng lặp lại. Tôi cần phải tìm kích thước của nó mà không iterating.But đó là không thể vì không phải là một đối tượng bộ sưu tập. Tôi cần phải làm một số hoạt động khác sau khi tìm thấy kích thước. Nếu tôi đang lặp qua đối tượng này, thì sau khi lặp lại, trình vòng lặp sẽ trỏ đến giá trị cuối cùng của nó. Tôi cần phải thiết lập lại nó. Vì vậy, tôi đang sử dụng một ResettableIterator để sau khi iteration tôi có thể thiết lập lại nó. –

+0

Bạn sẽ có thể yêu cầu một 'iterator()' nhiều lần như bạn muốn từ một 'Iterable', đó là lý do tại sao bạn nhận được một' Iterable' và không phải là 'Iterator' trong' reduce'. Vì vậy, 'Iterator a = values.iterator(), b = values.iterator();' là hoàn toàn hợp lệ và chúng phải độc lập miễn là bạn không gọi 'remove()' trên một trong hai. – TWiStErRob

5

Bạn phải đi qua trình vòng lặp và đếm các mục. Ví dụ,

  while (iterator.hasNext()) { 
      iterator.next(); 
      count++; 
     } 

này không phải là rất sạch nhưng iterator được sử dụng với mục đích lặp và không cung cấp bất kỳ api cụ thể cho điều đó.

Nhưng, trình tạo vòng lặp được tạo ở đâu? Nếu nó đến từ một đối tượng khác, ví dụ một đối tượng Collection, bạn có thể xác định kích thước của nguồn và không phải bản thân trình vòng lặp.

+0

Điều này sẽ không hoạt động trong trường hợp có thể lặp lại. – Siddarth