What we have is a list of objects of type Object, we might take them from a cache for example, so we want to iterate over that list with a lambda stream and after mapping an object in every iteration we want to see if attribute of that new class is present in a list of string values that we passed to the method.
2 Answers
Your solution is not optimised. Using List.contains will give you O(n*m) complexity. Use a HashSet instead:
public List<MyClass> getMyClassListByStates(List<String> states) { Set<String> set = new HashSet<>(states); return cache.getCacheByCacheNameList(CacheTypeConstants.MY_CLASS) .stream() .map(MyClass.class::cast) .filter(myc -> set.contains(myc.getState())) .collect(Collectors.toList()); } This will run in O(max(n,m)) time instead of O(n*m).
This is my solution to that problem:
public List<MyClass> getMyClassListByStates(List<String> states) { return cache.getCacheByCacheNameList(CacheTypeConstants.MY_CLASS) .stream() .map((myc) -> (MyClass) myc) .filter(myc -> states.contains(myc.getState())) .collect(Collectors.toList()); } If someone has any other way to do it, please be free to comment, thx.
2 Comments
Nikolai Shevchenko
If you want someone to criticize your solution it's better to put it in your Question instead of posting it as an Answer
Zabuzard
Your
states.contains call is expensive. Go Set and it will be faster. Personally, I would prefer a method reference on the cast, so MyClass.class::cast. Also, with Java 16+ you can just use .toList() on the stream directly and do not need .collect(Collectors.toList()) anymore.