0

数値のコレクション全体の合計を出したいです。しかし、戻り値の種類を示したいと思います。たとえば、double コレクションの合計を計算したいのですが、Integer を取得したいとします。この SumAggregator のようなものが欲しいです。これが私が開発したコードですが、キャストの問題があります。

public class SumAggregator<N1 extends Number, N2 extends Number> {

    public SumAggregator() {

    }

    public N2 sum(Collection<? extends N1> list){
        Double sum = 0;
        for(Number n : list){
        sum += n.doubleValue();
        }
        return (N2) sum;
    }

}

やりたいと思ったらSumAggregator<Double, Double>何の問題もありません。しかし、実行したい場合はSumAggregator<Double, Integer>、実行すると次の例外が発生します。 java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer

これを解決する方法はありますか?

4

2 に答える 2

0

これは私が選択したソリューションです:

public class SumAggregator<N1 extends Number, N2 extends Number> {

    private final NumberConverter<N2> converter;

    public SumAggregator(NumberConverter<N2> converter) {
        this.converter = converter;
    }

    public N2 sum(Collection<? extends N1> list){
        double sum = 0;
        for(Number n : list){
            sum += n.doubleValue();
        }
        return converter.convert(sum);
    }

}

その後:

public interface NumberConverter<N2> {

    N2 convert(Number d);

    NumberConverter<Short> SHORT = new NumberConverter<Short>() {
        public Short convert(Number d) { 
            return d.shortValue(); 
        }
    };

    NumberConverter<Integer> INTEGER = new NumberConverter<Integer>() {
        public Integer convert(Number d) { 
            return d.intValue(); 
        }
    };

    NumberConverter<Double> DOUBLE = new NumberConverter<Double>() {
        public Double convert(Number d) { 
            return d.doubleValue(); 
        }
    };

    NumberConverter<Float> FLOAT = new NumberConverter<Float>() {
        public Float convert(Number d) { 
            return d.floatValue(); 
        }
    };

    NumberConverter<Long> LONG = new NumberConverter<Long>() {
        public Long convert(Number d) { 
            return d.longValue(); 
        }
    };

}
于 2013-08-05T17:14:43.340 に答える
0

まさにあなたが望んでいたものではありませんが、次のようなことができます:

interface DoubleConverter<N extends Number) {
    N2 convert(double d);
}

SumAggregator にコンストラクターを追加します。

private final DoubleConverter<N2> converter;
public SumAggregator(DoubleConverter<N2> converter) {
    this.converter = converter;
}

そして、あなたの方法は次のようになります:

public N2 sum(Collection<? extends N1> list){
    double sum = 0;
    for(Number n : list){
        sum += n.doubleValue();
    }
    return converter.convert(sum);
}

最後に、次のものを作成します。

SumAggregator<Double, Integer> a = new SumAggregator<> (new DoubleConverter<Integer>() {
    public Integer convert(double d) { return (int) d; }
});

最後に、DoubleConverter インターフェイスにいくつかのヘルパー メソッドを追加できます。

DoubleConverter<Integer> INTEGER = new DoubleConverter<Integer>() {
    public Integer convert(double d) { return (int) d; }
}

そのため、呼び出し元のコードは次を使用できます。

SumAggregator<Double, Integer> a = new SumAggregator<> (DoubleConverter.INTEGER);
于 2013-08-04T21:21:33.780 に答える