I'm looking for feedback on how this can be improved. Basically what I'm trying to do is check if the cache has the object, else check from the database.

I have a list of ids, then I separate them based on whether they already exist in the cache or not, based on the date as well. One list fetches from the cache, the other from the db. Then return the list. That way I don't have to make multiple calls to cache/db.

The alternative is to implement a compound-key, but I would rather not go that route.


 private List<Cab> getFromCacheOrDb(CabTripsRequest request) {
        Map<Boolean, List<String>> cachedCabs = request.getMedallions().stream().collect(
                partitioningBy(key -> {
                    if (!cache.peek(key)) { return false; }
                    return cache.get(key).stream().anyMatch(a -> a.getPickupDateTime().equals(request.getDate()));
        List<Cab> response = cachedCabs.get(true).stream().map(k -> cache.get(k)).flatMap(List::stream)
                .filter(cab -> cab.getPickupDateTime().equals(request.getDate())).collect(toList());
        if (cachedCabs.get(false).size() > 0) {
            List<Cab> database = storage.fetch(cachedCabs.get(false), request.getDate());
        log.info("response from cache/db size:" + response.size());
        return response;
  • \$\begingroup\$ In your partitioning you can simplify a bit the code with : return cache.peek(key) && cache.get(key).stream().anyMatch(...) \$\endgroup\$
    – gervais.b
    Jan 18, 2019 at 9:08
  • \$\begingroup\$ You can also change your storage.fetch to deal with empty list so that you can just do List<Dab> database = storage.fetch(cachedCabs.get(false)) // may be empty and remove the if (cachedCabs.get(false).size()>0 ) \$\endgroup\$
    – gervais.b
    Jan 18, 2019 at 9:14

1 Answer 1


One approach you could pick here is to design your data stores in Storage interfaces in an increasing fashion.

Storage classes ordered by access time

private List<Cab> getCabs(Key key) {
    List<Cab> cabsByKey = this.cache.stream().filter(c -> c.equals(key)).anyMatch();
    if (cabsByKey.isEmpty()) {
       cabsByKey = this.higherStorage.getByKey(key);

    return cabsByKey;

The idea is to store its higher level cache instance for each data storage and to propagate request up whenever nothing has been found.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.