Close

Java - How to add new item to a Collection while enforcing a fixed size and removing old item?

[Updated: May 30, 2018, Created: May 23, 2018]

Java Collections Java 

Following utility code shows how to add new element to a Collection while keeping a fixed size and removing an old element if the size is more than the specified limit.
This can be useful if we want to enforce a rolling behavior to a collection of our choice. For example if we use a list with this utility method, then we would have the advantage of accessing any element by index and enforcing rolling behavior as well.

package com.logicbig.example;

import java.util.*;

public class CircularCollectionWithLimit {

  public static <T, C extends Collection<T>> void addWithLimit(C c, T itemToAdd, int limit) {
      List<T> list = new ArrayList<>(c);
      list.add(itemToAdd);
      while (list.size() > limit) {
          list.remove(0);
      }
      c.clear();
      c.addAll(list);
  }

  public static void main(String[] args) {
      int limit = 4;
      List<Integer> l = new ArrayList<>(List.of(4, 3));
      System.out.println("given list: " + l);
      addWithLimit(l, 6, limit);
      System.out.println(l);
      addWithLimit(l, 7, limit);
      System.out.println(l);
      addWithLimit(l, 8, limit);
      System.out.println(l);

      Set<Integer> s = new LinkedHashSet<>(List.of(4, 3));
      System.out.println("given LinkedHashSet: " + s);
      addWithLimit(s, 6, limit);
      System.out.println(s);
      addWithLimit(s, 7, limit);
      System.out.println(s);
      addWithLimit(s, 8, limit);
      System.out.println(s);

      Queue<Integer> q = new ArrayDeque<>(List.of(4, 3));
      System.out.println("given ArrayDeque: " + q);
      addWithLimit(q, 6, limit);
      System.out.println(q);
      addWithLimit(q, 7, limit);
      System.out.println(q);
      addWithLimit(q, 8, limit);
      System.out.println(q);
  }
}
given list: [4, 3]
[4, 3, 6]
[4, 3, 6, 7]
[3, 6, 7, 8]
given LinkedHashSet: [4, 3]
[4, 3, 6]
[4, 3, 6, 7]
[3, 6, 7, 8]
given ArrayDeque: [4, 3]
[4, 3, 6]
[4, 3, 6, 7]
[3, 6, 7, 8]

For SortedSet, HashSet, EnumSet or PriorityQueue the insertion order is not maintained. Since the excess item is always removed at index 0, it might not be the oldest item it these cases.

Using CircularFifoQueue

Alternatively, if we only want to work with a Queue then we can use CircularFifoQueue from apache commons collections.

CircularFifoQueue is a first-in first-out queue with a fixed size that replaces its oldest element if full.

pom.xml

<dependency>
   <groupId>org.apache.commons</groupId>
   <artifactId>commons-collections4</artifactId>
   <version>4.1</version>
</dependency>
package com.logicbig.example;

import org.apache.commons.collections4.queue.CircularFifoQueue;
import java.util.List;
import java.util.Queue;

public class ApacheCircularFifoQueueExample {
  public static void main(String[] args) {
      Queue<Integer> q = new CircularFifoQueue<>(4);
      q.addAll(List.of(4, 3));
      System.out.println("given queue: " + q);
      q.add(6);
      System.out.println(q);
      q.add(7);
      System.out.println(q);
      q.add(8);
      System.out.println(q);
  }
}
given queue: [4, 3]
[4, 3, 6]
[4, 3, 6, 7]
[3, 6, 7, 9]

Example Project

Dependencies and Technologies Used:

  • commons-collections4 4.1: The Apache Commons Collections package contains types that extend and augment the Java Collections Framework.
  • JDK 10
  • Maven 3.3.9

Java - Rolling Collection Example Select All Download
  • java-rolling-collection
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • ApacheCircularFifoQueueExample.java

    See Also