Gibt es die Möglichkeit der Summe von ArrayList ohne Schleife

87

Gibt es die Möglichkeit der Summe ArrayListohne Schleife?

PHP bietet sum(array)die Summe der Arrays.

Der PHP-Code ist wie

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

Ich wollte dasselbe in Java tun:

List tt = new ArrayList();
tt.add(1);
tt.add(2);
tt.add(3);
Tapsi
quelle
2
Was ist, wenn das ArrayListnicht etwas enthält, das "summierbar" ist? ArrayList und ein Array sind nicht unbedingt dasselbe. Das Summieren von Zahlen in einem Array ist eine sehr einfache Schleife über die Elemente und das Berechnen einer kumulativen Summe.
Posdef
Die PHP-Funktion führt array_sumauch intern eine Schleife durch, sie versteckt sie nur vor dem Benutzer.
Paŭlo Ebermann
1
Das ist eine vernünftige Frage. Immerhin ist es fast genauso trivial, eine Schleife zu schreiben, um das größte Element in einer Liste zu finden, doch java.util.Collections bietet eine max () -Methode.
John Velonis
1
Sehr vernünftige Frage, das ist doch der Sinn der Methoden, oder? Wiederverwendung :)
Ben Taliadoros
Loops sind wunderschön.
Alex78191

Antworten:

153

Einmal ist aus (März 2014) Sie können Streams verwenden :

Wenn Sie eine haben List<Integer>

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

Wenn es ein ist int[]

int sum = IntStream.of(a).sum();
msayag
quelle
5
mapverwendet implizit Schleifen
Nikos M.
6
Sie können die Rekursion verwenden, um keine Schleife zu verwenden. : D (nicht tun)
Caleb Fenton
23

Dann schreibe es selbst:

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

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

     return sum;
}
Erhan Bagdemir
quelle
1
Oder erweitern Sie ArrayList mit der Summenmethode, damit Sie sie in Ihre eigene ArrayList integrieren können.
Bueller
3
Bei der eigentlichen Hinzufügung ist es einfach schöner, eine einfache zu verwenden int. Die Verwendung Integermit den Auto-Boxing-Funktionen von Java ist hier wenig sinnvoll. Außerdem erstellen und erstellen Sie Integerjedes Mal potenziell viele neue Objekte, da es sich um einen ImmutableTyp handelt.
Java Drinker
10

Die einzige Alternative zur Verwendung einer Schleife ist die Verwendung der Rekursion.

Sie können eine Methode wie definieren

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

Dies ist im Vergleich zur Verwendung einer einfachen Schleife sehr ineffizient und kann explodieren, wenn Sie viele Elemente in der Liste haben.

Eine Alternative, die einen Stapelüberlauf vermeidet, ist die Verwendung.

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));
}

Dies ist ebenso ineffizient, vermeidet jedoch einen Stapelüberlauf.


Der kürzeste Weg, dasselbe zu schreiben, ist

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

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

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

druckt

sum(a) = 20
Peter Lawrey
quelle
Im Code verpassen Sie den Aufruf von sum () in der ersten rekursiven Definition. Die zweite rekursive Definition verhindert nicht das Auftreten eines Stapelüberlaufs, sondern verringert die Wahrscheinlichkeit.
Teudimundo
1
@Teudimundo True, obwohl dies nicht verhindert wird, ist die maximale Größe einer Liste Integer.MAX_VALUE und log2 ist 31, was der maximalen Tiefe entspricht. Die meisten Systeme haben viele tausend Anrufe als Limit, aber wenn Sie dem sehr nahe sind, kann es immer noch explodieren.
Peter Lawrey
9

Schreiben Sie eine util-Funktion wie

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;
    }
}

Dann benutze gerne

int sum = ListUtil.sum(yourArrayList)
Nishant
quelle
aber wie kann ich es für einen langen Wert in Arraylist tun?
Ravi Parmar
5

Für mich ist der klarste Weg:

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

oder

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

Es werden auch interne Schleifen verwendet, aber ohne Schleifen ist dies nicht möglich.

Ján Яabčan
quelle
2

Sie können die Apache Commons-Collections-API verwenden.

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;
        }
    }

Verwenden Sie dann diesen Verschluss wie unten gezeigt:

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

Wenn Sie die Kartenfunktion kennen, wissen Sie, dass eine Karte auch eine rekursive Schleife oder eine rekursive Schleife sein kann. Aber dafür muss man natürlich jedes Element erreichen. Daher konnte ich Java 8 nicht ausarbeiten, da die Syntax nicht übereinstimmte, aber ich wollte eine sehr kurze Version, also habe ich diese bekommen.

int sum = 0
for (Integer e : myList) sum += e;
sivi
quelle
Du hast recht. Ich sagte, es ist eine minimale Schleife anstelle einer Karte, die rekursiv sein kann.
Sivi
"Gibt es die Möglichkeit der Summe von ArrayList ohne Schleife"
Alexander
0

Da eine Liste jeden Objekttyp enthalten kann, gibt es keine integrierte Methode, mit der Sie alle Elemente summieren können. Sie könnten so etwas tun:

int sum = 0;

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

Alternativ können Sie einen eigenen Containertyp erstellen, der von ArrayList erbt, aber auch eine Methode namens sum () implementiert, die den obigen Code implementiert.

Mike Kwan
quelle
0

ArrayList ist eine Sammlung von Elementen (in Form einer Liste), Grundelemente werden als Wrapper-Klassenobjekt gespeichert, aber gleichzeitig kann ich auch Objekte der String-Klasse speichern. SUM wird darin keinen Sinn ergeben. Übrigens, warum haben Sie sowieso solche Angst, eine Schleife (erweitert oder durch Iterator) zu verwenden?

GauravJ
quelle
0

Oder wechseln Sie zu Groovy, es hat eine sum () - Funktion für eine Sammlung. [1,2,3,4,5,6] .sum ()

http://groovy.codehaus.org/JN1015-Collections

Läuft auf derselben JVM wie Ihre Java-Klassen.

dbrin
quelle
8
Ja. Die Summenfunktion ist definitiv ein Grund, in eine andere Sprache zu wechseln. : D
ruX
1
Die Frage ist mit einem Tag versehen Java, daher ist dies technisch keine gültige Antwort.
Bengt
0

Dieser Link zeigt drei verschiedene Möglichkeiten, wie man in Java summiert. Es gibt eine Option, die in früheren Antworten mit Apache Commons Math nicht enthalten ist.

Beispiel:

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));

}

Siehe StatUtils api

Nachokk
quelle
0

Sie können die GNU Trove- Bibliothek verwenden:

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

Dies kann durch Reduzieren mithilfe von Methodenreferenzen erfolgen reduce(Integer::sum):

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

Oder ohne Optional:

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