J'ai une liste d'objets comme List<Object> p
. Je veux trier cette liste par ordre alphabétique en utilisant le champ Nom de l'objet. L'objet contient 10 champs et le champ nom en est un.
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.compare ..?
D'après 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 est inutile de vérifier la taille de la liste. Sort travaillera sur une liste vide.
La méthode la plus correcte pour trier les chaînes alphabétiquement consiste à 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());
}
});
}
Regardez Collections.sort()
et l'interface Comparator
.
La comparaison de chaînes peut être effectuée avec object1.getName().compareTo(object2.getName())
ou object2.getName().compareTo(object1.getName())
(selon le sens du tri souhaité).
Si vous voulez que la sorte soit agnostique à la casse, faites 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());
}
}
Veuillez remplacer Object par votre classe qui contient le champ name
Usage:
ObjectComparator comparator = new ObjectComparator();
Collections.sort(list, comparator);
Utilisation de Java 8 Comparator.comparing :
list.sort(Comparator.comparing(Campaign::getName));
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())); }});
Voici une version de la réponse de Robert B qui fonctionne pour List<T>
et qui est triée en fonction d'une propriété String spécifiée de l'objet à l'aide de Reflection et 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;
}
Vous pouvez utiliser sortThisBy()
de Eclipse Collections :
MutableList<Campaign> list = Lists.mutable.empty();
list.sortThisBy(Campaign::getName);
Si vous ne pouvez pas changer le type de liste de List
:
List<Campaign> list = new ArrayList<>();
ListAdapter.adapt(list).sortThisBy(Campaign::getName);
Remarque: je contribue aux collections Eclipse.
Essaye ça:
List< Object> myList = x.getName;
myList.sort(Comparator.comparing(Object::getName));
Si vos objets ont un ancêtre commun [soit T
], vous devez utiliser List<T>
au lieu de List<Object>
et implémenter un Comparateur pour ce T, en utilisant le champ de nom.
Si vous n'avez pas d'ancêtre commun, vous pouvez implémenter un compilateur et utiliser réflexion pour extraire le nom. Notez qu'il est dangereux, qu'il n'a pas été suggéré et qu'il présente de mauvaises performances si vous utilisez la réflexion. vous permet d'accéder à un nom de champ sans rien connaître du type réel de l'objet [outre le fait qu'il comporte un champ avec le nom correspondant]
Dans les deux cas, vous devez utiliser Collections.sort () pour trier.
Ceci 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();
Les autres réponses qui mentionnent Comparator
ne sont pas incorrectes, car Ordering
implémente Comparator
. Cette solution est, à mon avis, un peu plus facile, bien que cela puisse être plus difficile si vous êtes débutant et que vous n'êtes pas habitué à utiliser des bibliothèques et/ou une "programmation fonctionnelle".
Copié sans vergogne de cette réponse à ma propre question.
Si vous utilisez un List<Object>
pour contenir des objets d'un sous-type comportant un champ de nom (appelons le sous-type NamedObject
), vous devez rétrograder les éléments de la liste pour pouvoir accéder au nom. Vous avez 3 options dont la meilleure est la première:
List<Object>
en premier lieu si vous pouvez l'aider - conservez vos objets nommés dans un List<NamedObject>
List<Object>
dans un List<NamedObject>
, vers le bas dans le processus, faites le tri, puis recopiez-les.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());
}
}
Utiliser une sélection Trier
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;
}
if(listAxu.size() > 0){
Collections.sort(listAxu, new Comparator<Situacao>(){
@Override
public int compare(Situacao lhs, Situacao rhs) {
return lhs.getDescricao().compareTo(rhs.getDescricao());
}
});
}