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

后端 未结 22 2307
天命终不由人
天命终不由人 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 01:58
    String[] namesArray = {"Sam","Pamela", "Dave", "Pascal", "Erik"};
    String completeString
             =  IntStream.range(0,namesArray.length)
               .mapToObj(i -> namesArray[i]) // Converting each array element into Object
               .map(String::valueOf) // Converting object to String again
               .collect(Collectors.joining(",")); // getting a Concat String of all values
            System.out.println(completeString);
    

    OUTPUT : Sam,Pamela,Dave,Pascal,Erik

    String[] namesArray = {"Sam","Pamela", "Dave", "Pascal", "Erik"};
    
    IntStream.range(0,namesArray.length)
                   .mapToObj(i -> namesArray[i]) // Converting each array element into Object
                   .map(String::valueOf) // Converting object to String again
                   .forEach(s -> {
                    //You can do various operation on each element here
                    System.out.println(s);
                   }); // getting a Concat String of all 
    

    To Collect in the List:

    String[] namesArray = {"Sam","Pamela", "Dave", "Pascal", "Erik"};
     List<String> namesList
                    =  IntStream.range(0,namesArray.length)
                    .mapToObj(i -> namesArray[i]) // Converting each array element into Object
                    .map(String::valueOf) // Converting object to String again
                    .collect(Collectors.toList()); // collecting elements in List
            System.out.println(listWithIndex);
    
    0 讨论(0)
  • 2020-11-22 02:01

    I found the solutions here when the Stream is created of list or array (and you know the size). But what if Stream is with unknown size? In this case try this variant:

    public class WithIndex<T> {
        private int index;
        private T value;
    
        WithIndex(int index, T value) {
            this.index = index;
            this.value = value;
        }
    
        public int index() {
            return index;
        }
    
        public T value() {
            return value;
        }
    
        @Override
        public String toString() {
            return value + "(" + index + ")";
        }
    
        public static <T> Function<T, WithIndex<T>> indexed() {
            return new Function<T, WithIndex<T>>() {
                int index = 0;
                @Override
                public WithIndex<T> apply(T t) {
                    return new WithIndex<>(index++, t);
                }
            };
        }
    }
    

    Usage:

    public static void main(String[] args) {
        Stream<String> stream = Stream.of("a", "b", "c", "d", "e");
        stream.map(WithIndex.indexed()).forEachOrdered(e -> {
            System.out.println(e.index() + " -> " + e.value());
        });
    }
    
    0 讨论(0)
  • 2020-11-22 02:02

    With https://github.com/poetix/protonpack u can do that zip:

    String[] names = {"Sam","Pamela", "Dave", "Pascal", "Erik"};
    
    List<String> nameList;
    Stream<Integer> indices = IntStream.range(0, names.length).boxed(); 
    
    nameList = StreamUtils.zip(indices, stream(names),SimpleEntry::new)
            .filter(e -> e.getValue().length() <= e.getKey()).map(Entry::getValue).collect(toList());                   
    
    System.out.println(nameList);
    
    0 讨论(0)
  • 2020-11-22 02:02

    As jean-baptiste-yunès said, if your stream is based on a java List then using an AtomicInteger and its incrementAndGet method is a very good solution to the problem and the returned integer does correspond to the index in the original List as long as you do not use a parallel stream.

    0 讨论(0)
  • 2020-11-22 02:03

    you don't need a map necessarily
    that is the closest lambda to the LINQ example:

    int[] idx = new int[] { 0 };
    Stream.of( names ).filter( name -> name.length() <= idx[0]++ ).collect( Collectors.toList() );
    
    0 讨论(0)
  • 2020-11-22 02:04

    With a List you can try

    List<String> strings = new ArrayList<>(Arrays.asList("First", "Second", "Third", "Fourth", "Fifth")); // An example list of Strings
    strings.stream() // Turn the list into a Stream
        .collect(HashMap::new, (h, o) -> h.put(h.size(), o), (h, o) -> {}) // Create a map of the index to the object
            .forEach((i, o) -> { // Now we can use a BiConsumer forEach!
                System.out.println(String.format("%d => %s", i, o));
            });
    

    Output:

    0 => First
    1 => Second
    2 => Third
    3 => Fourth
    4 => Fifth
    
    0 讨论(0)
提交回复
热议问题