Java collection with expiring entries - java

I need to track certain events over a specified time frame and act if the number of events reaches a certain number. In more detail, I connect to an external service and submit requests which are acknowledged with a status that equals CONF or FAIL. I need to be able to monitor the responses to detect if I get an unusual number of fails in a given time frame, e.g. >3 fails during the last 5 seconds, so that I can check for errors and act accordingly. I could alternatively check for 3 fails in a row but I prefer a time based approach.
I have been testing Guava's CacheLoader after reading this post but while entries (I only store FAIL-events) in the Cache appears to expire as expected, a call to size() (to determine number of fails) includes also the expired entries. This appears to be how it is supposed to work according to the documentation, if I have not misunderstood things?? Is there any way to get the number of 'active' events from a Cache?
I guess an alternative solution is to use a CEP-framework like Esper but it seems like overkill and cumbersome for my simple needs. Does anyone have a completely different approach to suggest that would facilitate my requirement? Thanks

Getting the exact number of active elements from the Cache would require locking the entire cache, which is extremely expensive. You might be able to use the cleanUp() method to make sure that size is not accidentally counting entries that have been quietly evicted, though.
I would not depend on this giving you exact results, but it should improve the accuracy of the results significantly.

I think Guava collection with the nearest functionality to what you want is MinMaxPriorityQueue with a limited maximum size. You'd have to put failure events in chronological order and check periodically for the difference between first and last element and whether it is full.
But what you essentially want is a meter. You can try this Meter from Coda Hale's Metrics library.

You could decorate a collection implementation to do that. Something like this:
public class ExpirableArrayList<E> extends ArrayList<E> {
private final Date creation = new Date();
private final long timeToLiveInMs;
public ExpirableArrayList(long timeToLiveInMs, int initialCapacity) {
super(initialCapacity);
this.timeToLiveInMs = timeToLiveInMs;
}
public ExpirableArrayList(long timeToLiveInMs) {
this.timeToLiveInMs = timeToLiveInMs;
}
public ExpirableArrayList(long timeToLiveInMs, Collection<? extends E> c) {
super(c);
this.timeToLiveInMs = timeToLiveInMs;
}
private void expire() {
if (System.currentTimeMillis() - creation.getTime() > timeToLiveInMs) {
clear();
}
}
#Override
public int size() {
expire();
return super.size();
}
#Override
public boolean isEmpty() {
expire();
return super.isEmpty();
}
#Override
public boolean contains(Object o) {
expire();
return super.contains(o);
}
#Override
public Iterator<E> iterator() {
expire();
return super.iterator();
}
#Override
public Object[] toArray() {
expire();
return super.toArray();
}
#Override
public <T> T[] toArray(T[] a) {
expire();
return super.toArray(a);
}
#Override
public boolean add(E e) {
expire();
return super.add(e);
}
#Override
public boolean remove(Object o) {
expire();
return super.remove(o);
}
#Override
public boolean containsAll(Collection<?> c) {
expire();
return super.contains(c);
}
#Override
public boolean addAll(Collection<? extends E> c) {
expire();
return super.addAll(c);
}
#Override
public boolean addAll(int index, Collection<? extends E> c) {
expire();
return super.addAll(index, c);
}
#Override
public boolean removeAll(Collection<?> c) {
expire();
return super.removeAll(c);
}
#Override
public boolean retainAll(Collection<?> c) {
expire();
return super.retainAll(c);
}
#Override
public E get(int index) {
expire();
return super.get(index);
}
#Override
public E set(int index, E element) {
expire();
return super.set(index, element);
}
#Override
public E remove(int index) {
expire();
return super.remove(index);
}
#Override
public int indexOf(Object o) {
expire();
return indexOf(o);
}
#Override
public int lastIndexOf(Object o) {
expire();
return lastIndexOf(o);
}
#Override
public ListIterator<E> listIterator() {
expire();
return listIterator();
}
#Override
public ListIterator<E> listIterator(int index) {
expire();
return listIterator();
}
#Override
public List<E> subList(int fromIndex, int toIndex) {
expire();
return subList(fromIndex, toIndex);
}
}

I haven't used it but it looks like this might satisfy your needs

Related

Compiler asking for optional methods from Collections to be overridden

I'm creating a class-wide project with my school mates, I'm supposed to create pull requests for some functions, but I'm having some problems just creating the class and overriding the methods in a way that it would just compile (I don't need to write the methods at this moment, that's the project, I just need it to compile). I've found most methods are working (or at least the compiler is not complaining), but I'm confused about a few things:
Compiler complaining about methods that are optional (like set, and addAll)
The method addAll, although it was added, complains that it wasn't overridden, although it was, and when I add the other addAll method for it, then I get an erasure error as well.
I've read a bunch about it, but I couldn't find a proper conclusion on how to solve it. I'm just using Atom to write my code, and the Terminal, no fancy IDE (perhaps I should learn one).
In case it isn't clear, I'm just looking to have the stubs of the methods available, not an all around answer for every single method, since this is the project with the class.
// https://docs.oracle.com/javase/8/docs/api/java/util/List.html
import java.util.*;
import java.lang.reflect.*;
public class SkipList<E> implements List<E>
{
// compiler complaining, then added, although optional
public E set(int index, E element)
{
throw new IndexOutOfBoundsException();
}
// compiler complaining, then added, although optional
public boolean addAll(Collection <? extends E> c)
{
return true;
}
// Group 1
public boolean add(E e)
{
return true;
}
public void add(int index, E e)
{
}
public boolean addAll(Collection c)
{
return true;
}
public int indexOf(Object o)
{
int index = 0;
return index;
}
public int lastIndexOf(Object o)
{
int index = 0;
return index;
}
// Group 2
public boolean contains(Object o)
{
return true;
}
public boolean containsAll(Collection c)
{
return true;
}
public boolean equals(Object o)
{
return true;
}
public List<E> subList(int fromIndex, int toIndex)
{
List<E> sub = new SkipList<>();
return sub;
}
// Group 3
public boolean isEmpty()
{
return true;
}
public int size()
{
int size = 0;
return size;
}
public void clear()
{
}
public E get(int index)
{
throw new IndexOutOfBoundsException();
}
public E getQuantile(double quantile) // e.g. 0 = minimum, 0.5 = median, 1 = max
{
throw new IndexOutOfBoundsException();
}
// Group 4
public Iterator<E> iterator()
{
throw new IndexOutOfBoundsException();
}
public ListIterator<E> listIterator()
{
throw new IndexOutOfBoundsException();
}
public ListIterator<E> listIterator(int index)
{
throw new IndexOutOfBoundsException();
}
// Group 5
public E remove(int index)
{
throw new IndexOutOfBoundsException();
}
public boolean remove(Object o)
{
return true;
}
public boolean removeAll(Collection c)
{
return true;
}
public boolean retainAll(Collection c)
{
return true;
}
// Group 6
public int hashCode()
{
int hashCode = 0;
return hashCode;
}
public Object[] toArray()
{
Object[] arr = new Object[0];
return arr;
}
public <T> T[] toArray(T[] a)
{
return a;
}
}
Turns out that when reading the API, for some reason I glossed over the other parameter for the addAll method, that led me to believe something else was wrong. I changed the method with the correct parameters and it compiled.
public boolean addAll(int index, Collection <? extends E> c)
{
return true;
}

Java Mutable data structures

Why do I keep getting an error when I try to execute this method,
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.ArrayList;
import java.util.HashSet;
public class BIAOperations <T extends Comparable<T>, E> implements Set<T>
{
private HashSet<T> Set;
public BIAOperations(){
Set = new HashSet<T>();
}
#Override
public boolean isEmpty()
{
if(Set.isEmpty())
{
return true;
}
else
return false;
}
#Override
public int size(){
return Set.size();
}
#Override
public int compareTo(Set<T> o) {
return 0;
}
#Override
public List<T> toList() {
List<T> list = new ArrayList<T>();
list.addAll(Set);
return list;
}
#Override
public Set<T> add(T x) {
Set.add(x);
return this;
}
#Override
public Set<T> remove(T x) {
Set.remove(x);
return this;
}
#Override
public boolean contains(T x)
{
if(Set.contains(x))
return true;
}
else
{
return false;
}
The error which I get is at the contains method at the bottom of the code.
the error I keep getting is void methods cannot return a value and on else I keep getting syntax error on else delete this token.
The else block is outside the method. Fix it as follows:
#Override
public boolean contains(T x)
{
if(Set.contains(x))
return true;
else
return false;
}
EDIT: you can also shorten this code as per #Unholysheep's suggestion in the comment.
#Override
public boolean contains(T x)
{
return Set.contains(x);
}
Also, as per #domdom's suggestion in the comment, use a better name for your object. In Java, I would recommend you use names starting with a small letter for your objects. Typically, names starting with a upper case letter are used for Class names. So instead of Set, use set or customSet or something for your object.

Java sorted and iterable Defaultlistmodel

I'm trying to extend the DefaultListModel so it will be sort-able and iterable. I found some code here http://www.javalobby.org/java/forums/t94074.html. I'm now trying to parameterize this code, but the addAll,containsAll,removeAll,retainAll, and toArray methods all give a name clash error. I kind of understand why this is, but I'm unsure how to fix it. Is there a better way to do this? Code below
package main;
import javax.swing.DefaultListModel;
import javax.swing.*;
import java.util.*;
public class DefaultListModelSort<E extends Object> extends DefaultListModel<E>
implements List<E> {
private Delegate m_delegate = new Delegate();
public DefaultListModelSort() {
super();
}
public DefaultListModelSort(Collection<E> c) {
this();
addAll(c);
}
public boolean add(E o) {
return m_delegate.add(o);
}
public boolean removeE(E o) {
return m_delegate.remove(o);
}
public boolean addAll(int index, Collection<E> c) {
return m_delegate.addAll(index, c);
}
public boolean addAll(Collection<E> c) {
return m_delegate.addAll(c);
}
public boolean containsAll(Collection<E> c) {
return m_delegate.containsAll(c);
}
public boolean removeAll(Collection<E> c) {
return m_delegate.removeAll(c);
}
public boolean retainAll(Collection<E> c) {
return m_delegate.retainAll(c);
}
public Iterator<E> iterator() {
return m_delegate.iterator();
}
public List<E> subList(int fromIndex, int toIndex) {
return m_delegate.subList(fromIndex, toIndex);
}
public ListIterator<E> listIterator() {
return m_delegate.listIterator();
}
public ListIterator<E> listIterator(int index) {
return m_delegate.listIterator(index);
}
public E[] toArray(E a[]) {
return m_delegate.toArray(a);
}
/**
* This class extends AbstractList so we get all the functionality of
* iterators and such for free.
*/
private class Delegate extends AbstractList<E> {
public Delegate() {
super();
}
public E get(int index) {
return DefaultListModelSort.super.get(index);
}
public int size() {
return DefaultListModelSort.super.size();
}
public E set(int index, E element) {
return DefaultListModelSort.super.set(index, element);
}
public void add(int index, E element) {
DefaultListModelSort.super.add(index, element);
}
public E remove(int index) {
return DefaultListModelSort.super.remove(index);
}
}
}
I'm trying to extend the DefaultListModel so it will be sort-able and
iterable.
use JTable with one Column, JTableHeader can be removed
for more info about RowSorter to read Oracle tutorial How to use Tables - Sorting and Filtering

Make a unique list of objects Java

I have an ArrayList filled with objects with attributes name and time. I would like to remove duplicates based on the name and keep only records with the latest time. So I have overriden equals and hashcode for name in my object and used code like this.
private List<ChangedRecentlyTO> groupRecords(List<ChangedRecentlyTO> toList) {
changedRecentlyList.clear(); //static list
for(ChangedRecentlyTO to : toList) {
if(!changedRecentlyList.contains(to)) {
changedRecentlyList.add(to);
} else {
if(changedRecentlyList.get(changedRecentlyList.lastIndexOf(to)).getTimeChanged().before(to.getTimeChanged())) {
changedRecentlyList.remove(to);
changedRecentlyList.add(to);
}
}
}
return changedRecentlyList;
}
But I am wondering, is there a better solution?I was thinking about using Set but I am not able to figure out how should I put there the time criterion.
You have to me two ways, one which requires understanding how the set work, and one which is more understandable for people who have littler understanding of Java Collections:
If you want to make it simple, you can simply read in the detail the Javadoc of Set, http://docs.oracle.com/javase/6/docs/api/java/util/Set.html#add(E). It clearly states that if an element is already inside, it won't be added again.
You implement your equals and hashcode using only the name
You sort the items by time and then you add them to the Set.
In such a way, the first time you will add the item to Set, you will be adding the elements with the latest times. When you'll add the others, they will be ignored because they are already contained.
If someone else who does not know exactly the contract of java.util.Set behaves, you might want to extend Set to make your intention clearer. However, since a Set is not supposed to be accessed to "get back an element after removal", you will need to back your set with an HashMap:
interface TimeChangeable {
long getTimeChanged();
}
public class TimeChangeableSet<E extends TimeCheangeable> implements Set<E> {
private final HashMap<Integer,E> hashMap = new HashMap<Integer,E>();
#Override
public boolean add(E e) {
E existingValue = hashMap.remove(e.hashCode());
if(existingValue==null){
hashMap.put(e.hashCode(),e);
return true;
}
else{
E toAdd = e.getTimeChanged() > existingValue.getTimeChanged() ? e : existingValue;
boolean newAdded = e.getTimeChanged() > existingValue.getTimeChanged() ? true : false;
hashMap.put(e.hashCode(),e);
return newAdded;
}
}
#Override
public int size() {
return hashMap.size();
}
#Override
public boolean isEmpty() {
return hashMap.isEmpty();
}
#Override
public boolean contains(Object o) {
return hashMap.containsKey(o.hashCode());
}
#Override
public Iterator<E> iterator() {
return hashMap.values().iterator();
}
#Override
public Object[] toArray() {
return hashMap.values().toArray();
}
#Override
public <T> T[] toArray(T[] a) {
return hashMap.values().toArray(a);
}
#Override
public boolean remove(Object o) {
return removeAndGet(o)!=null ? true : false;
}
public E removeAndGet (Object o) {
return hashMap.remove(o.hashCode());
}
#Override
public boolean containsAll(Collection<?> c) {
boolean containsAll = true;
for(Object object:c){
E objectInMap = removeAndGet(object);
if(objectInMap==null || !objectInMap.equals(object))
containsAll=false;
}
return containsAll;
}
#Override
public boolean addAll(Collection<? extends E> c) {
boolean addAll=true;
for(E e:c){
if(!add(e)) addAll=false;
}
return addAll;
}
#Override
public boolean retainAll(Collection<?> c) {
boolean setChanged=false;
for(E e: hashMap.values()){
if(!c.contains(e)){
hashMap.remove(e.hashCode());
setChanged=true;
}
}
return setChanged;
}
#Override
public boolean removeAll(Collection<?> c) {
throw new UnsupportedOperationException("Please do not use type-unsafe methods in 2012");
}
#Override
public void clear() {
hashMap.clear();
}
}
Extend HashMap and override put method to put only if new object is more recent than the existing one.
Or, you can create your own dedicated container which will be backed by a HashMap, just like some implementations of Stack are backed by LinkedList
This is a mock code:
import java.util.HashMap;
import java.util.Map;
public class TimeMap<K, V> {
private Map<K, V> timeMap;
public TimeMap() {
this.timeMap = new HashMap<K, V>();
}
public void put(K key, V value) {
if (isNewer(key, value)) {
this.timeMap.put(key, value);
}
}
}
Why you dont use a Set and later:
new ArrayList(set);
A very quick implementation of what I had in mind.
Assumed the ChangedRecentlyTO object had a name property.
private List<ChangedRecentlyTO> groupRecords(List<ChangedRecentlyTO> toList) {
Map<String, ChangedRecentlyTO> uniqueMap = new HashMap<String, ChangedRecentlyTO>();
for(ChangedRecentlyTO to : toList) {
if (uniqueMap.containsKey(to.getName())) {
if (uniqueMap.get(to.getName()).getTimeChanged().before(to.getTimeChanged())) {
uniqueMap.put(to.getName(), to);
}
} else {
uniqueMap.put(to.getName(), to);
}
}
return (List<ChangedRecentlyTO>) uniqueMap.values();
}
After all of that, it doesn't seem to different to your original implementation with the exception that there is no need override hashcode and equals.
You could let your class implement the Comparable interface and make compare check the timestamps you are interested in. If you then sort it (e.g. put all the elements in a TreeSet) and then get them out one by one, only if they don't already exist. Something like this:
public void removeDuplicates(List<MyObject> list){
SortedSet<MyObject> sortedSet = new TreeSet<MyObject>();
sortedSet.addAll(list);
//Now clear the list, and start adding them again
list.clear();
for(MyObject obj : sortedSet){
if(!list.contains(obj) {
list.add(obj);
}
}
return list;
}
This, however, will only work if two objects with different timestamps are not equal! (in the equals() sense of the word
What I would suggest , Make your class Comparable by implementing Comparable interface.Then in comparetTo() based on name and time compare them if object time is recent return 1 else 0(if equal) or -1 .Once you got this functionality you can extend HashMap class and override the put method like.
o1.compareTo(o2) > 0 then simply overwrite the object with latest one.
Adding logic to #Lopina code like
public class MyHashMap extends HashMap<String, MyClass>{
private Map<String, MyClass> timeMap;
public MyHashMap() {
this.timeMap = new HashMap<String, MyClass>();
}
public MyClass put(String key, MyClass value) {
MyClass obj;
if (isNewer(key, value)) {
System.out.println("count");
obj=this.timeMap.put(key, value);
}else{
obj=value;
}
return obj;
}
private boolean isNewer(String key, MyClass value) {
if(this.timeMap.get(key)==null ||( key.equals(value.getName()))&& (this.timeMap.get(key).compareTo(value))<0)
return true;
else
return false;
}
#Override
public int size() {
return this.timeMap.size();
}
#Override
public MyClass get(Object key) {
return this.timeMap.get(key);
}
}
In MyClass implement comparable interface and override compareTo method like below.
#Override
public int compareTo(MyClass o) {
return this.getTime().compareTo(o.getTime());
}
I wrote a UniqueList class that extends an ArrayList to back its data and utilises a HashSet to efficiently reject duplicates. This gives O(1) Random Access Time and many other speed improvements to manually sweeping the dataset.
https://gist.github.com/hopesenddreams/80730eaafdfe816ddbb1
public class UniqueList<T> extends ArrayList<T> implements Set<T>
{
HashMap<T,Integer> hash; // T -> int
public UniqueList()
{
hash = new HashMap<>();
}
/*
* O(n)
* */
#Override
public void add(int location, T object)
{
super.add(location, object);
for( int i = location ; i < size() ; i++ )
{
hash.put(get(i),i);
}
}
/*
* O(1) amortized.
* */
#Override
public boolean add(T object) {
if( hash.containsKey(object) ) return false;
hash.put(object, size());
super.add(object);
return true;
}
/*
* O(MAX(collection.size(),n)) because of the hash-value-shift afterwards.
* */
#Override
public boolean addAll(int location, Collection<? extends T> collection) {
boolean bChanged = false;
for( T t : collection)
{
if( ! hash.containsKey( t ) )
{
hash.put(t, size());
super.add(t);
bChanged = true;
}
}
for( int i = location + collection.size() ; i < size() ; i ++ )
{
hash.put( get(i) , i );
}
return bChanged;
}
/*
* O(collection.size())
* */
#Override
public boolean addAll(Collection<? extends T> collection) {
boolean bChanged = false;
for( T t : collection)
{
if( ! hash.containsKey( t ) )
{
hash.put( t , size() );
super.add(t);
bChanged = true;
}
}
return bChanged;
}
/*
* O(n)
* */
#Override
public void clear() {
hash.clear();
super.clear();
}
/*
* O(1)
* */
#Override
public boolean contains(Object object) {
return hash.containsKey(object);
}
/*
* O(collection.size())
* */
#Override
public boolean containsAll(Collection<?> collection) {
boolean bContainsAll = true;
for( Object c : collection ) bContainsAll &= hash.containsKey(c);
return bContainsAll;
}
/*
* O(1)
* */
#Override
public int indexOf(Object object) {
//noinspection SuspiciousMethodCalls
Integer index = hash.get(object);
return index!=null?index:-1;
}
/*
* O(1)
* */
#Override
public int lastIndexOf(Object object)
{
return hash.get(object);
}
/*
* O(n) because of the ArrayList.remove and hash adjustment
* */
#Override
public T remove(int location) {
T t = super.remove(location);
hash.remove( t );
for( int i = size() - 1 ; i >= location ; i -- )
{
hash.put( get(i) , i );
}
return t;
}
/*
* O(n) because of the ArrayList.remove and hash adjustment
* */
#Override
public boolean remove(Object object) {
Integer i = hash.get( object );
if( i == null ) return false;
remove( i.intValue() );
return true;
}
/*
* O( MAX( collection.size() , ArrayList.removeAll(collection) ) )
* */
#Override
public boolean removeAll(#NonNull Collection<?> collection) {
for( Object c : collection )
{
hash.remove( c );
}
return super.removeAll( collection );
}
}

Maximum Size List in Java

It's useful to me to have a data structure in Java that has all the functionality of a List, but has a maximum storage capacity, and drops older data when newer data is added. Conceivably at some point I might want to implement a fixed size Queue which keeps a more general ordering of the data, and drops the old data lowest in that ordering, but that's the for the future.
At the moment I'm implementing it like this:
public class FixedSizeList<T> {
private final int maxSize;
private final LinkedList<T> list = new LinkedList<T>();
public FixedSizeQueue(int maxSize) {
this.maxSize = maxSize < 0 ? 0 : maxSize;
}
public T add(T t) {
list.add(t);
return list.size() > maxSize ? list.remove() : null;
}
// add remaining methods...
}
Is there either (a) an existing data structure that serves my needs, or (b) a better way of implementing this data structure?
I would use array and 2 indexes for head and tail of the list.Make sure that head is always < tail and you're safe.
Here's a List with a size limit, based on Guava's ForwardingList:
A list which forwards all its method
calls to another list. Subclasses
should override one or more methods to
modify the behavior of the backing
list as desired per the decorator
pattern.
Guava has base classes like this for all JDK-5 Collection types. Each of them fulfills the same purpose: making it easy to add value, while delegating all default functionality to the underlying collection.
public class LimitingList<E> extends ForwardingList<E> {
private final class LimitingListIterator extends ForwardingListIterator<E> {
private final ListIterator<E> innerListIterator;
private LimitingListIterator(final ListIterator<E> innerListIterator) {
this.innerListIterator = innerListIterator;
}
/**
* {#inheritDoc}
*/
#Override
public void add(final E element) {
if (inner.size() < maxSize)
innerListIterator.add(element);
else
throw new IndexOutOfBoundsException();
}
#Override
protected ListIterator<E> delegate() {
return innerListIterator;
}
}
public LimitingList(final int maxSize) {
this(new ArrayList<E>(), maxSize);
}
public LimitingList(final List<E> inner, final int maxSize) {
super();
this.inner = inner;
this.maxSize = maxSize;
}
#Override
public boolean addAll(final Collection<? extends E> collection) {
boolean changed = false;
for (final E item : collection) {
final boolean tmpChanged = add(item);
changed = changed || tmpChanged;
if (!tmpChanged)
break;
}
return changed;
}
#Override
public boolean add(final E e) {
if (inner.size() < maxSize)
return super.add(e);
else
return false;
}
#Override
public ListIterator<E> listIterator() {
return new LimitingListIterator(inner.listIterator());
}
#Override
public void add(final int index, final E element) {
throw new UnsupportedOperationException();
}
#Override
public boolean addAll(final int index, final Collection<? extends E> elements) {
throw new UnsupportedOperationException();
}
#Override
public ListIterator<E> listIterator(final int index) {
return new LimitingListIterator(inner.listIterator(index));
}
private final int maxSize;
private final List<E> inner;
#Override
protected List<E> delegate() {
return inner;
}
}
It delegates all real functionality to an underlying list, which is an ArrayList per default (single argument constructor), but you can also supply (two argument constructor)
Unless you want to use an actual array, I don't believe there is a list type data structure you can use.
Personally I would extend one of the existing list classes to get the functionality, and override the add methods. This way you get all the other list operations for free. ie something like the following...
public class FixedSizeArrayList<T> extends ArrayList<T> {
private final int maxSize;
public FixedSizeArrayList(int maxSize) {
super();
this.maxSize = maxSize
}
public boolean add(T t) {
if (size() >= maxSize) {
remove(0);
}
return super.add(t);
}
// implementation of remaining add methods....
}
If you extend the LinkedList class you will have direct access to all it's methods. Instead of having to write stuff like
fixedList.getList().pop()
you could just write
fixedList.pop()
You could then override the methods where you need to add the maxSize criteria.

Categories

Resources