How to sort a List<Object> alphabetically using Object name field

I have a List of Objects like List<Object> p.I want to sort this list alphabetically using Object name field. Object contains 10 field and name field is one of them.

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());
}
} );
}

But there is nothing like String.compare..?

221435 次浏览

看一下 Collections.sort()Comparator接口。

字符串比较可以用 object1.getName().compareTo(object2.getName())object2.getName().compareTo(object1.getName())完成(取决于您希望的排序方向)。

如果希望排序是不区分大小写的,请执行 object1.getName().toUpperCase().compareTo(object2.getName().toUpperCase())

如果您的对象有一些共同的祖先[让它是 T] ,您应该使用 List<T>而不是 List<Object>,并使用 name 字段为这个 T 实现一个 比较器

如果你没有一个共同的祖先,你可以实现一个 Comperator,并使用 反思来提取名称。注意,使用反射是不安全的,没有建议的,并且性能很差,但是它允许你访问一个字段名称,而不需要知道对象的实际类型(除了它有一个具有相关名称的字段)

在这两种情况下,都应该使用 Collections.sort ()进行排序。

这是假设一个 YourClass而不是 Object的列表,正如 amit所解释的那样。

你可以从谷歌番石榴图书馆中使用这一点:

Collections.sort(list, Ordering.natural()
.onResultOf(new Function<String,YourClass>() {
public String call(YourClass o) {
return o.getName();
}))
.nullsLast();

其他提到 Comparator的答案并不是不正确的,因为 Ordering实现了 Comparator。在我看来,这个解决方案稍微容易一些,但是如果你是个初学者,并且不习惯使用库和/或“函数式编程”,那么这个解决方案可能会更难一些。

厚颜无耻地抄袭 回答我自己的问题。

public class ObjectComparator implements Comparator<Object> {


public int compare(Object obj1, Object obj2) {
return obj1.getName().compareTo(obj2.getName());
}


}

请将 Object 替换为类 which contains name field

用法:

ObjectComparator comparator = new ObjectComparator();
Collections.sort(list, comparator);

比如

  List<FancyObject> theList = … ;
Collections.sort (theList,
new Comparator<FancyObject> ()
{ int compare (final FancyObject a, final FancyObject d)
{ return (a.getName().compareTo(d.getName())); }});

使用选择排序

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;


}

从您的代码来看,您的 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()));

最后一个注释——检查列表大小没有意义。排序将在空列表上工作。

如果使用 List<Object>来保存具有名称字段的子类型的对象(让我们调用子类型 NamedObject) ,则需要向下转换列表元素以访问名称。你有三个选择,其中最好的是第一个:

  1. 如果可以的话,首先不要使用 List<Object>-将命名对象保存在 List<NamedObject>
  2. List<Object>元素复制到 List<NamedObject>中,在过程中向下转换,进行排序,然后将它们复制回来
  3. 在比较器中执行向下转换

选项3是这样的:

Collections.sort(p, new Comparator<Object> () {
int compare (final Object a, final Object b) {
return ((NamedObject) a).getName().compareTo((NamedObject b).getName());
}
}

按字母顺序排序字符串的最正确方法是使用 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());
}
});
}

下面是 Robert B 的答案的一个版本,它适用于 List<T>,通过使用反射对象的指定 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;
}
if(listAxu.size() > 0){
Collections.sort(listAxu, new Comparator<Situacao>(){
@Override
public int compare(Situacao lhs, Situacao rhs) {
return lhs.getDescricao().compareTo(rhs.getDescricao());
}
});
}

你可以从 Eclipse 集合使用 sortThisBy():

MutableList<Campaign> list = Lists.mutable.empty();
list.sortThisBy(Campaign::getName);

如果不能从 List改变列表的类型:

List<Campaign> list = new ArrayList<>();
ListAdapter.adapt(list).sortThisBy(Campaign::getName);

注意: 我是 Eclipse 集合的贡献者。

使用 Java8比较器,比较:

list.sort(Comparator.comparing(Campaign::getName));

Try this:

List< Object> myList = x.getName;
myList.sort(Comparator.comparing(Object::getName));

我找到了另一种方法。

if(listAxu.size() > 0){
Collections.sort(listAxu, Comparator.comparing(IdentityNamed::getDescricao));
}

@Victor's answer worked for me and reposting it here in Kotlin in case useful to someone else doing 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!!)
})
}

You can use this:

List<Campaign> list = new ArrayList<>();
list.sort(Comparator.comparing(Campaign::getName));

In case property contains also NULL values you can use:

list.sort(Comparator.comparing(Campaign::getName, Comparator.nullsLast(Comparator.naturalOrder())));

这会将 NULL值放到排序列表中的最后一个位置。