首页 > 解决方案 > 在可观察列表 (JavaFX 8) 内的大量文件(对象)上更快地迭代

问题描述

我有一个包含所有图像文件名的 excel 文件。这些图像的路径存储在一个Observable Collectionvia<File>类中,该类来自包含所有图像的文件夹。我的目标是通过图像文件集合池匹配这些文件名来创建这些文件名的超链接。

我想问一下如何才能更快地遍历大量文件类以便轻松获取它们的路径。

例如:

Excel 中的图像名称:

ABC_0001

集合中的完整路径必须是:

C:\Users\admin\Desktop\Images\ABC_0001.jpg

为了获得它们的完整路径,我通过 Stream 执行迭代。

我的程序:

  1. 使用 Apache POI 提取数据。
  2. 通过将每个数据转换为其基本文件名与提取的数据来流式传输图像集合。
  3. 获取结果并将完整路径存储在对象上 getAbsolutePath()

代码:

//storage during iteration
ObservableList<DetailedData> dataCollection = FXCollections.observableArrayList()

//Image collection containing over 13k Images listed via commons-io
ObservableList<File> IMAGE_COLLECTION =  FXCollections.observableArrayList(FileUtils.listFiles(browsedFOLDER, new String[]{"JPG", "JPEG", "TIF", "TIFF", "jpg", "jpeg", "tif", "tiff"}, true));

//Sheet data
Sheet sheet1 = wb.getsheetAt(0);

 for (Row row: sheet1)
 {
    DetailedData data = new DetailedData();

    //extracted data from excel
    String FILENAME = row.getCell(0,Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();

    //to be filled up based on stream result.
    String IMAGE_SOURCE = null;

    //stream code with the help of commons-io
    File IMAGE = IMAGE_COLLECTION.stream().filter(e -> FilenameUtils.getBaseName(e.getName()).toLowerCase().equals(FILENAME.toLowerCase())).findFirst().orElse(null);

    if (IMAGE != null)
      IMAGE_SOURCE = IMAGE.getAbsolutePath();


    data.setFileName(FILENAME);
    data.setFullPath(IMAGE_SOURCE);
    dataCollection.add(data);

   }

结果:

Excel rows = 9,400
Image Files = 13,000

Iteration Time = 120,000ms

结果应该看起来正常还是可以变得更快?

我尝试使用parallelStream(),结果更快,但它消耗更高的 CPU 使用率。

标签: javafxlambdacollectionsstreamfilepath

解决方案


如果你真的想加快搜索速度,你应该尽量不要重复做那些只能做一次的事情。例如,您可以使用两个循环。第一个准备搜索,第二个实际进行搜索。在您的过滤器中,您调用 FilenameUtils.getBaseName 并两次转换为小写。最好在第一个循环中只做一次这些事情并将结果字符串存储在一个列表中。在第二个循环中,您然后在此列表上进行搜索。

我也想知道你为什么在这里使用 ObservableLists。一个简单的列表也可以。


推荐阅读