根据运行时属性对对象列表进行排序 [英] sort a list of objects based on runtime property

查看:131
本文介绍了根据运行时属性对对象列表进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个VO的arraylist。这些对象具有许多属性和相应的get / set方法。我想基于我将在运行时获得的属性对此数组列表进行排序。
让我详细解释一下。我的VO是这样的

I have an arraylist of VOs. These objects have many properties and corresponding get/set methods. I want to sort this array list based on a property which I'll be getting in runtime. Let me explain in detail. My VO is like this

public class Employee {
    String name;
    String id;

    private String getName() {
        return name;
    }

    private String getId() {
        return id;
    }
}

我将在运行时获取字符串'sortType' ,可以是'id'或'name'。我想根据字符串的值对列表进行排序。

I will be getting a string ‘sortType’ in runtime, which can be either ‘id’ or ‘name’. I want to sort the list based on the value of the string.

我试图一起使用比较器和反射,但没有运气。可能是我没有正确使用它。我不想使用if循环并创建新的比较器类。还有其他想法吗?

I have tried to use comparator and reflection together, but no luck. May be I didn't use it properly.I don’t want to use an if loop and create new comparator classes. Any other thoughts?

try catch应该在新类中。这是工作代码。如果你想为比较器使用一个单独的类,请在@ Bohemian的评论中找到它。

The try catch should be inside the new class. Here is the working code. If you want to use a separate class for comparator, please find it in @Bohemian's comment below.

        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;
            }
        }
       });


推荐答案

创建一个比较器用于工作:

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));

反射版本类似,除非您在获取对象上寻找方法+ type(大写)并调用它并将其强制转换为Comparable并使用compareTo(我将尝试显示代码,但我正在使用我的iPhone并且它有点延伸,但是这里去了)

The reflective version would be similar, except you would look for a method on the object of "get" + type (capitalised) and invoke that and hard cast it to Comparable and use compareTo (I'll try to show the code, but I'm using my iPhone and its a bit of a stretch, but here goes)

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... Here's how to do it without creating a class, using an anonymous class (with exception handling so code compiles):

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);
        }
    }
});

这篇关于根据运行时属性对对象列表进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆