java 根据其中一个字段对对象列表进行排序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11775980/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sorting a List of Objects Based on 1 of its Fields
提问by user1549672
Hello stackoverflow community! I am new to these forums and also fairly new to java and android programming--which happen to be the objects of my question--so sorry in advance for any blunders!
你好 stackoverflow 社区!我是这些论坛的新手,对 java 和 android 编程也很陌生——这恰好是我的问题的对象——所以提前为任何错误道歉!
My issue is sorting. I am looking for a method to sort objects based on a field that I choose (not sorting based on the first field, then the next, etc. exemplified by comparator chaining). I believe I've found the solution to my problem:
我的问题是排序。我正在寻找一种方法来根据我选择的字段对对象进行排序(不是根据第一个字段排序,然后是下一个字段,等等,以比较器链接为例)。我相信我已经找到了解决问题的方法:
https://stackoverflow.com/a/5113108/1549672
https://stackoverflow.com/a/5113108/1549672
but I am having trouble actually getting this to work. I have a suspicion that I'm probably missing something due to my lack of java experience, so any help is welcome!
但我在实际使用它时遇到了麻烦。我怀疑由于我缺乏 Java 经验,我可能遗漏了一些东西,所以欢迎任何帮助!
Here is what I am trying:
这是我正在尝试的:
As my class-
作为我的班级-
public class ItemLocation {
String title;
int id;
}
As my function-
作为我的功能-
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;
}
});
}
using these, could someone possibly give an example of using this method? I attempted to fill an ArrayList and sort it, but to no avail.
使用这些,有人可以举一个使用这种方法的例子吗?我试图填充一个 ArrayList 并对其进行排序,但无济于事。
Thanks for the help!
谢谢您的帮助!
回答by dacwe
You should not return 0
from the Comparator.compare
method if they are not equal. It's "okey" by the contract, but not exactly encouraged, from the API documentation:
如果它们不相等,则不0
应从该Comparator.compare
方法返回。从 API 文档来看,合同是“好的”,但并不完全鼓励:
It is generally the case, but not strictly required that (compare(x, y)==0) == (x.equals(y)). Generally speaking, any comparator that violates this condition should clearly indicate this fact. The recommended language is "Note: this comparator imposes orderings that are inconsistent with equals."
通常是这种情况,但并不严格要求 (compare(x, y)==0) == (x.equals(y))。一般而言,任何违反此条件的比较器都应清楚表明这一事实。推荐的语言是“注意:这个比较器强加了与 equals 不一致的排序。”
In my opinion you should return a specific Comparator
for each field instead:
在我看来,您应该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);
}
回答by Martin
Can you post the calling code that is not working? I can't see anything clearly wrong with the code you've provided.
您可以发布不起作用的调用代码吗?我看不出你提供的代码有什么明显的错误。
Firstly, you might try is putting an extra else case like so:
首先,您可以尝试放置一个额外的 else 案例,如下所示:
else {
throw new IllegalArgumentException("Unrecognised field name");
}
At the moment, if you had a typo in your calling code, the comparator would always return 0, which would leave the list unsorted.
目前,如果您的调用代码中有拼写错误,比较器将始终返回 0,这将使列表未排序。
A more robust way of passing the field would be to declare an enum:
传递该字段的更强大的方法是声明一个枚举:
enum ItemLocationField {
TITLE,
ID
}
Then your conditions would become:
那么你的条件就会变成:
if (field == ItemLocationField.TITLE)
and so on. That would reduce the chances of making a typo (the compiler will tell you if you do).
等等。这将减少打错字的机会(编译器会告诉你如果你这样做了)。
回答by amicngh
I don't see anything wrong except returning 0
and comparing parameter with equals
. you can improve it by throwing RuntimeException
rather than returning 0
and use equalsIgnoreCase
rather than equals
method , better to ignore the case of parameter.
除了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 .");
}
});
}
回答by Kumar Vivek Mitra
1.If you want to Sort object on the basis of only one attribute, then go for java.lang.Comparable
Interface along with Collections.sort(List<T> list)
1.如果你只想根据一个属性对对象进行排序,那么就选择java.lang.Comparable
Interface 和Collections.sort(List<T> list)
2.If you want to Sort the object on the basis of more than one attributes, then go for
java.util.Comparator
Interface along with Collections.sort(List<T> list, Comparator<? super T> c)
2.如果要根据多个属性对对象进行排序,请选择
java.util.Comparator
Interface 以及Collections.sort(List<T> list, Comparator<? super T> c)