java - 是否有一个 Java 框架可以实现一个简单灵活的多用途比较器,可以与 Java 1.7 一起使用

标签 java sorting frameworks java-7

很多次我需要根据不同的字段对对象列表进行排序,最后我编写了一个比较器,它使用反射根据给定的一个或多个方法对列表进行排序。是否有一个框架已经实现了类似的功能? Java 中是否已经实现了这个功能? (我在SO中搜索了java比较器框架,并找到了35个似乎没有解决这个问题的命中)。

类似这样的事情:

基于给定方法比较事物的比较器:

package org.myframework.util.comparator;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class SimpleComparator implements Comparator<Object> {

    //
    // instance variables
    //

    private ArrayList<Method> methods;

    //
    // constructors
    //

    public SimpleComparator() {
        this.methods = new ArrayList<Method>();
    }

    //
    // trivial getters and setters
    //

    public ArrayList<Method> getMethods() {
        return methods;
    }

    public void setMethods(ArrayList<Method> methods) {
        this.methods = methods;
    }

    //
    // implementation of compare
    //

    @Override
    public int compare(Object o1, Object o2) {
        for (Method method : this.methods) {
            int diff = this.compare(o1, o2, method);
            if (diff != 0) {
                return diff;
            }
        }
        return 0;
    }

    private int compare(Object o1, Object o2, Method method) {
        try {
            Object[] args = {};
            Comparable value1 = (Comparable) method.invoke(o1, args);
            Comparable value2 = (Comparable) method.invoke(o2, args);
            if (value1 == null && value2 == null) {
                return 0;
            } else if (value1 == null) {
                return 1;
            } else if (value2 == null) {
                return -1;
            } else {
                return value1.compareTo(value2);
            }
        } catch (Exception exp) {
            throw new RuntimeException(exp);
        }
    }

    public static <T> void sort(List<T> list, Class<T> cls, String methodName) {
        try {
            SimpleComparator comp = new SimpleComparator();
            Class[] parameterTypes = {};
            Method method = cls.getMethod(methodName, parameterTypes);
            comp.getMethods().add(method);
            Collections.sort(list, comp);
        } catch (Exception exp) {
            throw new RuntimeException(exp);
        }
    }

    public static <T> void sort(List<T> list, Class<T> cls, String[] methodNames) {
        try {
            SimpleComparator comp = new SimpleComparator();
            Class[] parameterTypes = {};
            for(String methodName : methodNames) {
                Method method = cls.getMethod(methodName, parameterTypes);
                comp.getMethods().add(method);
            }
            Collections.sort(list, comp);
        } catch (Exception exp) {
            throw new RuntimeException(exp);
        }
    }

}

可排序事物的示例事物类:

package org.myframework.util.comparator;

public class Thing {

    //
    // instance variables
    //

    private String name;

    private String color;

    private String hue;

    private int number;

    private float cost;

    //
    // constructor
    //

    public Thing(String name, String color, String hue, int number, float cost) {
        super();
        this.name = name;
        this.color = color;
        this.hue = hue;
        this.number = number;
        this.cost = cost;
    }

    //
    // trivial getters and setters
    //

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public String getHue() {
        return hue;
    }

    public void setHue(String hue) {
        this.hue = hue;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    public float getCost() {
        return cost;
    }

    public void setCost(float cost) {
        this.cost = cost;
    }

}

我希望能够做的事情的一个例子:

package org.myframework.util.comparator;

import java.util.ArrayList;
import java.util.List;

public class Example {

    public static void main(String[] args) {
        Thing thing1 = new Thing("thing1", "red  ", null, 1, 1.00f);
        Thing thing2 = new Thing("thing2", "green", null, 2, 100.00f);
        Thing thing3 = new Thing("thing3", "orange", null, 3, 3.00f);
        Thing thing4 = new Thing("thing4", "yellow", null, 4, 4.00f);
        Thing thing5 = new Thing("thing5", "red  ", "pink", 5, 5.00f);
        Thing thing6 = new Thing("thing6", "red  ", "maroon", 6, 6.00f);
        Thing thing7 = new Thing("thing7", "red  ", "candy", 7, 7.00f);
        Thing thing8 = new Thing("thing8", "red  ", "fire", 8, 8.00f);
        ArrayList<Thing> things = new ArrayList<Thing>();
        things.add(thing2);
        things.add(thing4);
        things.add(thing6);
        things.add(thing8);
        things.add(thing7);
        things.add(thing5);
        things.add(thing3);
        things.add(thing1);
        // the unsorted list
        System.out.println("\n\nBefore sort:");
        showList(things);
        // sort by name
        SimpleComparator.sort(things, Thing.class, "getName");
        System.out.println("\n\nSorted by name:");
        showList(things);
        // sort by color
        SimpleComparator.sort(things, Thing.class, "getColor");
        System.out.println("\n\nSorted by color:");
        showList(things);
        // sort by hue
        SimpleComparator.sort(things, Thing.class, "getHue");
        System.out.println("\n\nSorted by hue:");
        showList(things);
        // sort by color and hue
        String[] colorAndHue = { "getColor", "getHue" };
        SimpleComparator.sort(things, Thing.class, colorAndHue);
        System.out.println("\n\nSorted by color and hue:");
        showList(things);
        // sort by cost
        SimpleComparator.sort(things, Thing.class, "getCost");
        System.out.println("\n\nSorted by cost:");
        showList(things);
    }

    private static void showList(List<Thing> things) {
        for (Thing thing : things) {
            System.out.println(thing.getName() + "\t" + thing.getColor() + "\t" + thing.getHue() + "\t" + thing.getNumber() + "\t" + thing.getCost());
        }
    }

}

此示例的输出:

Before sort:
thing2  green   null    2   100.0
thing4  yellow  null    4   4.0
thing6  red     maroon  6   6.0
thing8  red     fire    8   8.0
thing7  red     candy   7   7.0
thing5  red     pink    5   5.0
thing3  orange  null    3   3.0
thing1  red     null    1   1.0


Sorted by name:
thing1  red     null    1   1.0
thing2  green   null    2   100.0
thing3  orange  null    3   3.0
thing4  yellow  null    4   4.0
thing5  red     pink    5   5.0
thing6  red     maroon  6   6.0
thing7  red     candy   7   7.0
thing8  red     fire    8   8.0


Sorted by color:
thing2  green   null    2   100.0
thing3  orange  null    3   3.0
thing1  red     null    1   1.0
thing5  red     pink    5   5.0
thing6  red     maroon  6   6.0
thing7  red     candy   7   7.0
thing8  red     fire    8   8.0
thing4  yellow  null    4   4.0


Sorted by hue:
thing7  red     candy   7   7.0
thing8  red     fire    8   8.0
thing6  red     maroon  6   6.0
thing5  red     pink    5   5.0
thing2  green   null    2   100.0
thing3  orange  null    3   3.0
thing1  red     null    1   1.0
thing4  yellow  null    4   4.0


Sorted by color and hue:
thing2  green   null    2   100.0
thing3  orange  null    3   3.0
thing7  red     candy   7   7.0
thing8  red     fire    8   8.0
thing6  red     maroon  6   6.0
thing5  red     pink    5   5.0
thing1  red     null    1   1.0
thing4  yellow  null    4   4.0


Sorted by cost:
thing1  red     null    1   1.0
thing3  orange  null    3   3.0
thing4  yellow  null    4   4.0
thing5  red     pink    5   5.0
thing6  red     maroon  6   6.0
thing7  red     candy   7   7.0
thing8  red     fire    8   8.0
thing2  green   null    2   100.0

最佳答案

从您提供的示例来看,似乎使用 Comparator.comparing在 Java 8 中,传递方法引用将是一个解决方案。

编辑:在OP请求后添加简单示例

Collections.sort(Comparator.comparing(Thing::getHue));

关于java - 是否有一个 Java 框架可以实现一个简单灵活的多用途比较器,可以与 Java 1.7 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32502084/

相关文章:

swift - 根据 Swift 中的可选字符串属性对自定义对象数组进行排序

java - 使用 MySQL 和 Java 优化排序功能

ios - 如何在 iOS 中制作供个人重用的框架(库?)?

c# Math.Sqrt 实现

java - 如何在无状态 Wicket 应用程序中使用 FeedbackPanel?

java - 为什么会发生 "Could not locate ordinal parameter [0], expecting one of []"?

c++ - 在 C++ 中对对象的输入数组进行排序

.net - .NET 应用程序的嵌入式 Web 服务器和 gui 框架

Java 类路径,未找到类

java - PHP Mysql 为什么会这样?安卓