반복하지 않고 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와 배열이 반드시 같은 것은 아닙니다. 배열의 숫자를 합산하는 것은 요소에 대한 매우 간단한 for 루프이고 누적 합계를 계산하는 것입니다.
posdef

PHP 함수 array_sum는 내부적으로 루프를 수행하며 사용자에게 숨 깁니다.
Paŭlo Ebermann

1
합리적인 질문입니다. 결국, 목록에서 가장 큰 요소를 찾기 위해 루프를 작성하는 것은 거의 간단하지만 java.util.Collections는 max () 메소드를 제공합니다.
John Velonis 2014 년

1
결국 매우 합리적인 질문은 방법의 요점입니다. 재사용 :
벤 Taliadoros

루프는 아름답습니다.
Alex78191

답변:



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
실제 덧셈을 할 때 간단한 int. 여기서 Integer자바의 자동 복싱 기능 을 사용 하는 것은 가치가 거의 없습니다 . 또한 유형 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

1
@Teudimundo True, 그것을 막지는 않지만 List의 최대 크기는 Integer.MAX_VALUE이고 log2는 최대 깊이 인 31입니다. 대부분의 시스템은 제한으로 수천 개의 호출을 가지고 있지만 이것에 매우 가까워지면 여전히 끊길 수 있습니다.
Peter Lawrey 2015

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에서 긴 값으로 어떻게 할 수 있습니까?
Ravi Parmar 2011-08-23

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 함수에 대해 알고 있다면 맵이 재귀 루프 또는 재귀 루프 일 수도 있음을 알고 있습니다. 그러나 분명히 당신은 그것을 위해 각 요소에 도달해야합니다. 그래서 일부 구문이 일치하지 않지만 매우 짧은 것을 원했기 때문에 Java 8을 해결할 수 없었습니다.

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

당신이 옳습니다. 나는 그것이 꼬리 재귀적일 수있는 맵 대신에 최소한의 루프라고 말했다.
sivi

"ArrayList에의 합이 가능성은 반복없이"
알렉산더

0

목록이 모든 유형의 객체를 보유 할 수 있다는 점을 감안할 때 모든 요소를 ​​합산 할 수있는 내장 메서드가 없습니다. 다음과 같이 할 수 있습니다.

int sum = 0;

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

또는 ArrayList에서 상속하지만 위의 코드를 구현하는 sum ()이라는 메서드를 구현하는 자체 컨테이너 유형을 만들 수 있습니다.


0

ArrayList는 요소 의 컬렉션 (목록 형태)이며, 기본 요소는 래퍼 클래스 개체로 저장되지만 동시에 String 클래스의 개체도 저장할 수 있습니다. SUM은 그 점에서 의미가 없습니다. BTW 왜 어쨌든 for 루프 (향상된 또는 반복기를 통해)를 사용하는 것을 두려워합니까?


0

또는 Groovy로 전환하면 컬렉션에 sum () 함수가 있습니다. [1,2,3,4,5,6] .sum ()

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

Java 클래스와 동일한 JVM에서 실행됩니다.


8
네. Sum 함수는 확실히 다른 언어로 전환하는 이유입니다. : D
ruX 2014 년

1
질문에 태그가 지정 Java되어 있으므로 기술적으로 유효한 답변이 아닙니다.
Bengt

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);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.