固定容量の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日時みたいな概念を持たせた方がいいかも。
あと、スレッドセーフではない。