I have a code like this:
List<Listing> Listings = new ArrayList<>();
Listings.add(listing1);
Listings.add(listing2);
...
...
...
Listing listing= listings.stream()
.filter(l -> l.getVin() == 456)
.findFirst();
My question is what is the time complexity of the filter process? If it is O(n), my intuition is to convert it into HashSet like data structures so that the time complexity could become O(1), Is there an elegant way to do this with streams?
It is O(n) . The stream filtering uses iteration internally. You could convert it to a map as follows: Map<Integer, Listing > mapOfVinToListing = listings.stream().collect(Collectors.toMap(Listing::getVin, Functions.identity()); // Assuming vin is unique per listing mapOfVinToListing.get(456);// O(1)
Count Complexity The Stream::count terminal operation counts the number of elements in a Stream . The complexity of the operation is often O(N) , meaning that the number of sub-operations is proportional to the number of elements in the Stream .
Again, the for- loop is faster that the sequential stream operation, but the difference on an ArrayList is not nearly as significant as it was on an array.
In Java8 Streams, performance is achieved by parallelism, laziness, and using short-circuit operations, but there is a downside as well, and we need to be very cautious while choosing Streams, as it may degrade the performance of your application. Let us look at these factors which are meant for Streams' performance.
It is O(n)
. The stream filtering uses iteration internally.
You could convert it to a map as follows:
Map<Integer, Listing > mapOfVinToListing = listings.stream().collect(Collectors.toMap(Listing::getVin, Functions.identity()); // Assuming vin is unique per listing
mapOfVinToListing.get(456);// O(1)
But, that conversion process is also O(n). So, if you only need to do this once, use the filter. If you need to query the same list many times, then converting it to a map may make sense.
You might also try using parallel streams. In some cases they may be more performant, but that depends a lot on the exact circumstances.
The worst case is O(n)
but since Stream
is lazy, if the value is found before, it'll stop the iteration. If you need constant time look up, all the time, converting to a Map
is a good idea, at the cost of additional space; if the list if huge, you should consider that aspect. In fact, if the list is small, the difference between a Map
and a List
will be barely noticeable, unless you're working in a time-critical system.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With