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..?
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.
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());
}
});
}
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())
.
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);
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 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;
}
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.
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.
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.
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;
}
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:
- Ne pas utiliser un
List<Object>
, en premier lieu, si vous pouvez l'aider - gardez vos objets nommés dans unList<NamedObject>
- copiez vos éléments
List<Object>
dans unList<NamedObject>
, downcasting dans le processus, faites le tri, puis copiez-les - 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());
}
}
if(listAxu.size() > 0){
Collections.sort(listAxu, new Comparator<Situacao>(){
@Override
public int compare(Situacao lhs, Situacao rhs) {
return lhs.getDescricao().compareTo(rhs.getDescricao());
}
});
}
En Utilisant Java 8 Comparateur.comparaison :
list.sort(Comparator.comparing(Campaign::getName));
Essayez ceci:
List< Object> myList = x.getName;
myList.sort(Comparator.comparing(Object::getName));