そこで、一定の Comparator 実装クラスをインジェクトさせる方法を考えた。
でも、当たり前の制約はある。
ソート対象のオブジェクトが Comparable#compareTo を実行できるインスタンスを
取得するメソッドを公開(public)できることである。
import java.lang.reflect.Method;
import java.util.Comparator;
import java.util.TreeSet;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
public final class TreeSetFactory{
private TreeSetFactory(){}
// ソート対象のクラスと Comparable#compareTo を実行できるインスタンスを取得する getter 名を指定
@SuppressWarnings("unchecked")
public static <T> TreeSet<T> createASC(final Class<T> cls,final String getterName){
Injector injector = Guice.createInjector(new AbstractModule(){
@Override
protected void configure(){
try{
binder().bind(Method.class).toInstance(cls.getMethod(getterName));
}catch(Exception e){
throw new RuntimeException(e);
}
binder().bind(Comparator.class).to(AscComparator.class);
}
}
);
return injector.getInstance(StencilTreeSet.class);
}
public static <T> TreeSet<T> createUniqueASC(final Class<T> cls,final String getterName){
Injector injector = Guice.createInjector(new AbstractModule(){
@Override
protected void configure(){
try{
binder().bind(Method.class).toInstance(cls.getMethod(getterName));
}catch(Exception e){
throw new RuntimeException(e);
}
binder().bind(Comparator.class).to(AscUniqueComparator.class);
}
}
);
return injector.getInstance(StencilTreeSet.class);
}
// 降順も同様に用意する。
// binder().bind(Comparator.class).to で指定するクラスは以下
// DescComparator.class → 重複許可の降順
// DescUniqueComparator.class → 重複させない降順
}
============================================
import java.lang.reflect.Method;
import java.util.Comparator;
import com.google.inject.Inject;
// 重複許可の昇順
class AscComparator<T> implements Comparator<T>{
@Inject private Method getterMethod;
@SuppressWarnings("unchecked")
@Override
public int compare(T o1,T o2){
try{
return *1.compareTo*2 >= 0 ? 1 : -1;
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
// 重複させない昇順(先行が残る)
class AscUniqueComparator<T> implements Comparator<T>{
@Inject private Method getterMethod;
@SuppressWarnings("unchecked")
@Override
public int compare(T o1,T o2){
try{
return *3.compareTo*4;
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
// 重複許可の降順
class DescComparator<T> implements Comparator<T>{
@Inject private Method getterMethod;
@SuppressWarnings("unchecked")
@Override
public int compare(T o1,T o2){
try{
return *5.compareTo*6 >= 0 ? -1 : 1;
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
// 重複させない降順(先行が残る)
class DescUniqueComparator<T> implements Comparator<T>{
@Inject private Method getterMethod;
@SuppressWarnings("unchecked")
@Override
public int compare(T o1,T o2){
try{
return -1 * *7.compareTo*8;
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
============================================
import java.util.Comparator;
import java.util.TreeSet;
import com.google.inject.Inject;
class StencilTreeSet<T> extends TreeSet<T>{
@SuppressWarnings("unchecked")
@Inject
protected StencilTreeSet(Comparator c){
super(c);
}
}
============================================
Setの作成例、
Sampleオブジェクトのソート対象の属性が日付で、getter名が、"getDate"である時
Set<Sample> set = TreeSetFactory.createASC(Sample.class,"getDate");
*1:Comparable<T>)this.getterMethod.invoke(o1
*2:T)this.getterMethod.invoke(o2
*3:Comparable<T>)this.getterMethod.invoke(o1
*4:T)this.getterMethod.invoke(o2
*5:Comparable<T>)this.getterMethod.invoke(o1
*6:T)this.getterMethod.invoke(o2
*7:Comparable<T>)this.getterMethod.invoke(o1
*8:T)this.getterMethod.invoke(o2