我试图优化我的代码;它读取特定文件夹中的文件并在Windows中显示它们,然后进一步使用它们。一切都按预期工作,但当文件夹中有很多文件(如100+)时,加载内容真的很滞后。
有人可以给我建议如何优化这个功能吗?
private void ReloadScanFiles() {
if (gsfCurRow != null) {
ArrayList<FileInfo> newTreeFileInfoList = new ArrayList<FileInfo>();
ArrayList<FileInfo> addTreeFileInfoList = new ArrayList<FileInfo>();
ArrayList<String> delTreeFileNameList = new ArrayList<String>();
File folder = new File(gsfCurRow.DOC_SOURCE_PATH);
FileFilter fileFilter = new FileFilter() {
public boolean accept(File file) {
return !file.isDirectory() && !file.isHidden();
}
};
/*
FilenameFilter fileFilter = new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".pdf") ||
name.toLowerCase().endsWith(".jpeg") ||
name.toLowerCase().endsWith(".jpg") ||
name.toLowerCase().endsWith(".tiff") ||
name.toLowerCase().endsWith(".txt");
}
};
*/
File[] listOfFiles = folder.listFiles(fileFilter);
for (int i = 0; i < listOfFiles.length; i++){
FileInfo fileInfo = new FileInfo();
fileInfo.Name = listOfFiles[i].getName();
//fileInfo.Length = (long) listOfFiles[i].length();
fileInfo.LastModified = (long) listOfFiles[i].lastModified(); //Long.parseLong("473", 10);
newTreeFileInfoList.add(fileInfo);
}
//add new items
for (FileInfo fileInfo: newTreeFileInfoList){
boolean existsItem = false;
if (actTreeFileInfoList != null){
for (FileInfo fileInfo1: actTreeFileInfoList){
if (fileInfo.Name.equals(fileInfo1.Name)) {
existsItem = true;
break;
}
}
}
if (!existsItem) {
addTreeFileInfoList.add(fileInfo);
}
}
//delete non existing items
if (actTreeFileInfoList != null){
for (FileInfo fileInfo: actTreeFileInfoList){
boolean existsItem = false;
for (FileInfo fileInfo1: newTreeFileInfoList){
if (fileInfo.Name.equals(fileInfo1.Name)) {
existsItem = true;
break;
}
}
if (!existsItem) {
delTreeFileNameList.add(fileInfo.Name);
}
}
}
actTreeFileInfoList = newTreeFileInfoList;
//add items to tree
for (FileInfo fileInfo: addTreeFileInfoList){
TreeItem item = new TreeItem(tv, SWT.NONE);
//item.setText(new String[] {fileInfo.Name, Long.toString(fileInfo.Length), df.format(fileInfo.LastModified)});
item.setText(new String[] {fileInfo.Name, null, df.format(fileInfo.LastModified)});
fileCount ++;
}
//delete item from tree
//update locked by
TreeItem [] items = tv.getItems();
for (TreeItem item: items){
//delete
if (delTreeFileNameList.contains(item.getText())) {
if (item.getChecked()) {
checkedFileCount --;
}
fileCount --;
item.dispose();
}
//update
if (!item.isDisposed()){
Integer lock_idusr = null;
try {
lock_idusr = db.FileLockedBy(gsfCurRow.DOC_SOURCE_ID, item.getText());
} catch (SQLException e) {
e.printStackTrace();
}
if ((lock_idusr != null) && (!lock_idusr.equals(idusr))){
try {
item.setText(3, db.GetOpid(lock_idusr));
} catch (SQLException e) {
e.printStackTrace();
}
Color color = new Color(display,180, 0, 0);
item.setForeground(color);
item.setChecked(false);
}
else{
item.setText(3, "");
Color color = new Color(display,0, 0, 0);
item.setForeground(color);
}
}
}
BtnDocAssignEnabled();
GenerateTreeStatusText();
}
}
答案 0 :(得分:2)
您所做的最明显的错误是:
for (FileInfo fileInfo: newTreeFileInfoList){
boolean existsItem = false;
if (actTreeFileInfoList != null){
for (FileInfo fileInfo1: actTreeFileInfoList){
if (fileInfo.Name.equals(fileInfo1.Name)) {
existsItem = true;
break;
}
}
}
if (!existsItem) {
addTreeFileInfoList.add(fileInfo);
}
}
对于每个新元素,您遍历整个旧条目列表以检查它是否已经在列表中。有了100个新文件,这将导致5050次迭代。您可以考虑使用带有文件名的Map作为键而不是ArrayList。您的支票将如下所示:
for (FileInfo fileInfo: newTreeFileInfoList){
if (!actTreeFileInfoMap.containsKey(fileInfo.Name)) {
actTreeFileInfoMap.put(fileInfo.Name, fileInfo);
}
}
如果Map中的实际fileinfo不重要,您可以跳过整个检查并将新的fileInfo放入Map中。这将导致用新添加的一个替换之前添加的一个。