如何使用对象名称字段</object>按字母顺序对List <object>进行排序

时间:2011-12-08 14:32:52

标签: java list

我有像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那样的东西..?

17 个答案:

答案 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个选项,其中最好的是第一个:

  1. 如果您可以提供帮助,请不要首先使用List<Object> - 将您的命名对象保留在List<NamedObject>
  2. 将您的List<Object>元素复制到List<NamedObject>,在此过程中进行向下转换,进行排序,然后将其复制回来
  3. 在比较器中进行向下转换
  4. 选项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。在我看来,这个解决方案稍微容易一点,但如果你是初学者并且不习惯使用库和/或“函数式编程”,可能会更难。

this answer on my own question.

无耻地复制

答案 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));