Java 8 for each and first index
14,376
Solution 1
May this work for you?
myList.stream().findFirst().ifPresent(e -> System.out.println("Special: " + e));
myList.stream().skip(1).forEach(System.out::println);
Output:
Special: A
B
Alternative:
myList.stream().findFirst().ifPresent(e -> somethingSpecial(e));
myList.stream().forEach(System.out::println);
Solution 2
I don't think there is something provided in stream.
There are several alternatives you may consider:
Method 1:
int[] i = {0}; // I am using it only as an int holder.
myList.stream().forEach(value -> {
if (i[0]++ == 0) {
doSomethingSpecial;
}
System.out.println(value);
});
Method 2:
If your list is quick for random access (e.g. ArrayList
), you may consider:
IntStream.range(0, myList.size())
.forEach(i -> {
ValueType value = myList.get(i);
if (i == 0) {
doSomethingSpecial();
}
System.out.println(value);
});
Solution 3
Try StreamEx
StreamEx.of("A", "B", "C") //
.peekFirst(e -> System.out.println(e + " Something special")).skip(1) //
.forEach(System.out::println);
Solution 4
If you were trying to achieve it in a single stream statement, here's how I'd do it:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
public class Solution {
public static void main(String[] args) {
List<String> myList = new ArrayList<>();
myList.add("A");
myList.add("B");
myList.add("C");
myList.add("D");
myList.add("E");
myList.add("F");
AtomicBoolean firstElementProcessed = new AtomicBoolean(false);
myList.stream().map(s -> {
if (firstElementProcessed.getAndSet(true)) {
return s;
}
return (s + " Something special");
}).forEach(System.out::println);
}
}
And maybe for better readability, I'd refactor it to:
public class Solution {
...
AtomicBoolean firstElementProcessed = new AtomicBoolean(false);
myList.stream().map(s -> getString(firstElementProcessed, s)).forEach(System.out::println);
}
private static String getString(AtomicBoolean firstElementProcessed, String s) {
if (firstElementProcessed.getAndSet(true)) {
return s;
}
return (s + " Something special");
}
}
Author by
David Dal Busco
Creator of DeckDeckGo | Organizer of the Ionic Zürich Meetup
Updated on June 26, 2022Comments
-
David Dal Busco almost 2 years
Anyone knows how to achieve following piece code in a Java 8 way respectively is there any stream methods to detect the first element in a forEach?
List<String> myList = new ArrayList<String>(); myList.add("A"); myList.add("B"); int i = 0; for (final String value : myList) { if (i == 0) { System.out.println("Hey that's the first element"); } System.out.println(value); i++; }
Java8:
myList.stream().forEach(value -> { // TODO: How to do something special for first element? System.out.println(value); });
Furthermore, let's says that the goal is the following (console output):
A Something special B C D E F
-
Adrian Shum about 7 yearstry a list of
{"one", "two", "one"}
-
Roland about 7 yearsI would rather use
myList.stream().findFirst().ifPresent(e -> System.out.println("Special: " + e));
instead ofpeek
... Note that the javadoc offindFirst()
says "If the stream has no encounter order, then any element may be returned.", but its ok for ordered lists. -
Eugene about 7 years@Oneiros you are assuming
myList
is a List, which is not bad, considering the OP wanted that, but if you (accidentally?) switch toSet
, this will fail. The proper way would probably be to check the Spliterator forSIZED
andSUBSIZED
properties. -
David Dal Busco about 7 yearsAs I said, curiosity and looking to learn something are the reasons for my question
-
Oneiros about 7 yearsWhy would OP use a
Set
considering that he wants to do special actions on first element? Sets are not ordered, it would make no sense in this context. -
Holger about 7 years@Oneiros: you’re right, treating the “first” element of an unordered
Set
specially makes no sense, but you wouldn’t believe how often people want exactly this… -
David Dal Busco about 7 yearsI marked this answer as the solution but I've to say that the other were also valid. I opened that post for curiosity and because I wanted to learn something, which was achieved. At the end, mostly for performance reason, I most probably gonna use a for like I always did but gonna use forEachOrdered and findFirst in other occasions
-
David Dal Busco about 7 yearsThx, StreamEx looks handy but my question was about native Java8