Double a stream

1.4k Views Asked by At

I want to double a Stream (no DoubleStream). Meaning I start with a stream and want to get a new stream where each element of the old stream is streamed twice. So 1,2,3,4,4,5 gives us 1,1,2,2,3,3,4,4,4,4,5,5. Is there such a stream operation?

3

There are 3 best solutions below

1
On BEST ANSWER

Create an inner stream which will contain current element two times and flatMap this stream.

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

If you want to multiply the number of elements by n you can create an utility method like this one:

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 (where n is excluded)
}

(but try to use a better name for this method, since the current one may be ambiguous)

Usage example:

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

Output:

1
1
1
2
2
2
1
On

You can create a stream of 2 elements for each original element and flatMap it:

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

Here's a simple example of what biziclop has described in the comments.

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();
                    }
                }
            };
        }
    };
}

(Working example on Ideone.)

CW'd since it wasn't my idea and the flatMap suggestions more directly answer the question.