2015-06-11 17 views
18

Tôi muốn tăng gấp đôi số Stream (không DoubleStream). Có nghĩa là tôi bắt đầu bằng luồng và muốn nhận luồng mới trong đó mỗi phần tử của luồng cũ được phát trực tiếp hai lần. Vì vậy, 1,2,3,4,4,5 cho chúng ta 1,1,2,2,3,3,4,4,4,4,5,5. Có hoạt động luồng như vậy không?Double a stream

+5

Chỉ cần lưu ý: cách tiếp cận khác là chỉ tạo chế độ xem bộ sưu tập gốc (hoặc nguồn khác của luồng) trả về từng phần tử hai lần. Tôi không nói đó là những gì bạn nên làm, chỉ là đó là một lựa chọn và trong một số trường hợp, cách tiếp cận xem hoạt động tốt hơn. – biziclop

+0

@biziclop: điều này thực sự có thể hoạt động hiệu quả hơn giải pháp 'flatMap' khi luồng từ chế độ xem như vậy sẽ có thể báo cáo kích thước chính xác của nó. –

+1

@TagirValeev Và nó không yêu cầu tạo luồng trung gian 'n'. – biziclop

Trả lời

28

Tạo luồng bên trong chứa phần tử hiện tại hai lần và flatMap luồng này.

stream.flatMap(e -> Stream.of(e,e)) 

Nếu bạn muốn để nhân số phần tử bằng n bạn có thể tạo ra một phương pháp hữu ích như thế này:

public static <T> Stream<T> multiplyElements(Stream<T> in, int n) { 
    return in.flatMap(e -> IntStream.range(0, n).mapToObj(i -> e)); 
    // we can also use IntStream.rangeClosed(1, n) 
    // but I am used to iterating from 0 to n (excluding n) 
} 

(nhưng cố gắng sử dụng một tên tốt hơn cho phương pháp này, vì hiện tại người ta có thể được mơ hồ)

Cách sử dụng Ví dụ:

multiplyElements(Stream.of(1,2), 3).forEach(System.out::println); 

Output:

1 
1 
1 
2 
2 
2 
+2

'repeatEach()' có thể là một tên tốt :) –

+1

Từ quan điểm toán học, một tên tốt sẽ là 'diagonalize (Luồng stream, int length)' vì bản đồ A-> A^n gửi x tới (x, ..., x) được gọi là nhúng chéo. –

6

Bạn có thể tạo một dòng của 2 yếu tố cho mỗi phần tử gốc và flatMap nó:

List<Integer> list = Arrays.asList(1, 2, 3, 4, 4, 5); 
List<Integer> doubled = list.stream().flatMap(i -> Stream.of(i, i)).collect(toList()); 
+4

IMHO bạn nên đề cập đến nhập tĩnh, như 'Collectors.toList' – fabian

3

Dưới đây là một ví dụ đơn giản về những gì biziclop đã được mô tả trong các ý kiến.

static <E> Collection<E> multiply(Collection<E> source, int count) { 
    return new AbstractCollection<E>() { 
     @Override 
     public int size() { 
      return count * source.size(); 
     } 
     @Override 
     public Iterator<E> iterator() { 
      return new Iterator<E>() { 
       final Iterator<E> it = source.iterator(); 

       E next; 
       int i = 0; 

       @Override 
       public boolean hasNext() { 
        return i < size(); 
       } 
       @Override 
       public E next() { 
        if (hasNext()) { 
         if ((i % count) == 0) { 
          next = it.next(); 
         } 
         ++i; 
         return next; 
        } else { 
         throw new NoSuchElementException(); 
        } 
       } 
      }; 
     } 
    }; 
} 

(ví dụ làm việc trên Ideone.)

CW'd vì nó không phải là ý tưởng của tôi và flatMap gợi ý trực tiếp hơn trả lời câu hỏi.