Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find first element by predicate

I've just started playing with Java 8 lambdas and I'm trying to implement some of the things that I'm used to in functional languages.

For example, most functional languages have some kind of find function that operates on sequences, or lists that returns the first element, for which the predicate is true. The only way I can see to achieve this in Java 8 is:

lst.stream()     .filter(x -> x > 5)     .findFirst() 

However this seems inefficient to me, as the filter will scan the whole list, at least to my understanding (which could be wrong). Is there a better way?

like image 391
siki Avatar asked May 16 '14 13:05

siki


People also ask

How do you extract the first element of a list?

To extract only first element from a list, we can use sapply function and access the first element with double square brackets. For example, if we have a list called LIST that contains 5 elements each containing 20 elements then the first sub-element can be extracted by using the command sapply(LIST,"[[",1).

How do you index the first element in a list?

To access the first element (12) of a list, we can use the subscript syntax [ ] by passing an index 0 . In Python lists are zero-indexed, so the first element is available at index 0 . Similarly, we can also use the slicing syntax [:1] to get the first element of a list in Python.

What is predicate in Python?

A predicate is a function that always returns True or False by performing some condition operations in a filter method. Syntax: filter(predicate, list)

How do I find an item in a list Python?

To find an element in the list, use the Python list index() method, The index() is an inbuilt Python method that searches for an item in the list and returns its index. The index() method finds the given element in the list and returns its position.


2 Answers

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.

like image 80
Alexis C. Avatar answered Sep 19 '22 15:09

Alexis C.


However this seems inefficient to me, as the filter will scan the whole list

No it won't - it will "break" as soon as the first element satisfying the predicate is found. You can read more about laziness in the stream package javadoc, in particular (emphasis mine):

Many stream operations, such as filtering, mapping, or duplicate removal, can be implemented lazily, exposing opportunities for optimization. For example, "find the first String with three consecutive vowels" need not examine all the input strings. Stream operations are divided into intermediate (Stream-producing) operations and terminal (value- or side-effect-producing) operations. Intermediate operations are always lazy.

like image 40
wha'eve' Avatar answered Sep 17 '22 15:09

wha'eve'