2011-12-29 22 views
9

私は総称してJavaで数字を追加したいと思います。 Numbersクラスは私がやりたいことを本当にサポートしていないので、難しかったです。これまで私が試したことは次のとおりです。Javaジェネリックスと一緒に番号を追加する

public class Summer<E extends Number> { 


    public E sumValue(List<E> objectsToSum) { 
     E total = (E) new Object(); 
     for (E number : objectsToSum){ 
      total += number; 
     } 
     return null; 

    } 

これは明らかに動作しません。 <int>または<long>などのリストが与えられ、合計を返すことができるように、このコードを修正するにはどうすればよいですか?

+1

異なるNumberサブクラスを含むリストをお持ちの場合はどうなりますか?例えば。 'Arrays.asList(5L、1e100、42)'? – kan

+0

@stackoverflow.com/questions/285754/java-using-generics-to-implement-a-class-that-operates-on-different-kinds-of-nuの重複 –

+0

@kan - 私はそれらはすべてタイプEではないので、エラーが発生します。 –

答えて

11

は、一般的に合計を計算するためには、次の2つの操作を提供する必要があります。

  • ゼロ項目
  • 2つの項目
  • Javaでは

を合計する方法を合計する方法を、あなたそれはインターフェイスを介して行います。ここに完全な例があります:

import java.util.*; 

interface adder<T extends Number> { 
    T zero(); // Adding zero items 
    T add(T lhs, T rhs); // Adding two items 
} 

class CalcSum<T extends Number> { 
    // This is your method; it takes an adder now 
    public T sumValue(List<T> list, adder<T> adder) { 
     T total = adder.zero(); 
     for (T n : list){ 
      total = adder.add(total, n); 
     } 
     return total; 
    } 
} 

public class sum { 
    public static void main(String[] args) { 
     List<Integer> list = new ArrayList<Integer>(); 
     list.add(1); 
     list.add(2); 
     list.add(4); 
     list.add(8); 
     CalcSum<Integer> calc = new CalcSum<Integer>(); 
     // This is how you supply an implementation for integers 
     // through an anonymous implementation of an interface: 
     Integer total = calc.sumValue(list, new adder<Integer>() { 
      public Integer add(Integer a, Integer b) { 
       return a+b; 
      } 
      public Integer zero() { 
       return 0; 
      } 
     }); 
     System.out.println(total); 
    } 
} 
+0

+1そのより具体的な受け入れられた答え。しかし、問題は本当に問題を解決していません。なぜなら問題は「一般的な」加算器を書くことにあるからです。 – Stefan

+0

@Stefan It *は、少なくとも型消去ルールを持つJavaでは、一般的な加算器です。何らかの種類のインタフェース以外の方法で、Javaで追加プリミティブを提供する他の方法はありません。 – dasblinkenlight

+0

あなたはまだSummerのために持っていたのと同じように、すべてのNumber型に対して加算器の実装を提供する必要があります。私は、この問題が新しいジェネリック型などである可能性があるので、ジェネリック(Javaジェネリックスのようにではない)の方法では全く解決できないと言っている限り、行っていきます。 – Stefan

1

Numberは操作をサポートしていないため、必要な型に値をキャストする必要があります。例えばNumberがBigDecimalの場合、+=演算子はありません。

3

Numberクラスでは計算を実行するためのインターフェイスが公開されていないため、この問題を解決する唯一の方法は、サポートされている数値タイプごとに必要な操作をカプセル化するクラスを作成することです。あなたのクラスよりも、特定のタイプを使用する必要があります。

0

ランタイムタイプ(たとえばinstanceofを使用)を確認し、既知のタイプにキャストし、適切な加算操作を行う必要があります。リストにさまざまな数値型が多数含まれる可能性があることを考慮して、結果のタイプが何であるかはわかりません。

+0

そしておそらく未知数(書いている時点で)の数値型。 – Stefan

1

数値には、intValue()、floatValue()、doubleValue()、longValue、およびshortValue()があります。 1つを選択して使用します。たとえば、

double total; 
total += number.doubleValue(); 

return total; 

また、Javaジェネリックは、決してC++テンプレートに相当しません。 Javaジェネリック型の新しいインスタンスを割り当てることはできません。これは働くことはできません。

E hoot = (E) new Object(); 

は最後に、longshortintdouble、およびfloatは、クラスのタイプではありません。それらは基本型です。したがって、Javaジェネリックでは使用できません。

+0

BigDecimal(それも数字です)はどうですか?どちらの関数も、多くの場合、「正しい」値を返しません。 – Stefan