我有像List<Object> p
这样的对象列表。我想使用对象名称字段按字母顺序对此列表进行排序。对象包含10个字段,名称字段是其中之一。
if (list.size() > 0) {
Collections.sort(list, new Comparator<Campaign>() {
@Override
public int compare(final Object object1, final Object object2) {
return String.compare(object1.getName(), object2.getName());
}
} );
}
但是没有像String.compare那样的东西..?
答案 0 :(得分:210)
在您的代码中,您的Comparator
似乎已经使用Campaign
参数化了。这仅适用于List<Campaign>
。此外,您正在寻找的方法是compareTo
。
if (list.size() > 0) {
Collections.sort(list, new Comparator<Campaign>() {
@Override
public int compare(final Campaign object1, final Campaign object2) {
return object1.getName().compareTo(object2.getName());
}
});
}
或者如果您使用的是Java 1.8
list
.stream()
.sorted((object1, object2) -> object1.getName().compareTo(object2.getName()));
最后一条评论 - 检查列表大小没有意义。排序将在空列表中工作。
答案 1 :(得分:13)
按字母顺序排序字符串的最正确方法是使用Collator
,因为国际化。由于几乎没有额外的字符等,有些语言的顺序不同。
Collator collator = Collator.getInstance(Locale.US);
if (!list.isEmpty()) {
Collections.sort(list, new Comparator<Campaign>() {
@Override
public int compare(Campaign c1, Campaign c2) {
//You should ensure that list doesn't contain null values!
return collator.compare(c1.getName(), c2.getName());
}
});
}
如果您不关心国际化,请使用string.compare(otherString)
。
if (!list.isEmpty()) {
Collections.sort(list, new Comparator<Campaign>() {
@Override
public int compare(Campaign c1, Campaign c2) {
//You should ensure that list doesn't contain null values!
return c1.getName().compare(c2.getName());
}
});
}
答案 2 :(得分:11)
查看Collections.sort()
和Comparator
界面。
可以使用object1.getName().compareTo(object2.getName())
或object2.getName().compareTo(object1.getName())
进行字符串比较(取决于您希望的排序方向)。
如果您希望排序与案例无关,请执行object1.getName().toUpperCase().compareTo(object2.getName().toUpperCase())
。
答案 3 :(得分:7)
public class ObjectComparator implements Comparator<Object> {
public int compare(Object obj1, Object obj2) {
return obj1.getName().compareTo(obj2.getName());
}
}
请将您的班级替换为包含姓名字段
的班级用法:
ObjectComparator comparator = new ObjectComparator();
Collections.sort(list, comparator);
答案 4 :(得分:6)
使用Java 8 Comparator.comparing:
list.sort(Comparator.comparing(Campaign::getName));
答案 5 :(得分:2)
类似
List<FancyObject> theList = … ;
Collections.sort (theList,
new Comparator<FancyObject> ()
{ int compare (final FancyObject a, final FancyObject d)
{ return (a.getName().compareTo(d.getName())); }});
答案 6 :(得分:2)
这是Robert B的答案的一个版本,适用于List<T>
并使用Reflection对象的指定String属性进行排序,而没有第三方库
/**
* Sorts a List by the specified String property name of the object.
*
* @param list
* @param propertyName
*/
public static <T> void sortList(List<T> list, final String propertyName) {
if (list.size() > 0) {
Collections.sort(list, new Comparator<T>() {
@Override
public int compare(final T object1, final T object2) {
String property1 = (String)ReflectionUtils.getSpecifiedFieldValue (propertyName, object1);
String property2 = (String)ReflectionUtils.getSpecifiedFieldValue (propertyName, object2);
return property1.compareToIgnoreCase (property2);
}
});
}
}
public static Object getSpecifiedFieldValue (String property, Object obj) {
Object result = null;
try {
Class<?> objectClass = obj.getClass();
Field objectField = getDeclaredField(property, objectClass);
if (objectField!=null) {
objectField.setAccessible(true);
result = objectField.get(obj);
}
} catch (Exception e) {
}
return result;
}
public static Field getDeclaredField(String fieldName, Class<?> type) {
Field result = null;
try {
result = type.getDeclaredField(fieldName);
} catch (Exception e) {
}
if (result == null) {
Class<?> superclass = type.getSuperclass();
if (superclass != null && !superclass.getName().equals("java.lang.Object")) {
return getDeclaredField(fieldName, type.getSuperclass());
}
}
return result;
}
答案 7 :(得分:2)
您可以使用Eclipse Collections中的sortThisBy()
:
MutableList<Campaign> list = Lists.mutable.empty();
list.sortThisBy(Campaign::getName);
如果您无法从List
更改列表类型:
List<Campaign> list = new ArrayList<>();
ListAdapter.adapt(list).sortThisBy(Campaign::getName);
注意:我是Eclipse Collections的撰稿人。
答案 8 :(得分:1)
如果你的对象有一些共同的祖先[让它为T
]你应该使用List<T>
而不是List<Object>
,并为此T实现Comparator,使用名称字段。
如果你没有共同的祖先,你可以实现一个Comperator,并使用reflection来提取名称,注意它是不安全的,未建议的,并且使用反射会有糟糕的性能,但它允许您访问字段名称,而不知道对象的实际类型[除了它有一个具有相关名称的字段的事实]
在这两种情况下,您都应该使用Collections.sort()进行排序。
答案 9 :(得分:1)
我找到了另一种打字方法。
if(listAxu.size() > 0){
Collections.sort(listAxu, Comparator.comparing(IdentityNamed::getDescricao));
}
答案 10 :(得分:1)
试试这个:
List< Object> myList = x.getName;
myList.sort(Comparator.comparing(Object::getName));
答案 11 :(得分:0)
if(listAxu.size() > 0){
Collections.sort(listAxu, new Comparator<Situacao>(){
@Override
public int compare(Situacao lhs, Situacao rhs) {
return lhs.getDescricao().compareTo(rhs.getDescricao());
}
});
}
答案 12 :(得分:0)
如果您使用List<Object>
来保存具有名称字段的子类型的对象(让我们调用子类型NamedObject
),您需要向下转换列表元素以便访问名称。你有3个选项,其中最好的是第一个:
List<Object>
- 将您的命名对象保留在List<NamedObject>
List<Object>
元素复制到List<NamedObject>
,在此过程中进行向下转换,进行排序,然后将其复制回来选项3看起来像这样:
Collections.sort(p, new Comparator<Object> () {
int compare (final Object a, final Object b) {
return ((NamedObject) a).getName().compareTo((NamedObject b).getName());
}
}
答案 13 :(得分:0)
使用选择排序
for(int i = list.size() - 1; i > 0; i--){
int max = i
for(int j = 0; j < i; j++){
if(list.get(j).getName().compareTo(list.get(j).getName()) > 0){
max= j;
}
}
//make the swap
Object temp = list.get(i);
list.get(i) = list.get(max);
list.get(max) = temp;
}
答案 14 :(得分:0)
这假定是YourClass
而不是Object
的列表,正如 amit 所解释的那样。
您可以使用Google Guava库中的这一位:
Collections.sort(list, Ordering.natural()
.onResultOf(new Function<String,YourClass>() {
public String call(YourClass o) {
return o.getName();
}))
.nullsLast();
提及Comparator
的其他答案并不正确,因为Ordering
实现了Comparator
。在我看来,这个解决方案稍微容易一点,但如果你是初学者并且不习惯使用库和/或“函数式编程”,可能会更难。
答案 15 :(得分:0)
@Victor的答案对我有用,并将其重新发布在Kotlin中,以防其他使用Android的人使用。
if (list!!.isNotEmpty()) {
Collections.sort(
list,
Comparator { c1, c2 -> //You should ensure that list doesn't contain null values!
c1.name!!.compareTo(c2.name!!)
})
}
答案 16 :(得分:-1)
你可以使用这个:
List<Campaign> list = new ArrayList<>();
list.sort(Comparator.comparing(Campaign::getName));