百万对象内存指定字段排序
package com;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
class Person implements Comparable<Person> {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = Objects.requireNonNull(name, "Name cannot be null");
if (age < 0) throw new IllegalArgumentException("Age cannot be negative");
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public int compareTo(Person other) {
Objects.requireNonNull(other, "Cannot compare with null");
return Integer.compare(this.age, other.age);
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}
public class BigDataSortExample {
public static void main(String[] args) {
// 模拟大数据量(假设100万条数据)
Person[] people = new Person[1_000_000];
try {
for (int i = 0; i < people.length; i++) {
people[i] = new Person("Name" + i, (int) (Math.random() * 100));
}
} catch (IllegalArgumentException | NullPointerException e) {
System.err.println("Error creating Person: " + e.getMessage());
return;
}
// 1. 并行数组排序(按年龄)
long startTime = System.nanoTime();
Arrays.parallelSort(people); // 使用parallelSort
long endTime = System.nanoTime();
System.out.println("ParallelSort by age took: " + (endTime - startTime) / 1_000_000 + " ms");
// 2. Stream API并行排序(按名字)
startTime = System.nanoTime();
List<Person> sortedByName = Arrays.stream(people)
.parallel()
.sorted(Comparator.comparing(Person::getName))
.collect(Collectors.toList());
endTime = System.nanoTime();
System.out.println("Parallel Stream sort by name took: " + (endTime - startTime) / 1_000_000 + " ms");
// 输出前5条验证结果
System.out.println("First 5 by age: " + Arrays.stream(people).limit(5).collect(Collectors.toList()));
System.out.println("First 5 by name: " + sortedByName.subList(0, 5));
}
}
大数据量优化建议
分块处理:
将数据分块加载到内存,使用BufferedReader或数据库分页查询。
对每块排序后归并。
数据库优化:
若数据来自数据库,使用索引和ORDER BY将排序卸载到数据库。
示例SQL:
SELECT name, age FROM people ORDER BY age LIMIT 1000000;
分布式处理:
对于亿级数据,使用Spark或Hadoop进行分布式排序。
缓存排序结果:
使用Redis或Memcached缓存频繁查询的排序结果,减少重复计算。
注意事项
内存管理:大数据量需监控JVM堆内存,调整-Xmx参数。
测试性能:在生产环境中测试parallelSort和Stream的实际性能,选择最优方案。
异常处理:确保捕获并处理所有可能的异常(如OutOfMemoryError)。