Google collection Library の Predicate を読んで、思いついたのがこれ。
ソースは static メソッドを提供するものと、3個の interface と public でないクラス2個の
合計6個
--------------------------
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
/**
* コレクションへの追加の制限インターフェースを実装したインスタンスを指定して挿入時制限付きコレクションを
* 生成する。
* public interface ListPredicate<E> → ArrayList 生成に使用する Predicate
* public interface TreePredicate<T> → TreeSet,TreeMap 生成に使用する Predicate
* public interface MapPredicate<K,V> → HashMap 生成に使用する Predicate
* これら Predicate を引数に持つコレクション生成メソッドを提供する。
* public static <T> Set<T> createTreeSet(final TreePredicate<T> predicate) → 制限付き TreeSet 生成
* public static <K,V> Map<K,V> createTreeMap(final TreePredicate<K> predicate) → 制限付き TreeMap 生成
* public static <E> List<E> createArrayList(ListPredicate<E> predicate) → 制限付き ArrayList 生成
* public static <K,V> Map<K,V> createHashMap(MapPredicate<K,V> predicate) → 制限付き HashMap 生成
*/
public final class LimitCollections{
private LimitCollections(){}
public static <T> Set<T> createTreeSet(final TreePredicate<T> predicate){
return new TreeSet<T>(new Comparator<T>(){
@SuppressWarnings("unchecked")
@Override
public int compare(T t1,T t2){
if (!predicate.apply(t1)) return 0;
return predicate.compare(t1,t2);
}
}
);
}
public static <K,V> Map<K,V> createTreeMap(final TreePredicate<K> predicate){
return new TreeMap<K,V>(new Comparator<K>(){
@SuppressWarnings("unchecked")
@Override
public int compare(K k1,K k2){
if (!predicate.apply(k1)) return 0;
return predicate.compare(k1,k2);
}
}
);
}
public static <E> List<E> createArrayList(ListPredicate<E> predicate){
return new LimitArrayList<E>(predicate);
}
public static <K,V> Map<K,V> createHashMap(MapPredicate<K,V> predicate){
return new LimitHashMap<K,V>(predicate);
}
}
--------------------------
import java.util.Comparator;
/**
* 制限付きの TreeSet,TreeMap 生成に使用する Predicate.
* 実装インスタンスの apply メソッドの戻り値 boolean値によって、
* TreeSet,TreeMap へ要素を格納をするかどうかの判断がなされます。
* TreeMap の場合、apply メソッドの引数は、Map 格納時、put メソッドの Key に相当します。
*/
public interface TreePredicate<T> extends Comparator{
/**
* 対象コレクションへの追加の許可
* @param t 追加する要素、または、TreeMap の場合は、Key
* @return true=追加を許可する
*/
public boolean apply(T t);
}
--------------------------
public interface ListPredicate<E>{
public boolean apply(E e);
}
--------------------------
public interface MapPredicate<K,V>{
public boolean apply(K k,V v);
}
--------------------------
import java.util.ArrayList;
import java.util.Collection;
final class LimitArrayList<E> extends ArrayList<E>{
private static final long serialVersionUID = 1L;
private ListPredicate<E> predicate;
protected LimitArrayList(ListPredicate<E> predicate){
this.predicate = predicate;
}
@Override
public void add(int index,E e){
if (this.predicate.apply(e)){
super.add(index,e);
}
}
@Override
public boolean add(E e){
return this.predicate.apply(e) ? super.add(e) : false;
}
@Override
public boolean addAll(Collection<? extends E> c){
boolean rtn = false;
for(E e : c){
rtn |= this.add(e);
}
return rtn;
}
@Override
public boolean addAll(int index,Collection<? extends E> c){
if (c.size() < 1) return false;
int ix = index;
for(E e : c){
if (this.predicate.apply(e)){
this.add(ix,e);
ix++;
}
}
return true;
}
}
--------------------------
import java.util.HashMap;
import java.util.Map;
final class LimitHashMap<K,V> extends HashMap<K,V>{
private static final long serialVersionUID = 1L;
private MapPredicate<K,V> predicate;
protected LimitHashMap(MapPredicate<K,V> predicate){
this.predicate = predicate;
}
@Override
public V put(K key,V value){
if (this.predicate.apply(key,value)){
return super.put(key,value);
}
return null;
}
@Override
public void putAll(Map<? extends K,? extends V> m){
for(K k : m.keySet()){
V v = m.get(k);
if (this.predicate.apply(k,v)){
super.put(k,v);
}
}
}
}