根据用户在Java 8中选择的属性对列表进行动态排序

时间:2018-07-20 01:52:39

标签: java sorting java-8

我正在尝试使用Comparator.comparing()对具有其成员属性的列表进行排序,并且该属性是由用户选择的。考虑以下情况:

public class MyClass extends BaseClass
{
    private String attr1;
    private Date attr2;
    private ChildClass attr3;

    //getter and setter
}

public class ChildClass extends BaseClass
{
    private String attr1;
    private Date attr2;
    private int attr3;

    //getter and setter
}

这是我尝试过的,但是有编译错误。

private Map<String, Function<MyClass, ?>> sortingOptions = new HashMap<>();
private String sortBy;  //sorting attribute selected by user

@PostConstruct
public void init()
{
    //my list to be sort
    List<MyClass> list = myService.getList();

    sortingOptions.put("attr1", MyClass::getAttr1);
    sortingOptions.put("attr2", MyClass::getAttr2);
    //......
}

//listener for sorting option changed
public void sortOptionChangedListener()
{
    //this line of code having error
    list.sort(Comparator.comparing(sortingOptions.get[sortBy]));
}

显示的错误是

The method comparing(Function<? super T,? extends U>) in the type Comparator is not applicable for the arguments (Function<MyClass,capture#3-of ?>)

3 个答案:

答案 0 :(得分:5)

仅将方法引用存储在Map中而不​​是现在使用的Function中可能会更容易。考虑一下...

public class BaseClass implements Comparable<BaseClass> {
    @Override
    public int compareTo(BaseClass o) {
        // implement this properly
        return 0;
    }
}

public class MyClass extends BaseClass {
    private String attr1;
    private Date attr2;
    private ChildClass attr3;

    //getter and setter
}

public class ChildClass extends BaseClass
{
    private String attr1;
    private Date attr2;
    private int attr3;

    //getter and setter
}

private List<MyClass> list;
private Map<String, Comparator<? super MyClass>> sortingOptions = new HashMap<>();
private String sortBy;  //sorting attribute selected by user

@PostConstruct
public void init()
{
    //my list to be sort
    list = myService.getList();

    sortingOptions.put("attr1", Comparator.comparing(MyClass::getAttr1));
    sortingOptions.put("attr2", Comparator.comparing(MyClass::getAttr2));
    sortingOptions.put("attr3", Comparator.comparing(MyClass::getAttr3));
    //......
}

public void sortOptionChangedListener()
{
    list.sort(sortingOptions.get(sortBy));
}

答案 1 :(得分:0)

我认为克林顿是正确的。以下是Comparator ::比较源代码。

ICar

其参数是一个函数,其输入参数为T并且返回值为Comparable,这不适用于简单的getter。我认为反射可以做到这一点,但更为复杂。

答案 2 :(得分:-1)

您可以这样做:

private Map<String, Function<MyClass, ? extends Comparable>> sortingOptions = new HashMap<>();

您可能必须忍受警告,一个警告sortingOptions,另一个警告list.sort()

如果您希望它变得更整洁,可以制作一个辅助方法。

@SuppressWarnings("unchecked")
private <T, U extends Comparable<U>> Function<? super T, ? extends U> getComparator(String sortBy) {
    return (Function<T, U>) sortingOptions.get(sortBy);
}

用法:

list.sort(Comparator.comparing(getComparator(sortBy)));

更新

您应该按照克林顿的建议进行操作,这种方法更加简洁。