2

率直に言って、私はジェネリックの第一人者には程遠いので、いくつかのコードをリファクタリングする必要があります。クラスD、クラスR、クラスSの 3 つのサブクラスがあります。これらの各クラスは、クラスAbstractAを拡張します。サブクラスの目的は非常に似ており、それぞれがメソッドm()に似たようなコードを持っています。したがって、サブクラスからメソッド m() を抽出し、それを 1 レベル上に (AbstractA クラスに) 置き換えることができれば、悪くないと思いました。

ただし、いくつかの違いがあります。

クラス D は次のものと連携します。

Map<String, Map<BigInteger, BigInteger>> counts = new HashMap<String, Map<BigInteger,BigInteger>>();
Map<String, Map<BigDecimal, Set<BigInteger>>> sums = new HashMap<String, Map<BigDecimal, Set<BigInteger>>>();

クラスRは以下で動作します:

Map<String, Map<String, BigInteger>> counts = new HashMap<String, Map<String,BigInteger>>();
Map<String, Map<BigDecimal, Set<String>>> sums = new HashMap<String, Map<BigDecimal, Set<String>>>();

クラス S は次のように動作します。

Map<String, Map<BigInteger, BigInteger>> counts = new HashMap<String, Map<BigInteger,BigInteger>>();
Map<String, Map<BigDecimal, BigInteger>> sums = new HashMap<String, Map<BigDecimal, BigInteger>>();

上記のジェネリックの可能な変更に関するヒントは大歓迎です。これにより、より「ジェネリック」なバージョンが作成される可能性があります(クラス AbstractA に移動でき、3 つのサブクラスで引き続き使用できます)。

4

4 に答える 4

3
 class AbstractA<T,U> {
    Map<String, Map<T, BigInteger>> counts = new HashMap<String, Map<T,BigInteger>>();
    Map<String, Map<BigDecimal, U>> sums = new HashMap<String, Map<BigDecimal, U>>();
 }
 class AbstractB<T> extends AbstractA<T, Set<T>> {
 }
 class D extends AbstractB<BigInteger> {
 }
 class R extends AbstractB<String> {
 }
 class S extends AbstractA<BigInteger, BigInteger> {
 }
于 2013-01-07T13:04:09.813 に答える
2

次の 2 つの汎用パラメーターのみが必要です。

public abstract class AbstractA<K, V> {
    private Map<String, Map<K, BigInteger>> counts = new HashMap<String, Map<K, BigInteger>>();
    private Map<String, Map<BigDecimal, V>> sums = new HashMap<String, Map<BigDecimal, V>>();

    public void m() {
    }
}


public class D extends AbstractA<BigInteger, Set<BigInteger>> {
}

public class R extends AbstractA<String, Set<String>> {
}

public class S extends AbstractA<BigInteger, BigInteger> {
}
于 2013-01-07T13:08:56.797 に答える
0

String最初に行う必要があるのは、との間に共通性を作成することですBigIntegercomposed次の 2 つのタイプの 新しいクラスを作成することをお勧めします。

public class Special  
{  
    private String string;  
    private BigInteger bigInt;  
    ...
}  

Mapこれで、次のよう にパラメーターを変更できます。

Map<String, Map<Special, BigInteger> ...  

これで、呼び出しを各サブクラスに残して、m関数AbstractAをいずれかとしてマークするかabstract、オーバーライド可能な実装を提供できます。

于 2013-01-07T12:55:31.073 に答える
0

次の実装はどうですか?

public abstract class AbstractA<K1, V1, K2, V2> {

    protected Map<String, Map<K1, V1>> counts;
    protected Map<String, Map<K2, V2>> sums;

    public void m() {
        // your factorized code using counts and sums
    }

}

public class D extends AbstractA<BigInteger, BigInteger, BigDecimal, Set<BigInteger>> {

    public D() {
        counts = new HashMap<String, Map<BigInteger, BigInteger>>();
        sums = new HashMap<String, Map<BigDecimal, Set<BigInteger>>>();
    }

}

public class R extends AbstractA<String, BigInteger, BigDecimal, Set<String>> {

    public R() {
        counts = new HashMap<String, Map<String, BigInteger>>();
        sums = new HashMap<String, Map<BigDecimal, Set<String>>>();
    }

}

public class S extends AbstractA<BigInteger, BigInteger, BigDecimal, BigInteger> {

    public S() {
        counts = new HashMap<String, Map<BigInteger, BigInteger>>();
        sums = new HashMap<String, Map<BigDecimal, BigInteger>>();
    }

}
于 2013-01-07T13:00:37.840 に答える