Is there a concise way to iterate over a stream with indices in Java 8?

后端 未结 22 2593
天命终不由人
天命终不由人 2020-11-22 01:42

Is there a concise way to iterate over a stream whilst having access to the index in the stream?

String[] names = {\"Sam\",\"Pamela\", \"Dave\", \"Pascal\",          


        
22条回答
  •  时光取名叫无心
    2020-11-22 02:10

    I've used the following solution in my project. I think it is better than using mutable objects or integer ranges.

    import java.util.*;
    import java.util.function.*;
    import java.util.stream.Collector;
    import java.util.stream.Collector.Characteristics;
    import java.util.stream.Stream;
    import java.util.stream.StreamSupport;
    import static java.util.Objects.requireNonNull;
    
    
    public class CollectionUtils {
        private CollectionUtils() { }
    
        /**
         * Converts an {@link java.util.Iterator} to {@link java.util.stream.Stream}.
         */
        public static  Stream iterate(Iterator iterator) {
            int characteristics = Spliterator.ORDERED | Spliterator.IMMUTABLE;
            return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, characteristics), false);
        }
    
        /**
         * Zips the specified stream with its indices.
         */
        public static  Stream> zipWithIndex(Stream stream) {
            return iterate(new Iterator>() {
                private final Iterator streamIterator = stream.iterator();
                private int index = 0;
    
                @Override
                public boolean hasNext() {
                    return streamIterator.hasNext();
                }
    
                @Override
                public Map.Entry next() {
                    return new AbstractMap.SimpleImmutableEntry<>(index++, streamIterator.next());
                }
            });
        }
    
        /**
         * Returns a stream consisting of the results of applying the given two-arguments function to the elements of this stream.
         * The first argument of the function is the element index and the second one - the element value. 
         */
        public static  Stream mapWithIndex(Stream stream, BiFunction mapper) {
            return zipWithIndex(stream).map(entry -> mapper.apply(entry.getKey(), entry.getValue()));
        }
    
        public static void main(String[] args) {
            String[] names = {"Sam", "Pamela", "Dave", "Pascal", "Erik"};
    
            System.out.println("Test zipWithIndex");
            zipWithIndex(Arrays.stream(names)).forEach(entry -> System.out.println(entry));
    
            System.out.println();
            System.out.println("Test mapWithIndex");
            mapWithIndex(Arrays.stream(names), (Integer index, String name) -> index+"="+name).forEach((String s) -> System.out.println(s));
        }
    }
    

提交回复
热议问题