365連休

にわかのandroidとかの開発メモ。

Java 固定容量のLimitedSet

固定容量のHashSetが欲しくて、ググったらjavaのライブラリには無いみたいで、ArrayListを継承したりして実装する例があったが、Iteratorとか全部Overrideするとめんどくさい。

個人的に欲しかった機能は、固定容量のSetがあって、容量が足りなくなった時に古いものを上書きしてほしかっただけなので、作ってみた。

 

 

/** 固定容量のSet、上限に達した場合古いものを削除する */
public class LimitedSet<E> {
    private final int limit;
    private final @NonNull Object[] array;
    private int index;
    public LimitedSet(int limit) {
        this.limit = limit; //正確には0以下や大きすぎる値はthrowしなければならない。
        array = new Object[limit];
        index = 0;
    }
    /** 要素を追加する、容量の上限に達している場合、最も古い要素を削除する
     * @return 追加された場合true / 既に存在した場合false */
    public boolean add(@NonNull E e){
        if(contains(e)){
            return false;
        }
        array[index%limit] = e;
        index++;
        return true;
    }
    /** 指定された要素が存在するか
     * @return 存在する場合true / 存在しない場合false */
    public boolean contains(@NonNull E e){
        for(@Nullable Object o: array){
            if(e.equals(o)){
                return true;
            }
        }
        return false;
    }
    @Override
    public @NonNull String toString() {
        return Arrays.toString(array);
    }
}

テスト結果

16:13:19.314	Test LimitedSet. new LimitedSet<>(5)=[null, null, null, null, null]
16:13:19.315	add("0")=true
16:13:19.316	add("1")=true
16:13:19.316	add("2")=true
16:13:19.316	retry. now=[0, 1, 2, null, null]
16:13:19.316	add("-2")=true
16:13:19.316	add("-1")=true
16:13:19.322	add("0")=false
16:13:19.322	add("1")=false
16:13:19.322	add("2")=false
16:13:19.322	retry. now=[0, 1, 2, -2, -1]
16:13:19.322	add("0")=false
16:13:19.322	add("1")=false
16:13:19.322	add("2")=false
16:13:19.323	add("3")=true
16:13:19.323	add("4")=true
16:13:19.323	now=[3, 4, 2, -2, -1]

テスト結果から分かるように初めてaddされた順に削除されていく。Priorityや最終add日時みたいな概念を持たせた方がいいかも。
あと、スレッドセーフではない。