Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

Java: หาค่าเฉลี่ย (Average) ของ List

วิธีการคำนวณค่าเฉลี่ยของ List ใน Java มีหลายวิธี ตั้งแต่ Stream API (Modern) ไปจนถึง Loop แบบเดิม

วิธีที่ 1: ใช้ Stream API + IntSummaryStatistics (Java 8+) - แนะนำ

import java.util.Arrays;
import java.util.IntSummaryStatistics;
import java.util.List;

public class Demo {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(10, 20, 50, 100, 130, 150, 200, 250, 500);

        IntSummaryStatistics stats = list.stream()
            .mapToInt(Integer::intValue) // หรือ .mapToInt(a -> a)
            .summaryStatistics();

        System.out.println("Average = " + stats.getAverage());
        System.out.println("Count = " + stats.getCount());
        System.out.println("Sum = " + stats.getSum());
        System.out.println("Min = " + stats.getMin());
        System.out.println("Max = " + stats.getMax());
    }
}

Output

Average = 156.66666666666666
Count = 9
Sum = 1410
Min = 10
Max = 500

วิธีที่ 2: ใช้ Stream.reduce() หรือ Collectors.averagingInt()

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StreamAverage {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(10, 20, 50, 100, 130, 150, 200, 250, 500);

        // reduce
        double avg1 = list.stream()
            .mapToInt(Integer::intValue)
            .average()
            .orElse(0.0);
        System.out.println("Average (reduce): " + avg1);

        // Collectors.averagingInt
        double avg2 = list.stream()
            .collect(Collectors.averagingInt(Integer::intValue));
        System.out.println("Average (collector): " + avg2);
    }
}

วิธีที่ 3: ใช้ For Loop แบบเดิม (Compatible ทุก Version)

import java.util.Arrays;
import java.util.List;

public class LoopDemo {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(10, 20, 50, 100, 130, 150, 200, 250, 500);

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

        if (list.isEmpty()) {
            System.out.println("Empty list!");
        } else {
            double average = (double) sum / list.size();
            System.out.println("Average = " + average);
        }
    }
}

Output

Average = 156.66667

วิธีที่ 4: ใช้ DoubleStream สำหรับ List<Double>

import java.util.Arrays;
import java.util.List;

public class DoubleListDemo {
    public static void main(String[] args) {
        List<Double> list = Arrays.asList(1.5, 2.5, 3.0, 4.5, 5.0);

        double avg = list.stream()
            .mapToDouble(Double::doubleValue)
            .average()
            .orElse(0.0);

        System.out.println("Average = " + avg); // 3.3
    }
}

วิธีที่ 5: ใช้ Apache Commons Math (Library ภายนอก)

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-math3</artifactId>
    <version>3.6.1</version>
</dependency>

import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
import java.util.Arrays;
import java.util.List;

public class CommonsMathDemo {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(10, 20, 50, 100, 130, 150, 200, 250, 500);
        
        DescriptiveStatistics stats = new DescriptiveStatistics();
        for (int v : list) stats.addValue(v);
        
        System.out.println("Mean: " + stats.getMean());
        System.out.println("Std Dev: " + stats.getStandardDeviation());
        System.out.println("Variance: " + stats.getVariance());
    }
}

สำหรับ Primitive Arrays

import java.util.Arrays;

public class PrimitiveArrayDemo {
    public static void main(String[] args) {
        int[] arr = {10, 20, 50, 100, 130, 150, 200, 250, 500};
        
        // Java 8+
        double avg = Arrays.stream(arr).average().orElse(0.0);
        System.out.println("Average: " + avg);

        // Manual
        long sum = 0;
        for (int v : arr) sum += v;
        System.out.println("Average: " + ((double) sum / arr.length));
    }
}

BigDecimal สำหรับ Precision สูง (Financial)

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.List;

public class BigDecimalAverage {
    public static void main(String[] args) {
        List<BigDecimal> list = Arrays.asList(
            new BigDecimal("10.123"),
            new BigDecimal("20.456"),
            new BigDecimal("30.789")
        );

        BigDecimal sum = BigDecimal.ZERO;
        for (BigDecimal bd : list) {
            sum = sum.add(bd);
        }

        BigDecimal avg = sum.divide(
            BigDecimal.valueOf(list.size()), 
            10, // scale
            RoundingMode.HALF_UP
        );

        System.out.println("Average: " + avg); // 20.456
    }
}

ตารางเปรียบเทียบ

วิธี Java Version Null/Empty Safe Return Type เพิ่มเติม
IntSummaryStatistics 8+ ✅ (orElse) double ได้ min/max/sum/count ฟรี
Stream.average() 8+ ✅ (orElse) OptionalDouble Clean, functional
Collectors.averagingInt 8+ ✅ (คืน 0.0 ถ้า empty) double ใช้กับ Collector pipeline
For Loop 1.0+ Manual check double Compatible, no overhead
BigDecimal 1.0+ Manual BigDecimal Financial precision

Best Practices

  • ใช้ IntSummaryStatistics หากต้องการ stats อื่นๆ ด้วย (min, max, count, sum)
  • ใช้ .average().orElse(0.0) สำหรับ simple case
  • ระวัง Integer Overflow ในการ sum - ใช้ long หรือ BigDecimal
  • Empty list: ตัดสินใจว่าจะ return 0, throw exception, หรือ Optional
  • Parallel stream: list.parallelStream().mapToInt(...).average() สำหรับ list ใหญ่มาก