在我的Java应用程序中,我有一个扩展ArrayList并实现TableModel的类MyFileList
。MyFile
类
当我单击在gui中对列进行排序时,我会收到一个异常,并且列表只剩下一半排序。
Exception in thread "AWT-EventQueue-2" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.ArrayList.elementData(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at com.example.smdb.MyFileList.getValueAt(MyFileList.java:321)
at com.example.util.MyObjectListComparator.compare(MyObjectListComparator.java:97)
at java.util.TimSort.mergeHi(Unknown Source)
at java.util.TimSort.mergeAt(Unknown Source)
at java.util.TimSort.mergeForceCollapse(Unknown Source)
at java.util.TimSort.sort(Unknown Source)
at java.util.Arrays.sort(Unknown Source)
at java.util.ArrayList.sort(Unknown Source)
at java.util.Collections.sort(Unknown Source)
at com.example.gui.MyTableSorter.sort(MyTableSorter.java:73)
at com.example.gui.MyTableSorter.sortByColumn(MyTableSorter.java:93)
at com.example.gui.PreservableColSizeJTable$PersistentJTableHeader.mouseClicked(PreservableColSizeJTable.java:935)
MyTableSorter
排序方法:
public void sort(int column) {
if(model instanceof List){
Collections.sort ((List)model, new MyObjectListComparator((List)model, column, ascending));
}
}
MyObjectListComparator
比较方法:
public int compare(Object obj, Object obj1) {
int result = 0;
int row = this.filelist.indexOf(obj);
int row1 = this.filelist.indexOf(obj1);
Object value = ((MyFileList) this.filelist).getValueAt(row, column);
value = ((MyFile.FileAttr) value).getAttrValue();
Object value1 = ((MyFileList) this.filelist).getValueAt(row1, column);
value1 = ((MyFile.FileAttr) value1).getAttrValue();
result = compareAttr(value, value1);
return result;
}
MyFile
等于方法:
public boolean equals(Object obj) {
if (obj instanceof MyFile) {
if (this.getAttribute(FILE_ID) != null) {
return this.getAttribute(FILE_ID).equals(((MyFile) obj).getAttribute(FILE_ID));
}
}
return false;
}
调试后,我看到compare
方法中的this.filelist.indexOf(obj)
正在返回-1
。如果我发现这个异常并让它继续排序,那么我的列表中会出现一些重复的项目和一些丢失的项目。
我在TimSort
中发现了一些听起来非常相似的bug引用,所以我尝试了useLegacySortMerge
选项。这给了我相同的行为,但堆栈跟踪略有不同,所以不幸的是,这看起来并不是问题所在。
Exception in thread "AWT-EventQueue-2" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.ArrayList.elementData(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at com.example.smdb.MyFileList.getValueAt(MyFileList.java:321)
at com.example.util.MyObjectListComparator.compare(MyObjectListComparator.java:97)
at java.util.Arrays.mergeSort(Unknown Source)
at java.util.Arrays.mergeSort(Unknown Source)
at java.util.Arrays.mergeSort(Unknown Source)
at java.util.Arrays.legacyMergeSort(Unknown Source)
at java.util.Arrays.sort(Unknown Source)
at java.util.ArrayList.sort(Unknown Source)
at java.util.Collections.sort(Unknown Source)
at com.example.gui.MyTableSorter.sort(MyTableSorter.java:73)
at com.example.gui.MyTableSorter.sortByColumn(MyTableSorter.java:93)
at com.example.gui.PreservableColSizeJTable$PersistentJTableHeader.mouseClicked(PreservableColSizeJTable.java:935)
这几天来一直让我抓狂。有什么见解吗?
只是一个想法:您可以处理在文件列表中找不到row和row1的情况,假设两者的缺席是等效的,并且缺席比任何存在都"少"。如果不起作用,则反转1和-1。
public int compare(Object obj, Object obj1) {
int result = 0;
int row = this.filelist.indexOf(obj);
int row1 = this.filelist.indexOf(obj1);
if(row == -1){
if(row1 == -1){
return 0;
}
return -1;
}else if(row1 == -1){
return 1;
}
Object value = ((MyFileList) this.filelist).getValueAt(row, column);
value = ((MyFile.FileAttr) value).getAttrValue();
Object value1 = ((MyFileList) this.filelist).getValueAt(row1, column);
value1 = ((MyFile.FileAttr) value1).getAttrValue();
result = compareAttr(value, value1);
return result;
}