有没有循环的ArrayList之和的可能性


87

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,2011年

PHP函数array_sum还在内部执行一个循环,它只是向用户隐藏了它。
2011年

1
这是一个合理的问题。毕竟,编写循环以查找列表中最大的元素几乎是微不足道的,但是java.util.Collections提供了max()方法。
John Velonis 2014年

1
毕竟,很合理的问题就是方法的重点,对吗?重用:)
Ben Taliadoros 2014年

循环很漂亮。
Alex78191

Answers:


154

一旦 完了(2014年3月),您将可以使用流

如果你有一个 List<Integer>

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

如果是 int[]

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

5
map隐式使用循环
Nikos M.

6
您可以使用递归不使用循环。:D(不要这样做)
卡莱布·芬顿

23

然后自己写:

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

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

     return sum;
}

1
或者使用sum方法扩展ArrayList,以便将其内置到自己的ArrayList中。
Bueller

3
在进行实际加法时,最好使用simple int。在这里使用IntegerJava的自动装箱功能几乎没有价值。另外,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()的调用。第二个递归定义并不能防止堆栈溢出的发生,而是降低了发生的可能性。
Teudimundo 2015年

1
@Teudimundo是的,虽然不能阻止,但List的最大大小为Integer.MAX_VALUE,log2为31,这是最大深度。大多数系统都有成千上万的通话限制,但是如果您非常接近此限制,它仍然可能会失败。
彼得·劳里

9

写一个像

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中获取长值呢?
拉维·帕尔玛

5

对我来说,最清晰的方法是:

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

要么

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

它还使用内部循环,但是没有循环是不可能的。


2

您可以使用apache commons-collections API。

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函数,那么您知道map也可以是递归循环或递归循环。但是显然,您必须做到这一点。因此,我无法解决Java 8的问题,因为某些语法不匹配,但希望很短,所以这就是我得到的。

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

你是对的。我说这是一个最小循环,而不是map,它可以是尾递归的。
sivi 2015年

“有没有循环的ArrayList之和的可能性”
亚历山大

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

1
该问题被标记为Java,因此从技术上讲这不是有效的答案。
Bengt 2014年

0

链接显示了使用Java求和的三种不同方式,在使用Apache Commons Math的以前的答案中没有一个选项。

例:

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

您可以使用GNU Trove库:

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);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.