Comment trier une liste Par Ordre alphabétique à l'aide du champ Nom D'objet

J'ai une liste d'objets comme List<Object> p.Je veux trier cette liste Par Ordre alphabétique en utilisant le champ Nom D'objet. Objet contient 10 champ et champ nom est l'un d'entre eux.

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

Mais il n'y a rien comme String.comparer..?

90
demandé sur David Newcomb 2011-12-08 18:32:51

14 réponses

À partir de votre code, il semble que votre Comparator soit déjà paramétré avec Campaign. Cela ne fonctionnera qu'avec List<Campaign>. En outre, la méthode que vous recherchez est 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());
      }
  });
}

, Ou si vous utilisez Java 1.8

list
  .stream()
  .sorted((object1, object2) -> object1.getName().compareTo(object2.getName()));

Un Dernier commentaire - il ne sert à rien de vérifier la taille de la liste. Tri fonctionnera sur une liste vide.

201
répondu Robert B 2017-02-17 07:55:41

La façon la plus correcte de trier les chaînes par ordre alphabétique est d'utiliser Collator, en raison de l'internationalisation. Certaines langues ont un ordre différent en raison de quelques caractères supplémentaires etc.

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

Si vous ne vous souciez pas de l'internationalisation, utilisez 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());
        }
       });
   }
12
répondu viktor 2011-12-08 15:49:30

Regardez Collections.sort() et le Comparator interface.

La comparaison de Chaînes peut se faire avec object1.getName().compareTo(object2.getName()) ou object2.getName().compareTo(object1.getName()) (selon la direction de tri souhaitée).

Si vous voulez que le tri soit agnostique, faites object1.getName().toUpperCase().compareTo(object2.getName().toUpperCase()).

10
répondu tobiasbayer 2011-12-08 15:51:19
public class ObjectComparator implements Comparator<Object> {

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

}

Veuillez remplacer L'objet par votre classe qui contient le champ Nom

Utilisation:

ObjectComparator comparator = new ObjectComparator();
Collections.sort(list, comparator);
7
répondu Jan Vorcak 2011-12-08 14:39:03

Quelque Chose comme

  List<FancyObject> theList = … ;
  Collections.sort (theList,
                    new Comparator<FancyObject> ()
                    { int compare (final FancyObject a, final FancyObject d)
                          { return (a.getName().compareTo(d.getName())); }});
2
répondu BRPocock 2011-12-08 14:40:31

Voici une version de la réponse de Robert B qui fonctionne pour List<T> et le tri par une propriété de chaîne spécifiée de l'objet en utilisant la réflexion et pas de bibliothèques tierces

/**
 * 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;
}
2
répondu che javara 2014-10-27 21:30:19

Vous pouvez utiliser sortThisBy() à partir de Eclipse Collections:

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

Si vous ne pouvez pas modifier le type de liste à partir de List:

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

Remarque: je suis un contributeur aux Collections Eclipse.

2
répondu Nikhil Nanivadekar 2016-03-27 01:18:20

Si vos objets ont un ancêtre commun [let it be T] Vous devez utiliser List<T> au lieu de List<Object>, et implémenter un comparateur pour ce T, en utilisant le champ name.

Si vous n'avez pas d'ancêtre commun, vous pouvez implémenter un Comperator, et utiliser reflection pour extraire le nom, notez qu'il est dangereux, non testé et souffre de mauvaises performances pour utiliser reflection, mais il vous permet d'accéder à un nom de champ sans rien savoir sur le type réel de l'objet [outre le fait qu'il dispose d'un champ avec le nom]

Dans les deux cas, vous devez utiliser Collections.trier () {[5] } pour trier.

1
répondu amit 2011-12-08 14:41:51

Cela suppose une liste de YourClass au lieu de Object, comme expliqué par amit.

Vous pouvez utiliser ce bit de la bibliothèque Google Guava:

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

Autres réponses qui mentionnent Comparator ne sont pas erronée, puisque Ordering implémente Comparator. Cette solution est, à mon avis, Un peu plus facile, même si cela peut être plus difficile si vous êtes un débutant et que vous n'avez pas l'habitude d'utiliser des bibliothèques et/ou de la "programmation fonctionnelle".

Copié sans vergogne de cette réponse sur mon propre question.

0
répondu Bart van Heukelom 2017-05-23 10:31:28

Utiliser un tri de sélection

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;

}
0
répondu Shizumaru18 2011-12-08 14:51:04

Si vous utilisez un List<Object> pour contenir des objets d'un sous-type qui a un champ Nom (appelons le sous-type NamedObject), vous devrez réduire les éléments de la liste pour accéder au nom. Vous avez 3 options, dont la meilleure est la première:

  1. Ne pas utiliser un List<Object>, en premier lieu, si vous pouvez l'aider - gardez vos objets nommés dans un List<NamedObject>
  2. copiez vos éléments List<Object> dans un List<NamedObject>, downcasting dans le processus, faites le tri, puis copiez-les
  3. faites le downcasting dans le comparateur

L'Option 3 ressemblerait à ceci:

Collections.sort(p, new Comparator<Object> () {
        int compare (final Object a, final Object b) {
                return ((NamedObject) a).getName().compareTo((NamedObject b).getName());
        }
}
0
répondu Mike E 2011-12-08 14:58:41
if(listAxu.size() > 0){
     Collections.sort(listAxu, new Comparator<Situacao>(){
        @Override
        public int compare(Situacao lhs, Situacao rhs) {            
            return lhs.getDescricao().compareTo(rhs.getDescricao());
        }
    });
 }
0
répondu George Freire 2015-01-28 14:34:58

En Utilisant Java 8 Comparateur.comparaison :

list.sort(Comparator.comparing(Campaign::getName));
0
répondu Oleksandr 2018-02-06 22:10:51

Essayez ceci:

List< Object> myList = x.getName;
myList.sort(Comparator.comparing(Object::getName));
0
répondu Alper Karaağaçlı 2018-03-09 12:02:50