2017-02-20 26 views
1

我正在为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; 
     }); 

    } 

我的两种方法都觉得像黑客,有没有一种标准的方法来实现这一点?

+2

排序任何属性的对象,而不对这些属性提供比较bascially给你留下了这些选项,即使用Java中的反射(您可以使用库来简化使用)或将对象转换为另一种表示形式(例如,用于Nashorn的JSON,地图等),然后对其进行排序。但请注意:我不会在每次调用compare()时调用反射代码,而是在实际排序之前调用反射代码 - 至少需要检索字段。 – Thomas

回答

0

您可以创建一个通用的比较是这样的:

class MyComparator<T extends MyObject> implements Comparator<T> { 

    private String field; 

    public MyComparator(String field) { 
     this.field = field; 
    } 

    @Override 
    public int compare(T o1, T o2) { 
     switch (field) { 
      case "id" : 
       return o1.id.compareTo(o2.id); 

      case "productType": 
       return o1.productType.compareTo(o2.productType); 

      case "productGroup": 
       return o1.productGroup.compareTo(o2.productGroup); 

      //... 
     } 
     return 0; 
    } 
} 

使用方法如下:

public static void main(String[] args) 
{ 
    List<MyObject> objects = new ArrayList<>(); 

    Collections.sort(objects, new MyComparator<>("id")); 
} 
+2

这种做法违反了“没有为每个字段硬编码比较器功能”的要求。“ – Thomas

+0

是的,但作为他的问题的一部分是“我将如何实现通用分类功能” –