从文件读取数据并将其存储的最佳方法

时间:2020-02-12 12:52:29

标签: java arrays arraylist

我从每行都是学生的学生文件中读取数据,然后将这些数据转换为学生对象,并且我想返回一个学生对象数组。我目前正在通过将每个学生对象存储在数组列表中,然后将其作为标准Student []返回的方式来执行此操作。使用arraylist拥有一个动态大小的数组,然后将其转换为返回的标准数组更好吗?还是我应该首先计算文件中的行数,使该大小的Student []然后只是填充该数组?还是有一种更好的方法可以完全做到这一点。

如果有帮助,请参见以下代码:

public Student[] readStudents() {
        String[] lineData;
        ArrayList<Student> students = new ArrayList<>();
        while (scanner.hasNextLine()) {
            lineData = scanner.nextLine().split(" ");
            students.add(new Student(lineData));
        }
        return students.toArray(new Student[students.size()]);
    }

2 个答案:

答案 0 :(得分:2)

哪个更好取决于您需要什么和您的数据集大小。需求可能是-最简单的代码,最快的加载,最少的内存使用,对resultind数据集的快速迭代...选项可能是

  1. 对于一次性脚本或小型数据集(成千上万个元素),可能会做任何事情。
  2. 也许根本不存储元素,而是在阅读它们时对其进行处理? -使用最少的内存,适合非常大的数据集。
  3. 使用预分配的数组-如果您事先知道数据集的大小-确保最少的内存分配-但是对元素本身进行计数可能会很昂贵。
  4. 如果不确定-使用ArrayList收集元素。如果您可以预先估计数据集大小的上限,那将是最有效的,例如,您知道通常不超过5000个元素。在这种情况下,创建具有5000个元素的ArrayList。如果后备阵列已满,它将自动调整大小。
  5. LinkedList(可能是最保守的),它随您分配空间,但是每个元素所需的内存比数组或ArrayLists大,并且迭代速度慢。
  6. 您自己的数据结构已针对您的需求进行了优化。通常,这样做是不值得的,因此仅当您已经知道要解决的问题时才使用此选项。

关于ArrayList的注意事项:它开始于预先分配一个带有一组插槽的数组,这些插槽随后被填充而无需重新分配内存。只要后备阵列已满,就会分配一个新的更大的后备阵列,并将所有元素移入其中。默认情况下,新数组的大小是前一个数组的两倍-通常这不是问题,但是如果新数组不能获得足够的连续内存块,则可能导致内存不足。

答案 1 :(得分:1)

将数组用于固定大小的数组。对于学生而言并非如此,因此如您在阅读中所见,ArrayList更适合。从ArrayList到数组的转换是多余的。

然后,使用最通用的类​​型,在这里List界面。这样的实现ArrayListLinkedList是一个技术实现问题。您稍后可能会使用其他运行时行为来更改其他实现。

但是您的代码可以处理各种List,这确实是一个强大的概括。

此处包含一些实现的有用接口的不完整列表

  • 列表-ArrayList(快速,很少的内存开销),LinkedList
  • Set-HashSet(快速),TreeSet(是SortedSet)
  • 地图-HashMap(快速),TreeMap(是SortedMap),LinkedHashMap(插入顺序)

所以:

public List<Student> readStudents() {
    List<Student> students = new ArrayList<>();
    while (scanner.hasNextLine()) {
        String[] lineData = scanner.nextLine().split(" ");
        students.add(new Student(lineData));
    }
    return students;
}

在代码审查中,人们将对构造函数Student(String[] lineData)进行评论,这可能会导致将来的数据更改。