If you have many identifiers for searching, it is recommended to use a solution that does this in one pass, and not for a linear search for each identifier:
Map<Integer,Optional<Item>> map=ids.stream() .collect(Collectors.toMap(id -> id, id -> Optional.empty())); items.forEach(item -> map.computeIfPresent(item.getId(), (i,o)->o.isPresent()? o: Optional.of(item))); for(ListIterator<Integer> it=ids.listIterator(ids.size()); it.hasPrevious();) { map.get(it.previous()).ifPresent(item -> { // do stuff }); }
The first statement simply creates a map from the list of identifiers, matching each search identifier with an empty Optional .
The second statement iterates over the elements using forEach and for each element, it checks whether it matches its identifier with the empty Optional and replaces it Optional , encapsulating the element, if there is such a mapping, all in one operation, computeIfPresent .
The last for loop repeats back in the ids list, since you wanted to process them in that order and perform the action if theres a nonempty Optional . Since the map was initialized with all identifiers found in the list, get will never return null , it will return empty Optional if the identifier is not found in the items list.
Thus, assuming that the Map s search has O(1) time complexity, which is the case in typical implementations, the average time complexity changed from O(m×n) to O(m+n) ...
Holger
source share