I have a DelayQueue, and the goal is to collect statistical information from the collection in O(1) time and space from getStatistics(). The stream for loop does not provide it. However I thought of keeping statistics updated on add of a transaction. But this will not guarantee that at the time when the getStatistics() called the queue will contain only unexpired item, and therefore I would need to iterate anyway. Or maybe the whole architecture here is not correct. I had also other thoughts, like having background task, with waiting time of the difference of the oldest transaction to drain the queue, and running it when that time expires, and update that watch to run it again when the other oldest transaction is approaching in time. public class TransactionManager {    private DelayQueue<Transaction> transactions;    public TransactionManager() {        transactions = new DelayQueue<>();    }    /**     * Create a transaction. If the json string is not valid, return {@link HttpStatus} UNPROCESSABLE_ENTITY     * If a transaction was created more than 60 seconds ago, return {@link HttpStatus} NO_CONTENT     * Otherwise add this transaction to the queue     *     * @param json {@link String} json object containing amount (type of {@link Double}),     *             and timestamp (type of {@link Long})     */    public Object createTransaction(String json) {        JSONObject jsonObject = null;        try {            jsonObject = JsonValidator.validateTransactionJson(json);        } catch (Exception ex) {            return new ResponseEntity(HttpStatus.UNPROCESSABLE_ENTITY);        }        long delay = System.currentTimeMillis() - ((Long) jsonObject.get(TIMESTAMP));        if (delay > ONEMINUTE) {            return new ResponseEntity(HttpStatus.NO_CONTENT);        }        transactions.add(new Transaction((Double) jsonObject.get(AMOUNT), (Long) jsonObject.get(TIMESTAMP)));        return new ResponseEntity(HttpStatus.OK);    }    /**     * Return statistics of transaction for the last 60 seconds.     *     * @return {@link String} in a JSON format     */    public String getStatistics() {        //drain to a list        List<Transaction> tempForCleaning = new ArrayList<>();        transactions.drainTo(tempForCleaning);        //clear it        tempForCleaning.clear();        Statistic statistics = new Statistic();        transactions.forEach(transaction -> {            statistics.setCount(statistics.getCount() + 1);            statistics.setSum(statistics.getSum() + transaction.getAmount());            statistics.setMax(statistics.getMax() > transaction.getAmount() ? statistics.getMax() : transaction.getAmount());            statistics.setMin(statistics.getMin() < transaction.getAmount() ? statistics.getMin() : transaction.getAmount());        });        if (statistics.getCount() > 0) {            statistics.setAvg(statistics.getSum() / statistics.getCount());        }        return statistics.toJSON();    }}Update:Statistic.class with getters and setters. public class Statistic {private double sum = 0.0;private double avg = 0.0;private double max = 0.0;private double min = 0.0;private int count = 0;}Just in case transaction as well:public class Transaction implements Delayed {    private final Double amount;    private final Long timestamp;   //timestamp of a time when the item was created and send here    public Transaction(double amount, long timestamp) {        this.amount = amount;        this.timestamp = timestamp;    }    @Override    public long getDelay(TimeUnit unit) {        return unit.convert(ONEMINUTE - (System.currentTimeMillis() - timestamp), MILLISECONDS);    }    @Override    public int compareTo(Delayed delayed) {        return delayed == this ?                0 :                Long.compare(getDelay(MILLISECONDS), delayed.getDelay(MILLISECONDS));    }    public double getAmount() {        return amount;    }}
Method to return statistics from a collection with O(1) time and space
java;time limit exceeded;collections;statistics