在 Java 中對包含 Date 對象的 ArrayList 進行降序排序,並顯示在 ListView 中,核心是使用 Collections.sort() 配合自定義 Comparator。
// 原代碼嘗試在獲取數據時排序,邏輯混亂
Map dateMap = new TreeMap<>(new Comparator() {
public int compare(Date d1, Date d2) {
return d1.compareTo(d2); // 升序
}
});
// 且未實際用於排序列表數據
public class DataItem {
public Date submitDate; // 或 lastModifiedDate
public String title;
// 其他字段...
}
List list = DBAdapter.requestUserData(token);
// 方式一:Java 8+ Lambda (推薦)
list.sort((item1, item2) -> item2.submitDate.compareTo(item1.submitDate));
// 或
Collections.sort(list, (item1, item2) -> item2.submitDate.compareTo(item1.submitDate));
// 方式二:傳統 Comparator (Java 7 兼容)
Collections.sort(list, new Comparator() {
@Override
public int compare(DataItem o1, DataItem o2) {
// 降序:o2 在前
if (o1.submitDate == null && o2.submitDate == null) return 0;
if (o1.submitDate == null) return 1; // null 排最後
if (o2.submitDate == null) return -1;
return o2.submitDate.compareTo(o1.submitDate);
}
});
// 排序後直接設置適配器
lv.setAdapter(new MyListAdapter(getApplicationContext(), list));
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView> parent, View view, int position, long id) {
List list = DBAdapter.requestUserData(token);
switch (position) {
case 0: // 默認排序 (或按 ID)
// 不排序或按 ID 排序
break;
case 1: // 按提交時間降序 (最新優先)
list.sort((a, b) -> {
if (a.submitDate == null && b.submitDate == null) return 0;
if (a.submitDate == null) return 1;
if (b.submitDate == null) return -1;
return b.submitDate.compareTo(a.submitDate);
});
break;
case 2: // 按修改時間降序
list.sort((a, b) -> {
if (a.lastModifiedDate == null && b.lastModifiedDate == null) return 0;
if (a.lastModifiedDate == null) return 1;
if (b.lastModifiedDate == null) return -1;
return b.lastModifiedDate.compareTo(a.lastModifiedDate);
});
break;
}
// 關鍵:排序後刷新適配器
adapter.updateData(list); // 或重新 setAdapter
}
// ...
});
public class MyListAdapter extends BaseAdapter {
private List data = new ArrayList<>();
public void updateData(List newData) {
this.data.clear();
if (newData != null) this.data.addAll(newData);
notifyDataSetChanged(); // 通知 ListView 刷新
}
// ... getView 等方法
}
| 錯誤 | 後果 | 修正 |
|---|---|---|
| Comparator 返回固定值 | 排序無效、拋異常 | 正確實現 compare 邏輯 |
| 未處理 null Date | NPE 崩潰 | 在 compare 中優先判斷 null |
| 排序後未通知適配器 | UI 不更新 | 調用 notifyDataSetChanged() |
| 在 getView 中排序 | 極度低效、閃爍 | 在數據層排序、UI 只顯示 |
// RecyclerView 適配器使用 ListAdapter + DiffUtil
class MyAdapter extends ListAdapter {
MyAdapter() { super(DIFF_CALLBACK); }
static DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback<>() {
@Override boolean areItemsTheSame(DataItem old, DataItem new) { return old.id == new.id; }
@Override boolean areContentsTheSame(DataItem old, DataItem new) { return old.equals(new); }
};
// 提交新列表自動計算差異動畫
public void submitList(List list) { super.submitList(list); }
}