我正在爲jQuery數據表實現服務器端處理。對於那些不熟悉它的人來說,插件允許你對asc/desc列進行排序,以及用單個文本框搜索所有列。由於我的對象列表太大而無法發送到客戶端,我需要通過Java複製它的排序功能。按屬性排序收集,以字符串形式給出
這是我正在使用的對象。每個字段都是客戶端表中的一列。所有字段都是字符串或原語/包裝。
public class MyObject{
String id;
String productType;
String productGroup;
double totalSales;
double salesVariance;
int vendorId;
String vendorName;
}
我需要能夠通過任何字段,上升/下降的排序,沒有硬編碼爲每個字段比較功能。
給定一個表示字段名的字符串,我將如何實現一個通用的排序函數?
我目前的解決辦法是處理與犀牛列表... :)
調用犀牛Java方法:
/**
* @param sortBy - field name
* @param sortDirection - asc/desc
*/
public void applyFilteringChanges(List<MyObject> myObjects, String sortBy, String sortDirection) throws Exception{
Invocable invocable = (Invocable) engine;
invocable.invokeFunction("sortObjects", myObjects, sortBy, sortDirection);
}
犀牛代碼:
function sortObjects(myObjects, prop, direction) {
var dir = (direction === 'asc') ? 1 : -1;
myObjects.sort(function(a,b){
return compare(a,b,prop) * dir;
})
};
function compare(a,b,prop){
if(a[prop] < b[prop])
return -1;
else if(a[prop] > b[prop])
return 1;
return 0;
}
我還涉獵反思,但目前尚不完整。
public void applyFilteringChanges(List<MyObject> myObjects, String sortBy, String sortDirection) throws Exception{
myObjects.sort((s1,s2)->{
Field field;
try {
field = s1.getClass().getDeclaredField(sortBy);
Class<?> type = field.getType();
if(type.isPrimitive()){
//deal with primitive
}else{
Comparable o1FieldValue = (Comparable) field.get(s1);
Comparable o2FieldValue = (Comparable) field.get(s2);
return o1FieldValue.compareTo(o2FieldValue);
}
} catch (Exception e) {
e.printStackTrace();
}
return 0;
});
}
我的兩種方法都覺得像黑客,有沒有一種標準的方法來實現這一點?
排序任何屬性的對象,而不對這些屬性提供比較bascially給你留下了這些選項,即使用Java中的反射(您可以使用庫來簡化使用)或將對象轉換爲另一種表示形式(例如,用於Nashorn的JSON,地圖等),然後對其進行排序。但請注意:我不會在每次調用compare()時調用反射代碼,而是在實際排序之前調用反射代碼 - 至少需要檢索字段。 – Thomas