I have List of file Paths: .
List<Path> filePaths; //e.g. [src\test\resources\file\15\54\54_exampleFile.pdf]
54
above refers to file ID
I then obtain a Set
of String
Ids which my application can handle as follows:
Set<String> acceptedIds = connection.getAcceptedIDs(); //e.g. elements [64, 101, 33]
How can I use Java 8 lambdas to filter
out all elements in filePaths
that do not contain any of the acceptable Ids that are contained in acceptedIds
collection Set.
In other words, I would like to retain in filePaths
only the paths that have ids which are in acceptedIds
set. For example, 54 is not in the above list so is removed.
filePaths.stream().filter(...).collect(Collectors.toList());
To remove an element from a list using the remove() method, specify the value of that element and pass it as an argument to the method. remove() will search the list to find it and remove it.
What you need to do if you want to use remove is loop calling l. remove over and over until you get ValueError and at that point break that loop. That would account for the case that there are multiple occurrences of a value in the list. (The better solution is still your first one, though.)
The most efficient way is to extract the ID from the path, then attempt to find it in the Set, making each filter execute in constant time, ie O(1)
giving an overall O(n)
, where n
is the number of paths:
filePaths.stream()
.filter(p -> acceptedIds.contains(p.getParent().getFileName().toString()))
.collect(Collectors.toList());
If the reverse approach is done, where each acceptedIds
is searched for in the path (as in other answers), each filter is O(m*k)
, where m
is the number of acceptedIds
and k
is the average Path length, giving an overall O(n * m * k)
, which will perform very poorly for even moderate sizes of collections.
You could write:
filePaths.stream()
.filter(p -> acceptedIds.stream().anyMatch(id -> p.toString().contains(id)))
.collect(toList());
This filters each path such that at least one of the acceptedIds
is contained in the string representation of the path. You might want to implement something better than contains
here, depending on your use-case (matching the beginning of the filename for example).
anyMatch
is an operation that determines if at least one element matches the given predicate.
Note that this answer does not make any assumption about the path to filter out elements. If you can safely say that in each path, the parent directory is named with the id, you should definitely go with @Bohemian answer, for performance reason.
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