514 Stimmen

Gibt es eine prägnante Möglichkeit, über einen Stream mit Indizes in Java 8 zu iterieren?

Gibt es einen prägnanten Weg, über einen Stream zu iterieren und dabei Zugriff auf den Index im Stream zu haben?

String[] names = {"Sam","Pamela", "Dave", "Pascal", "Erik"};

List nameList;
Stream indices = intRange(1, names.length).boxed();
nameList = zip(indices, stream(names), SimpleEntry::new)
        .filter(e -> e.getValue().length() <= e.getKey())
        .map(Entry::getValue)
        .collect(toList());

was im Vergleich zum dort gegebenen LINQ-Beispiel recht enttäuschend erscheint

string[] names = { "Sam", "Pamela", "Dave", "Pascal", "Erik" };
var nameList = names.Where((c, index) => c.Length <= index + 1).ToList();

Gibt es einen prägnanteren Weg?

Zudem scheint es, dass zip entweder verschoben oder entfernt wurde...

0voto

Arpan Saini Punkte 3235
String[] namesArray = {"Sam","Pamela", "Dave", "Pascal", "Erik"};
String completeString
         =  IntStream.range(0,namesArray.length)
           .mapToObj(i -> namesArray[i]) // Jedes Array-Element in ein Objekt konvertieren
           .map(String::valueOf) // Objekt wieder in String konvertieren
           .collect(Collectors.joining(",")); // Concat-String aller Werte erhalten
        System.out.println(completeString);

AUSGABE: Sam,Pamela,Dave,Pascal,Erik

String[] namesArray = {"Sam","Pamela", "Dave", "Pascal", "Erik"};

IntStream.range(0,namesArray.length)
               .mapToObj(i -> namesArray[i]) // Jedes Array-Element in ein Objekt konvertieren
               .map(String::valueOf) // Objekt wieder in String konvertieren
               .forEach(s -> {
                // Hier können verschiedene Operationen auf jedem Element durchgeführt werden
                System.out.println(s);
               }); // Erhalten eines Concat-Strings aller

Um in der Liste zu sammeln:

String[] namesArray = {"Sam","Pamela", "Dave", "Pascal", "Erik"};
 List namesList
                =  IntStream.range(0,namesArray.length)
                .mapToObj(i -> namesArray[i]) // Jedes Array-Element in ein Objekt konvertieren
                .map(String::valueOf) // Objekt wieder in String konvertieren
                .collect(Collectors.toList()); // Elemente in Liste sammeln
        System.out.println(listWithIndex);

0voto

mario Punkte 585

Wie jean-baptiste-yunès sagte, wenn Ihr Stream auf einer Java-Liste basiert, ist die Verwendung eines AtomicInteger und seiner incrementAndGet-Methode eine sehr gute Lösung für das Problem, und die zurückgegebene Ganzzahl entspricht dem Index in der Original-Liste, solange Sie keinen parallelen Stream verwenden.

0voto

vbezhenar Punkte 9767

Hier ist die Lösung für standard Java:

Inline-Lösung:

Arrays.stream("zero,one,two,three,four".split(","))
        .map(new Function>() {
            int index;

            @Override
            public Map.Entry apply(String s) {
                return Map.entry(index++, s);
            }
        })
        .forEach(System.out::println);

und eine lesbarere Lösung mit einer Hilfsmethode:

static  Function> mapWithIntIndex() {
    return new Function>() {
        int index;

        @Override
        public Map.Entry apply(T t) {
            return Map.entry(index++, t);
        }
    };
}

...
Arrays.stream("zero,one,two,three,four".split(","))
        .map(mapWithIntIndex())
        .forEach(System.out::println);

0voto

Ishan Liyanage Punkte 1917

Wenn die Liste eindeutig ist, können wir die indexOf-Methode verwenden.

List namen = Arrays.asList("Sam", "Pamela", "Dave", "Pascal", "Erik");

    namen.forEach(name ->{
        System.out.println((namen.indexOf(name) + 1) + ": " + name);
    });

0voto

ursa Punkte 3918

Gibt es einen prägnanten Weg, über einen Stream zu iterieren und dabei zugriff auf den Index im Stream zu haben?

Wenn man sich das Iterieren über als Terminaloperation (wie forEach) vorstellt, dann Ja, es gibt eine einfache Möglichkeit auf den Index zuzugreifen:

Stream namen = Stream.of("Sam","Pamela", "Dave", "Pascal", "Erik");
List gefiltert = new ArrayList<>();

namen.reduce(0L, (index, element) -> {
    log.info("Iteration über Elemente [Index: {}, Element: {}]", index, element);
    if (element.length() < index) {
        gefiltert.add(element);
    }
    return index + 1;
}, Long::sum);

Dies funktioniert nur für sequenzielle Streams.

Parallele Streams müssen zuerst in sequenzielle umgewandelt werden:

namen.sequential().reduce(0L, (index, element) -> {
    log.info("Iteration über Elemente [Index: {}, Element: {}]", index, element);
    if (element.length() < index) {
        gefiltert.add(element);
    }
    return index + 1;
}, Long::sum);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X