排序基于运行时属性的对象的列表(sort a list of objects based on ru

2019-08-03 04:41发布

我有虚拟组织的ArrayList。 这些对象有很多属性和相应的get / set方法。 我想排序在此基础上,我会在运行时得到一个属性这个数组列表。 让我详细解释。 我的VO是这样的

public class Employee {
    String name;
    String id;

    private String getName() {
        return name;
    }

    private String getId() {
        return id;
    }
}

我会得到在运行时字符串“sortType”,它可以是“身份证”或“名”。 我要排序基于字符串的值列表。

我曾尝试使用比较和反思起来,但没有运气。 可能是我没有使用它properly.I不希望的,如果循环使用,创造新的比较类。 没有其他的想法?

在尝试捕捉应该是新类里。 这里是工作的代码。 如果你想使用一个单独的类的比较,请找到它@下面波西米亚的评论。

        String sortType = "name"; // determined at runtime
        Collections.sort(results, new Comparator<Employee>() {
        public int compare(Employee c1, Employee c2) {
            try{
            Method m = c1.getClass().getMethod("get" + StringUtils.capitalize(sortType));
            String s1 = (String)m.invoke(c1);
            String s2 = (String)m.invoke(c2);
            return s1.compareTo(s2);
            }
            catch (Exception e) {
                return 0;
            }
        }
       });

Answer 1:

创建Comparator作业:

public class EmployeeComparator implements Comparator<Employee> {

    private final String type;

    public EmployeeComparator (String type) {
        this.type = type;
    }

    public int compare(Employee e1, Employee e2) {
        if (type.equals("name")) {
             return e1.getName().compareTo(e2.getName());
        }
        return e1.getId().compareTo(e2.getId());
    }

}

然后用它

String type = "name"; // determined at runtime
Collections.sort(list, new EmployeeComparator(type));

反射版本是相似的,但你能看到的“得到” +类型(大写)的对象上的方法,并调用该和它硬铸铁可比和使用的compareTo(我会尽量表现出的代码,但我“M用我的iPhone和它的一个有点夸张,但在这里不用)

public class DynamicComparator implements Comparator<Object> {
    private final String type;
    // pass in type capitalised, eg "Name" 
    // ie the getter method name minus the "get"
    public DynamicComparator (String type) {
        this.type = type;
    }
    public int compare(Object o1, Object o2) {
        // try-catch omitted 
        Method m = o1.getClass().getMethod("get" + type);
        String s1 = (String)m.invoke(o1);
        String s2 = (String)m.invoke(o2);
        return s1.compareTo(s2);
    }
}

OK ...以下是如何做到这一点,而无需创建一个类,使用匿名类(例外处理的代码编译):

List<?> list;
final String attribute = "Name"; // for example. Also, this is case-sensitive
Collections.sort(list, new Comparator<Object>() {
    public int compare(Object o1, Object o2) {
        try {
            Method m = o1.getClass().getMethod("get" + attribute);
            // Assume String type. If different, you must handle each type
            String s1 = (String) m.invoke(o1);
            String s2 = (String) m.invoke(o2);
            return s1.compareTo(s2);
        // simply re-throw checked exceptions wrapped in an unchecked exception
        } catch (SecurityException e) {
            throw new RuntimeException(e); 
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }
});


Answer 2:

请执行下列操作:

  • 从客户端得到的字段的名称
  • 建立吸气的名称 - >“获得” +字段名(大写的第一个字符后)
  • 尝试通过找到与反射方法Class.getDeclaredMethod()
  • 如果找到,则调用你的VO类的两个实例返回Method对象
  • 使用被调用的getter方法的结果进行排序


Answer 3:

把事情简单化!

如果选择的是唯一的idname -使用if语句。

两种选择之间采摘。 这是否已经发明了什么。

或者,如果它是许多属性,然后使用反射,或存储数据的Map摆在首位。 有时候Map是不是一个好班。 特别是如果你的VO必须不低于getter和setter等方法。

注意,虽然使用反射可能会在这种情况下不安全的客户端可能会在攻击类似于SQL注入注入的CGI参数的任何条款。



文章来源: sort a list of objects based on runtime property