Method to return statistics from a collection with O(1) time and space 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&lt;Transaction&gt; transactions;


    public TransactionManager() {
        transactions = new DelayQueue&lt;&gt;();
    }

    /**
     * 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 &gt; 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&lt;Transaction&gt; tempForCleaning = new ArrayList&lt;&gt;();
        transactions.drainTo(tempForCleaning);
        //clear it
        tempForCleaning.clear();

        Statistic statistics = new Statistic();
        transactions.forEach(transaction -&gt; {
            statistics.setCount(statistics.getCount() + 1);
            statistics.setSum(statistics.getSum() + transaction.getAmount());
            statistics.setMax(statistics.getMax() &gt; transaction.getAmount() ? statistics.getMax() : transaction.getAmount());
            statistics.setMin(statistics.getMin() &lt; transaction.getAmount() ? statistics.getMin() : transaction.getAmount());
        });
        if (statistics.getCount() &gt; 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;
    }
}
Initializing in the declaration


    private DelayQueue&lt;Transaction&gt; transactions;


    public TransactionManager() {
        transactions = new DelayQueue&lt;&gt;();
    }



You could replace this entire block with just 

    private BlockingQueue&lt;Transaction&gt; transactions = new DelayQueue&lt;&gt;();


This has the identical effect.  No big advantage, just less code.  

Using the interface rather than the implementation is good practice, as it makes the code more flexible.  

Statistics

You have 


        Statistic statistics = new Statistic();
        transactions.forEach(transaction -&gt; {
            statistics.setCount(statistics.getCount() + 1);
            statistics.setSum(statistics.getSum() + transaction.getAmount());
            statistics.setMax(statistics.getMax() &gt; transaction.getAmount() ? statistics.getMax() : transaction.getAmount());
            statistics.setMin(statistics.getMin() &lt; transaction.getAmount() ? statistics.getMin() : transaction.getAmount());
        });
        if (statistics.getCount() &gt; 0) {
            statistics.setAvg(statistics.getSum() / statistics.getCount());
        }



And 


  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;}



Consider getting rid of the setters.  Instead, move that block from the getStatistics method into an addDatum method in the Statistics class.  

public class Statistics {

    private double sum = 0.0;
    private double maximum = 0.0;
    private double minimum = 0.0;
    private int count = 0;

    public void addDatum(double amount) {
        count++;
        sum += amount;

        if (amount &gt; maximum) {
            maximum = amount;
        } else if (amount &lt; minimum) {
            minimum = amount;
        }
    }

    public double calculateAverage() {
        return (count &gt; 0) ? (sum / count) : 0.0;
    }

}


This way the Statistics class knows how to do calculations.  In the original, it was only a dumb container.  So you had to get the value, update it, and then set to the result.  

I also fixed the indentation and spacing of the class.  

I updated the name.  Average is a statistic.  This is a collection of statistics.  

I moved the average calculation into a replacement for getAvg.  It calculates it on the fly.  You could memoize the result if you wanted, but you'd have to invalidate it with each addition.  Or you could recalculate the average each time you add something.  

Updating as you go

You are considering making changes to update as you go.  This is still consistent with that.  

You may also want to consider how you use this.  You say 


     * Return statistics of transaction for the last 60 seconds.



But there are easier ways to do that than to use a DelayQueue.  Rather than use a sorted queue, use buckets.  E.g. with a HashMap&lt;MinuteTime, Transactions&gt;:   

buckets.get(timeToTheMinute).add(transaction);


Then you can calculate the statistics in the add method.  And you don't have to worry about expirations to separate one period from another.