如何按字母顺序使用Object name字段对List <Object>进行sorting

我有一个对象List<Object> pList<Object> p我想按字母顺序使用对象名称字段sorting此列表。 对象包含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 ..?

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

最后一点评论 – 检查清单大小没有意义。 sorting将在一个空的列表上工作。

按字母顺序sortingstring的最正确方法是使用Collator ,因为国际化。 有些语言由于less数多余的字符而有不同的顺序

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

看看Collections.sort()Comparator接口。

string比较可以用object1.getName().compareTo(object2.getName())object2.getName().compareTo(object1.getName()) (取决于你想要的sorting方向)。

如果你想sorting是不区分大小写的,请执行object1.getName().toUpperCase().compareTo(object2.getName().toUpperCase())

 public class ObjectComparator implements Comparator<Object> { public int compare(Object obj1, Object obj2) { return obj1.getName().compareTo(obj2.getName()); } } 

请用包含名称字段的类replaceObject

用法:

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

这里是罗伯特B的答案的一个版本的工作List<T>和sorting的对象指定的string属性使用reflection和没有第三方库

 /** * 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; } 

你可以在Eclipse Collections中使用sortThisBy()

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

如果您不能从List更改列表的types:

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

注意:我是Eclipse Collections的贡献者。

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

如果你没有一个共同的祖先,你可以实现一个Comperator,并使用reflection来提取名称,请注意,这是不安全的,不被恳求的,使用reflection的性能不好,但它允许你访问一个字段名不知道任何有关对象的实际types[除了它有一个与相关名称字段的事实]

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

这是假设列表的YourClass而不是Object ,由阿米特解释。

您可以使用Google Guava库中的这一点:

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

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

在我自己的问题上从这个答案无耻地复制。

使用selectsorting

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

如果使用List<Object>来保存具有名称字段(允许调用子typesNamedObject )的子types的对象,则需要向下转发列表元素才能访问该名称。 你有3个选项,其中最好的是第一个:

  1. 如果可以帮助的话,不要首先使用List<Object> – 将您的命名对象保存在List<NamedObject>
  2. List<Object>元素复制到List<NamedObject> ,在该过程中向下转换,进行sorting,然后将其复制回来
  3. 在比较器中进行向下转换

选项3将如下所示:

 Collections.sort(p, new Comparator<Object> () { int compare (final Object a, final Object b) { return ((NamedObject) a).getName().compareTo((NamedObject b).getName()); } } 
 if(listAxu.size() > 0){ Collections.sort(listAxu, new Comparator<Situacao>(){ @Override public int compare(Situacao lhs, Situacao rhs) { return lhs.getDescricao().compareTo(rhs.getDescricao()); } }); }