基于其中一个字段对对象列表进行排序

时间:2012-08-02 10:55:27

标签: java sorting

Hello stackoverflow社区! 我是这些论坛的新手,也是java和android编程的新手 - 这恰好是我的问题的对象 - 所以对于任何错误提前抱歉!

我的问题是排序。我正在寻找一种方法来根据我选择的字段对对象进行排序(不是基于第一个字段进行排序,然后是下一个,例如比较器链接)。我相信我找到了解决问题的方法:

https://stackoverflow.com/a/5113108/1549672

但我实际上遇到了麻烦。我怀疑由于缺乏java经验,我可能会遗漏一些东西,所以欢迎任何帮助!

以下是我的尝试:

作为我的班级 -

public class ItemLocation {
String title;
int id;
}

作为我的职能 -

public void sort(final String field, List<ItemLocation> itemLocationList) {
    Collections.sort(itemLocationList, new Comparator<ItemLocation>() {
        @Override
        public int compare(ItemLocation o1, ItemLocation o2) {
            if(field.equals("title")) {
                return o1.title.compareTo(o2.title);
            } else if(field.equals("id")) {
                return Integer.valueOf(o1.id).compareTo(o2.id);
            }
            return 0;
        }
    });
}

使用这些,有人可能会举例说明使用这种方法吗?我试图填充一个ArrayList并对其进行排序,但无济于事。

感谢您的帮助!

4 个答案:

答案 0 :(得分:8)

如果不相等,则不应从Comparator.compare方法返回0。合同中的“okey”,但不完全鼓励,来自API文档:

  

通常情况如此,但并非严格要求(比较(x,   y)== 0)==(x.equals(y))。一般来说,任何比较器   违反这一条件应清楚地表明这一事实。该   建议的语言是“注意:这个比较器强制执行排序   与平等不一致。“


在我看来,您应该为每个字段返回一个特定的Comparator

Comparator<ItemLocation> titleComparator = new Comparator<ItemLocation>() {
    @Override
    public int compare(ItemLocation o1, ItemLocation o2) {
        return o1.title.compareTo(o2.title);
    }
}

Comparator<ItemLocation> idComparator = new Comparator<ItemLocation>() {
    @Override
    public int compare(ItemLocation o1, ItemLocation o2) {
        return Integer.valueOf(o1.id).compareTo(o2.id);
    }
}

public void sort(final String field, List<ItemLocation> itemLocationList) {

    final Comparator<ItemLocation> comparator;

    if(field.equals("title")) {
        comparator = titleComparator;
    } else if (field.equals("id")) {
        comparator = idComparator;
    } else {
        throw new IllegalArgumentException("Comparator not found for " + field);
    }

    Collections.sort(itemLocationList, comparator);
}

答案 1 :(得分:0)

你能发布不起作用的主叫代码吗?我看不出你提供的代码有什么明显的错误。

首先,您可能会尝试更多其他情况:

else {
    throw new IllegalArgumentException("Unrecognised field name");
}

目前,如果您的调用代码中有拼写错误,则比较器将始终返回0,这将使列表未排序。

传递字段的更强大的方法是声明枚举:

enum ItemLocationField {
    TITLE,
    ID
}

然后你的条件会变成:

if (field == ItemLocationField.TITLE)

等等。这样可以减少输入拼写错误的机会(如果你这样做,编译器会告诉你)。

答案 2 :(得分:0)

除了returning 0并将参数与equals进行比较之外,我没有看到任何错误。您可以按throwing RuntimeException而不是returning 0进行改进,并使用equalsIgnoreCase而不是equals方法,最好忽略参数的情况。

public static void sort(final String field, List<ItemLocation> itemLocationList) {
    Collections.sort(itemLocationList, new Comparator<ItemLocation>() {
        @Override
        public int compare(ItemLocation o1, ItemLocation o2) {
            if(field.equalsIgnoreCase("title")) {
                return o1.title.compareTo(o2.title);
            } else if(field.equalsIgnoreCase("id")) {
                return Integer.valueOf(o1.id).compareTo(o2.id);
            }else
                throw new IllegalArgumentException("Invalid Parameter .");
        }
    });
}

答案 3 :(得分:0)

1。如果您想在基础上仅对一个属性排序对象,请转到java.lang.Comparable界面以及Collections.sort(List<T> list) < / p>

2. 如果您想根据多个属性对对象进行排序,请转到        java.util.Comparator界面以及Collections.sort(List<T> list, Comparator<? super T> c)