Apakah ada kemungkinan jumlah ArrayList tanpa perulangan

88

Apakah ada kemungkinan jumlah ArrayList tanpa perulangan?

PHP menyediakan sum(array) yang akan memberikan jumlah array.

Seperti kode PHP

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

Saya ingin melakukan hal yang sama di Java:

List tt = new ArrayList();
tt.add(1);
tt.add(2);
tt.add(3);
Tapsi
sumber
2
Bagaimana jika ArrayListtidak berisi sesuatu yang "dapat diringkas"? ArrayList dan array belum tentu sama. Adapun menjumlahkan angka dalam larik, itu adalah perulangan for yang sangat sederhana atas elemen dan menghitung jumlah kumulatif.
posdef
Fungsi PHP array_sumjuga melakukan loop secara internal, itu hanya menyembunyikannya dari pengguna.
Paŭlo Ebermann
1
Itu pertanyaan yang masuk akal. Lagipula, menulis loop untuk menemukan elemen terbesar dalam daftar hampir sama mudahnya, namun java.util.Collections menyediakan metode max ().
John Velonis
1
Pertanyaan yang sangat masuk akal, bagaimanapun, itulah intinya dari metode, bukan?
Gunakan
Lingkaran itu indah.
Alex78191

Jawaban:

156

Sekali sudah keluar (Maret 2014), Anda akan dapat menggunakan streaming :

Jika Anda memiliki file List<Integer>

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

Jika itu int[]

int sum = IntStream.of(a).sum();
msayag.dll
sumber
5
mapmenggunakan loop secara implisit
Nikos M.
8
Anda bisa menggunakan rekursi untuk tidak menggunakan loop. : D (jangan lakukan ini)
Caleb Fenton
23

Kemudian tulis sendiri:

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

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

     return sum;
}
Erhan Bagdemir
sumber
1
Atau memperluas ArrayList dengan metode penjumlahan sehingga Anda memilikinya di ArrayList Anda sendiri.
Bueller
3
Saat melakukan penambahan sebenarnya, lebih baik menggunakan yang sederhana int. Ada sedikit manfaat dalam menggunakan fitur Integerjava-boxing otomatis di sini. Selain itu, Anda membuat dan membuat ulang banyak Integerobjek baru yang berpotensi setiap kali, karena ini adalah Immutabletipe.
Java Drinker
10

Satu-satunya alternatif untuk menggunakan loop adalah dengan menggunakan rekursi.

Anda dapat menentukan metode seperti

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

Ini sangat tidak efisien dibandingkan dengan menggunakan loop biasa dan dapat meledak jika Anda memiliki banyak elemen dalam daftar.

Alternatif yang menghindari tumpukan overflow adalah dengan menggunakan.

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

Ini sama tidak efisiennya, tetapi akan menghindari tumpukan melimpah.


Cara terpendek untuk menulis hal yang sama adalah

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

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

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

cetakan

sum(a) = 20
Peter Lawrey
sumber
Dalam kode, Anda melewatkan panggilan ke sum () dalam definisi rekursif pertama. Definisi rekursif kedua tidak mencegah terjadinya luapan tumpukan, ini membuatnya lebih kecil kemungkinannya.
Teudimundo
1
@Teudimundo Benar, Meskipun tidak mencegahnya, ukuran maksimum Daftar adalah Integer.MAX_VALUE dan log2 adalah 31 yang merupakan kedalaman maksimum. Sebagian besar sistem memiliki ribuan panggilan sebagai batas tetapi jika Anda sangat dekat dengan ini, panggilan masih bisa meledak.
Peter Lawrey
9

Tulis fungsi util seperti

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

Kemudian gunakan seperti

int sum = ListUtil.sum(yourArrayList)
Nishant
sumber
tetapi bagaimana saya bisa melakukannya untuk nilai panjang dalam daftar larik?
Ravi Parmar
5

bagi saya cara paling jelas adalah ini:

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

atau

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

Ini juga menggunakan loop internal, tetapi tidak mungkin tanpa loop.

Ján Яabčan
sumber
2

Anda dapat menggunakan API apache commons-collections.

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

Kemudian gunakan penutupan ini seperti yang ditunjukkan di bawah ini:

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

Jika Anda mengetahui tentang fungsi peta, maka Anda tahu bahwa peta juga dapat berupa loop rekursif atau loop rekursif. Tapi jelas Anda harus mencapai setiap elemen untuk itu. jadi, saya tidak bisa mengerjakan Java 8, karena beberapa sintaks tidak cocok tetapi ingin sangat singkat jadi inilah yang saya dapatkan.

int sum = 0
for (Integer e : myList) sum += e;
sivi
sumber
Kamu benar. Saya mengatakan ini adalah loop minimal, bukan peta yang bisa menjadi rekursif ekor.
sivi
"Apakah ada kemungkinan jumlah ArrayList tanpa perulangan"
alexander
0

Mengingat bahwa daftar dapat menampung semua jenis objek, tidak ada metode bawaan yang memungkinkan Anda menjumlahkan semua elemen. Anda bisa melakukan sesuatu seperti ini:

int sum = 0;

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

Alternatifnya, Anda bisa membuat jenis penampung Anda sendiri yang mewarisi dari ArrayList tetapi juga mengimplementasikan metode yang disebut sum () yang mengimplementasikan kode di atas.

Mike Kwan
sumber
0

ArrayList adalah Kumpulan elemen (dalam bentuk list), primitif disimpan sebagai objek kelas pembungkus tetapi pada saat yang sama saya dapat menyimpan objek kelas String juga. SUM tidak masuk akal dalam hal itu. BTW mengapa begitu takut menggunakan for loop (ditingkatkan atau melalui iterator) lagian?

GauravJ
sumber
0

Atau beralih ke Groovy, ini memiliki fungsi sum () pada koleksi. [1,2,3,4,5,6] .sum ()

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

Berjalan di JVM yang sama dengan kelas java Anda.

dbrin
sumber
8
Ya. Fungsi penjumlahan jelas merupakan alasan untuk beralih ke bahasa lain. : D
ruX
1
Pertanyaannya diberi tag Java, jadi ini secara teknis bukan jawaban yang valid.
Bengt
0

Tautan ini menunjukkan tiga cara berbeda bagaimana menjumlahkan di java, ada satu opsi yang tidak ada di jawaban sebelumnya menggunakan Apache Commons Math ..

Contoh:

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

}

Lihat api StatUtils

nachokk
sumber
0

Anda dapat menggunakan perpustakaan Trove GNU :

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

Ini dapat dilakukan dengan mengurangi menggunakan referensi metode reduce(Integer::sum):

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

Atau tanpa Optional:

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