ループせずにArrayListの合計の可能性はありますか


88

ArrayListループなしの合計の可能性はありますか?

PHPはsum(array)、配列の合計を与えるものを提供します。

PHPコードは次のようなものです

$a = array(2, 4, 6, 8);
echo "sum(a) = " . array_sum($a) . "\n";

私はJavaでも同じことをしたかった:

List tt = new ArrayList();
tt.add(1);
tt.add(2);
tt.add(3);

2
ArrayList「合計可能」なものが含まれていない場合はどうなりますか?ArrayListと配列は必ずしも同じものではありません。配列内の数値の合計に関しては、要素のループと累積合計の計算は非常に簡単です。
posdef

PHP関数array_sumも内部でループを実行し、ユーザーからループを非表示にします。
–PaŭloEbermann 2011

1
それは合理的な質問です。結局のところ、リスト内で最大の要素を見つけるためにループを作成するのはほとんど簡単ですが、java.util.Collectionsはmax()メソッドを提供します。
John Velonis 2014年

1
結局のところ、非常に合理的な質問が方法のポイントですよね?再利用:)
ベンタリアドロス2014

ループは美しいです。
Alex78191 2018

回答:


156

一度 出ています(2014年3月)ストリーム使用できるようになります

あなたが持っている場合 List<Integer>

int sum = list.stream().mapToInt(Integer::intValue).sum();

それが int[]

int sum = IntStream.of(a).sum();

5
map暗黙的にループを使用
Nikos M.

8
再帰を使用してループを使用しないようにすることができます。:D(これをしないでください)
Caleb Fenton 2016

23

次に、自分で書きます。

public int sum(List<Integer> list) {
     int sum = 0; 

     for (int i : list)
         sum = sum + i;

     return sum;
}

1
または、sumメソッドを使用してArrayListを拡張し、独自のArrayListに組み込みます。
ビュラー

3
実際の加算を行うときは、単純なを使用する方が良いでしょうint。ここではInteger、Javaの自動ボクシング機能を使用する価値はほとんどありません。また、タイプIntegerであるため、毎回、潜在的に多くの新しいオブジェクトを作成および再作成していますImmutable
Java Drinker

10

ループを使用する唯一の方法は、再帰を使用することです。

次のようなメソッドを定義できます

public static int sum(List<Integer> ints) {
   return ints.isEmpty() ? 0 : ints.get(0) + ints.subList(1, ints.length());
}

これは、プレーンループを使用する場合に比べて非常に非効率的であり、リストに多くの要素がある場合に爆発する可能性があります。

スタックオーバーフローを回避する別の方法は、を使用することです。

public static int sum(List<Integer> ints) {
    int len = ints.size();
    if (len == 0) return 0;
    if (len == 1) return ints.get(0);
    return sum(ints.subList(0, len/2)) + sum(ints.subList(len/2, len));
}

これも同様に非効率的ですが、スタックオーバーフローを回避します。


同じことを書く最短の方法は

int sum = 0, a[] = {2, 4, 6, 8};

for(int i: a) {
    sum += i;
}

System.out.println("sum(a) = " + sum);

プリント

sum(a) = 20

コードでは、最初の再帰的定義でのsum()の呼び出しを見逃しています。2番目の再帰的定義は、スタックオーバーフローの発生を防ぐものではなく、発生する可能性を低くします。
Teudimundo 2015

1
@Teudimundo True、それを防ぐことはできませんが、リストの最大サイズはInteger.MAX_VALUEであり、log2は最大深度である31です。ほとんどのシステムには制限として何千もの呼び出しがありますが、これに非常に近い場合でも、それは失敗する可能性があります。
Peter Lawrey 2015

9

次のようなutil関数を記述します

public class ListUtil{

    public static int sum(List<Integer> list){
      if(list==null || list.size()<1)
        return 0;

      int sum = 0;
      for(Integer i: list)
        sum = sum+i;

      return sum;
    }
}

次に、次のように使用します

int sum = ListUtil.sum(yourArrayList)

しかし、arraylistの長い値に対してどのようにそれを行うことができますか?
Ravi Parmar 2011

5

私にとって最も明確な方法はこれです:

doubleList.stream().reduce((a,b)->a+b).get();

または

doubleList.parallelStream().reduce((a,b)->a+b).get();

内部ループも使用しますが、ループなしでは不可能です。


2

apache commons-collectionsAPIを使用できます。

class AggregateClosure implements org.apache.commons.collections.Closure {
        int total = 0;

        @Override
        public void execute(Object input) {
            if (input != null) {
                total += (Integer) input;
            }
        }

        public int getTotal() {
            return total;
        }
    }

次に、以下に示すようにこのクロージャを使用します。

public int aggregate(List<Integer> aList) {
        AggregateClosure closure = new AggregateClosure();
        org.apache.commons.collections.CollectionUtils.forAllDo(aList, closure);
        return closure.getTotal();
}

1

map関数について知っている場合は、マップが再帰ループまたは再帰ループになることもあることを知っています。しかし、明らかにそのためには各要素に到達する必要があります。そのため、構文の不一致があったため、Java 8を解決できませんでしたが、非常に短いものが必要だったため、これが得られました。

int sum = 0
for (Integer e : myList) sum += e;

あなたが正しいです。末尾再帰になる可能性があるマップではなく、最小限のループだと言いました。
sivi 2015

「ループせずにArrayListの合計の可能性はありますか」
alexander 2016年

0

リストは任意のタイプのオブジェクトを保持できるため、すべての要素を合計できる組み込みのメソッドはありません。あなたはこのようなことをすることができます:

int sum = 0;

for( Integer i : ( ArrayList<Integer> )tt ) {
  sum += i;
}

または、ArrayListを継承するだけでなく、上記のコードを実装するsum()というメソッドを実装する独自のコンテナータイプを作成することもできます。


0

ArrayListは要素のコレクション(リスト形式)であり、プリミティブはラッパークラスオブジェクトとして格納されますが、同時にStringクラスのオブジェクトも格納できます。SUMはその点では意味がありません。ところで、とにかくforループ(拡張またはイテレータを介して)を使用することをなぜそれほど恐れているのですか?


0

または、Groovyに切り替えると、コレクションにsum()関数があります。[1,2,3,4,5,6] .sum()

http://groovy.codehaus.org/JN1015-コレクション

Javaクラスと同じJVMで実行されます。


8
ええ。合計関数は間違いなく別の言語に切り替える理由です。:D
ruX 2014年

1
質問にはタグが付けられているJavaため、これは技術的には有効な回答ではありません。
bengt 2014

0

このリンクは、Javaで合計する3つの異なる方法を示しています。ApacheCommonsMathを使用した以前の回答にはないオプションが1つあります。

例:

public static void main(String args []){
    List<Double> NUMBERS_FOR_SUM = new ArrayList<Double>(){
         {
            add(5D);
            add(3.2D);
            add(7D);
         }
    };
    double[] arrayToSume = ArrayUtils.toPrimitive(NUMBERS_FOR_SUM
            .toArray(new Double[NUMBERS_FOR_SUM.size()]));    
    System.out.println(StatUtils.sum(arrayToSume));

}

参照StatUtilsのAPI


0

GNUTroveライブラリを使用できます。

TIntList tt = new TIntArrayList();
tt.add(1);
tt.add(2);
tt.add(3);
int sum = tt.sum();

0

これは、メソッド参照を使用してreduceで実行できますreduce(Integer::sum)

Integer reduceSum = Arrays.asList(1, 3, 4, 6, 4)
        .stream()
        .reduce(Integer::sum)
        .get();

またはなしOptional

Integer reduceSum = Arrays.asList(1, 3, 4, 6, 4)
        .stream()
        .reduce(0, Integer::sum);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.