Fetch first element of stream matching the criteria
This might be what you are looking for:
yourStream
.filter(/* your criteria */)
.findFirst()
.get();
And better, if there's a possibility of matching no element, in which case get()
will throw a NPE. So use:
yourStream
.filter(/* your criteria */)
.findFirst()
.orElse(null); /* You could also create a default object here */
An example:public static void main(String[] args) {
class Stop {
private final String stationName;
private final int passengerCount;
Stop(final String stationName, final int passengerCount) {
this.stationName = stationName;
this.passengerCount = passengerCount;
}
}
List<Stop> stops = new LinkedList<>();
stops.add(new Stop("Station1", 250));
stops.add(new Stop("Station2", 275));
stops.add(new Stop("Station3", 390));
stops.add(new Stop("Station2", 210));
stops.add(new Stop("Station1", 190));
Stop firstStopAtStation1 = stops.stream()
.filter(e -> e.stationName.equals("Station1"))
.findFirst()
.orElse(null);
System.out.printf("At the first stop at Station1 there were %d passengers in the train.", firstStopAtStation1.passengerCount);
}
Output is:
At the first stop at Station1 there were 250 passengers in the train.
Find first element by predicate
No, filter does not scan the whole stream. It's an intermediate operation, which returns a lazy stream (actually all intermediate operations return a lazy stream). To convince you, you can simply do the following test:
List<Integer> list = Arrays.asList(1, 10, 3, 7, 5);
int a = list.stream()
.peek(num -> System.out.println("will filter " + num))
.filter(x -> x > 5)
.findFirst()
.get();
System.out.println(a);
Which outputs:
will filter 1
will filter 10
10
You see that only the two first elements of the stream are actually processed.
So you can go with your approach which is perfectly fine.
Return Element based on matching criteria from Stream
You should filter
the list first and the use findFirst
AllData allData = allDataList.stream()
.filter(e -> e.getMyTicker().getWidgetId() == 58)
.findFirst().get();
I would recommend to use orElse to avoid NoSuchElementException - if there is no value present in Optional
Stream Way to get index of first element matching boolean
Occasionally there is no pythonic zipWithIndex
in java. So I came across something like that:
OptionalInt indexOpt = IntStream.range(0, users.size())
.filter(i -> searchName.equals(users.get(i)))
.findFirst();
Alternatively you can use zipWithIndex
from protonpack library
Note
That solution may be time-consuming if users.get is not constant time operation.
How get the first matching element from stream filter() in JAVA 11?
Use a list of the types, in order of desired precedence, to both filter the stream and as the basis of a comparator you use with min()
on the stream:
List<String> types = List.of("Residence", "Correspondance", "Office", "Next Door");
addresses.stream()
.filter(a -> types.contains(a.getType()))
.min(comparingInt(a -> types.indexOf(a.getType())));
——
You would typically use a constant for the list so it didn’t need to be created every time.
private static final List<String> ADDRESS_TYPES = List.of("Residence", "Correspondance", "Office", "Next Door");
——-
p.s "Correspondence" is spelled ...ence, not ...ance
Is there a way to find the first element to match a Predicate?
It does exactly what you want. It doesn't run over all the elements. The filter
method creates a stream and on top of it findFirst
creates another stream.
So when you try to get the element of the stream that was created after findFirst()
you'll get only the first one that matches the predicate.
Best way to check that is to add a print line or something like that inside the predicate.
Create a stream of integers for example from 0 to 10 and create a predicate that prints the number and then checks if it's divided by 3. You'll get this printed out: 0, 1, 2, 3 and that's it.
I wrote a question + answer in the past to explain in more details how it works: Understanding java 8 stream's filter method
Return first match in Java 8 stream (similar to _.find)
Nope, what you already have is totally the way to do it, and it's not actually any less performant. filter
is performed lazily, which means that the predicate only gets evaluated until the first element matching the predicate is found. It does not evaluate the predicate for any more elements than it has to.
What you have is the way the Stream framework designers intended you to do this operation.
Using Java8 streams to filter list and get the first element
You can simplify it as follows (there is no need to collect and then stream and call findFirst
. You can use flatMap
here)
collectorConfiguration = Optional.ofNullable(recapPlacement.getPnetCode())
.flatMap(pnetCode -> collectorConfigurations.stream()
.filter(c -> pnetCode.equals(c.getPnetCode()))
.filter(Objects::nonNull)
.findFirst())
.orElse(unknownExternalCollector);
Related Topics
Java String.Indexof and Empty Strings
When Does Java's Thread.Sleep Throw Interruptedexception
Setting Outer Variable from Anonymous Inner Class
Maximum Size of Hashset, Vector, Linkedlist
Ssl Peer Shut Down Incorrectly in Java
How to Change the Color of Titlebar in Jframe
Equivalent Function to C's "_Getch()" in Java
Pdfbox - Signature Validity Checkmark Not Visible in Acrobat Reader
In Java, Differencebetween This.Method() and Method()
Can't Make Jackson and Lombok Work Together
In Which Thread Do Completablefuture's Completion Handlers Execute
How to Make a List with Checkboxes in Java Swing
What's the Use of Session.Flush() in Hibernate
Permutation Algorithm Without Recursion? Java
How to Use Collections.Sort() in Java
Calling Getters on an Object VS. Storing It as a Local Variable (Memory Footprint, Performance)