J'ai une liste de doubles en Java et je veux trier ArrayList par ordre décroissant.
Input ArrayList est comme ci-dessous:
List<Double> testList = new ArrayList();
testList.add(0.5);
testList.add(0.2);
testList.add(0.9);
testList.add(0.1);
testList.add(0.1);
testList.add(0.1);
testList.add(0.54);
testList.add(0.71);
testList.add(0.71);
testList.add(0.71);
testList.add(0.92);
testList.add(0.12);
testList.add(0.65);
testList.add(0.34);
testList.add(0.62);
La sortie devrait être comme ça
0.92
0.9
0.71
0.71
0.71
0.65
0.62
0.54
0.5
0.34
0.2
0.12
0.1
0.1
0.1
Collections.sort(testList);
Collections.reverse(testList);
Cela fera ce que vous voulez. N'oubliez pas d'importer Collections
cependant!
Descendant:
Collections.sort(mArrayList, new Comparator<CustomData>() {
@Override
public int compare(CustomData lhs, CustomData rhs) {
// -1 - less than, 1 - greater than, 0 - equal, all inversed for descending
return lhs.customInt > rhs.customInt ? -1 : (lhs.customInt < rhs.customInt) ? 1 : 0;
}
});
Utilisez la méthode util de Java.util.Collections class, c.-à-d.
Collections.sort(list)
En fait, si vous voulez trier un objet personnalisé, vous pouvez utiliser
Collections.sort(List<T> list, Comparator<? super T> c)
voir les collections api
Pour votre exemple, cela fera la magie de Java 8
List<Double> testList = new ArrayList();
testList.sort(Comparator.naturalOrder());
Mais si vous souhaitez trier certains des champs de l'objet que vous triez, vous pouvez le faire facilement en:
testList.sort(Comparator.comparing(ClassName::getFieldName));
ou
testList.sort(Comparator.comparing(ClassName::getFieldName).reversed());
ou
testList.stream().sorted(Comparator.comparing(ClassName::getFieldName).reversed()).collect(Collectors.toList());
Sources: https://docs.Oracle.com/javase/8/docs/api/Java/util/Comparator.html
En utilisant lambdas (Java8) et en le réduisant à la syntaxe la plus simple (la JVM déduira beaucoup dans ce cas), vous obtenez:
Collections.sort(testList, (a, b) -> b.compareTo(a));
Une version plus verbeuse:
// Implement a reverse-order Comparator by lambda function
Comparator<Double> comp = (Double a, Double b) -> {
return b.compareTo(a);
};
Collections.sort(testList, comp);
L'utilisation d'un lambda est possible car l'interface de Comparateur n'a qu'une seule méthode à implémenter. Par conséquent, VM peut en déduire quelle méthode est implémentée. Puisque les types de paramètres peuvent être déduits, ils n'ont pas besoin d'être déclarés (c'est-à-dire (a, b)
au lieu de (Double a, Double b)
. Et comme le corps lambda n'a qu'une seule ligne et que la méthode doit renvoyer une valeur, la return
est déduite et les accolades ne sont pas nécessaires.
Avec Java8, il existe une méthode de tri par défaut sur l'interface List qui vous permettra de trier la collection si vous fournissez un comparateur. Vous pouvez facilement trier l'exemple dans la question comme suit:
testList.sort((a, b) -> Double.compare(b, a));
Remarque: les arguments dans le lambda sont échangés lorsqu'ils sont passés à Double.compare pour assurer que le tri est décroissant.
Vous pouvez utiliser Collections.sort(list)
pour trier list
si votre list
contient des éléments Comparable
. Sinon, je vous recommanderais de mettre en place cette interface comme ici:
public class Circle implements Comparable<Circle> {}
et bien sûr, fournissez votre propre réalisation de la méthode compareTo
comme ici:
@Override
public int compareTo(Circle another) {
if (this.getD()<another.getD()){
return -1;
}else{
return 1;
}
}
Et vous pouvez à nouveau utiliser Colection.sort(list)
car la liste contient maintenant des objets de type Comparable et peut être triée. L'ordre dépend de la méthode compareTo
. Cochez cette https://docs.Oracle.com/javase/tutorial/collections/interfaces/order.html pour des informations plus détaillées.
Collections.sort
vous permet de transmettre une instance de Comparator
qui définit la logique de tri. Ainsi, au lieu de trier la liste dans l'ordre naturel puis de l'inverser, on peut simplement passer de Collections.reverseOrder()
à sort
afin de trier la liste dans l'ordre inverse:
// import Java.util.Collections;
Collections.sort(testList, Collections.reverseOrder());
Comme mentionné par @ Marco1313, en plus d’être plus idiomatique (et peut-être plus efficace), l’utilisation du comparateur d’ordre inverse garantit la stabilité du tri (ce qui signifie que l’ordre des éléments ne sera pas modifié quand ils sont égaux, alors que l'inversion changera l'ordre)
//Here is sorted List alphabetically with syncronized
package com.mnas.technology.automation.utility;
import Java.util.ArrayList;
import Java.util.Collections;
import Java.util.Comparator;
import Java.util.Iterator;
import Java.util.List;
import org.Apache.log4j.Logger;
/**
* @author manoj.kumar
*/
public class SynchronizedArrayList {
static Logger log = Logger.getLogger(SynchronizedArrayList.class.getName());
@SuppressWarnings("unchecked")
public static void main(String[] args) {
List<Employee> synchronizedList = Collections.synchronizedList(new ArrayList<Employee>());
synchronizedList.add(new Employee("Aditya"));
synchronizedList.add(new Employee("Siddharth"));
synchronizedList.add(new Employee("Manoj"));
Collections.sort(synchronizedList, new Comparator() {
public int compare(Object synchronizedListOne, Object synchronizedListTwo) {
//use instanceof to verify the references are indeed of the type in question
return ((Employee) synchronizedListOne).name
.compareTo(((Employee) synchronizedListTwo).name);
}
});
/*for( Employee sd : synchronizedList) {
log.info("Sorted Synchronized Array List..."+sd.name);
}*/
// when iterating over a synchronized list, we need to synchronize access to the synchronized list
synchronized (synchronizedList) {
Iterator<Employee> iterator = synchronizedList.iterator();
while (iterator.hasNext()) {
log.info("Sorted Synchronized Array List Items: " + iterator.next().name);
}
}
}
}
class Employee {
String name;
Employee(String name) {
this.name = name;
}
}
si vous utilisez Java SE 8, cela peut être utile.
//create a comparator object using a Lambda expression
Comparator<Double> compareDouble = (d1, d2) -> d1.compareTo(d2);
//Sort the Collection in this case 'testList' in reverse order
Collections.sort(testList, Collections.reverseOrder(compareDouble));
//print the sorted list using method reference only applicable in SE 8
testList.forEach(System.out::println);
| * | Tri d'une liste:
import Java.util.Collections;
| => Ordre Asc:
Collections.sort(NamAryVar);
| => Trier l'ordre Dsc:
Collections.sort(NamAryVar, Collections.reverseOrder());
| * | Inverser l'ordre de la liste:
Collections.reverse(NamAryVar);
vous pouvez faire comme ça:
List<String> yourList = new ArrayList<String>();
Collections.sort(yourList, Collections.reverseOrder());
Collection a un comparateur par défaut qui peut vous aider.
En outre, si vous souhaitez utiliser certaines nouvelles fonctionnalités de Java 8, vous pouvez procéder comme suit:
List<String> yourList = new ArrayList<String>();
yourList = yourList.stream().sorted(Collections.reverseOrder()).collect(Collectors.toList());
Vous pouvez utiliser comme ça
ArrayList<Group> groupList = new ArrayList<>();
Collections.sort(groupList, Collections.reverseOrder());
Collections.reverse(groupList);
Par exemple, j'ai une classe Person: String name, int age ==> Nouvelle personne du constructeur (nom, age)
import Java.util.Collections;
import Java.util.ArrayList;
import Java.util.Arrays;
public void main(String[] args){
Person ibrahima=new Person("Timera",40);
Person toto=new Person("Toto",35);
Person alex=new Person("Alex",50);
ArrayList<Person> myList=new ArrayList<Person>
Collections.sort(myList, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
// return p1.age+"".compareTo(p2.age+""); //sort by age
return p1.name.compareTo(p2.name); // if you want to short by name
}
});
System.out.println(myList.toString());
//[Person [name=Alex, age=50], Person [name=Timera, age=40], Person [name=Toto, age=35]]
Collections.reverse(myList);
System.out.println(myList.toString());
//[Person [name=Toto, age=35], Person [name=Timera, age=40], Person [name=Alex, age=50]]
}
La ligne suivante devrait faire l'épaisseur
testList.sort(Collections.reverseOrder());
En Java 8, c'est beaucoup plus facile maintenant.
List<String> alphaNumbers = Arrays.asList("one", "two", "three", "four");
List<String> alphaNumbersUpperCase = alphaNumbers.stream()
.map(String::toUpperCase)
.sorted()
.collect(Collectors.toList());
System.out.println(alphaNumbersUpperCase); // [FOUR, ONE, THREE, TWO]
- Pour inverser, utilisez cette
.sorted(Comparator.reverseOrder())
Avec Collections Eclipse , vous pouvez créer une double liste primitive, la trier puis l’inverser pour la mettre en ordre décroissant. Cette approche éviterait de boxer les doubles.
MutableDoubleList doubleList =
DoubleLists.mutable.with(
0.5, 0.2, 0.9, 0.1, 0.1, 0.1, 0.54, 0.71,
0.71, 0.71, 0.92, 0.12, 0.65, 0.34, 0.62)
.sortThis().reverseThis();
doubleList.each(System.out::println);
Si vous voulez un List<Double>
, alors ce qui suit fonctionnera.
List<Double> objectList =
Lists.mutable.with(
0.5, 0.2, 0.9, 0.1, 0.1, 0.1, 0.54, 0.71,
0.71, 0.71, 0.92, 0.12, 0.65, 0.34, 0.62)
.sortThis(Collections.reverseOrder());
objectList.forEach(System.out::println);
Si vous souhaitez conserver le type ArrayList<Double>
, vous pouvez initialiser et trier la liste à l'aide de la classe d'utilitaire ArrayListIterate
comme suit:
ArrayList<Double> arrayList =
ArrayListIterate.sortThis(
new ArrayList<>(objectList), Collections.reverseOrder());
arrayList.forEach(System.out::println);
Remarque: je suis un partisan de Eclipse Collections .
Voici un bref aide-mémoire qui couvre des cas typiques:
// sort
list.sort(naturalOrder())
// sort (reversed)
list.sort(reverseOrder())
// sort by field
list.sort(comparing(Type::getField))
// sort by field (reversed)
list.sort(comparing(Type::getField).reversed())
// sort by int field
list.sort(comparingInt(Type::getIntField))
// sort by double field (reversed)
list.sort(comparingDouble(Type::getDoubleField).reversed())
// sort by nullable field (nulls last)
list.sort(comparing(Type::getNullableField, nullsLast(naturalOrder())))
// two-level sort
list.sort(comparing(Type::getField1).thenComparing(Type::getField2))