Collection triée en Java

je suis débutant en Java. Veuillez indiquer quel(s) peut/doit être utilisée pour maintenir une liste triée en Java. J'ai essayé Map et Set , mais ce n'était pas ce que je cherchais.

154
demandé sur b4hand 2009-01-06 15:02:05

18 réponses

cela arrive très tard, mais il y a une classe dans le JDK juste dans le but d'avoir une liste triée. Il est nommé (un peu hors de l'ordre avec les autres Sorted* interfaces) " java.util.PriorityQueue ". Il peut trier soit Comparable<?> s ou en utilisant un Comparator .

la différence avec un List trié en utilisant Collections.sort(...) est que cela maintiendra un ordre partiel à tout moment, avec des performances D'insertion O(log(n)), en utilisant une structure de données tas, tandis que l'insertion dans un ArrayList trié sera O (n) (i.e., en utilisant la recherche binaire et le déplacement).

cependant, contrairement à un List , PriorityQueue ne supporte pas l'accès indexé ( get(5) ), la seule façon d'accéder aux articles dans un tas est de les sortir, un par un (d'où le nom PriorityQueue ).

179
répondu Martin Probst 2015-01-09 15:40:06

TreeMap et TreeSet vous donneront une itération sur le contenu dans l'ordre trié. Ou vous pourriez utiliser un ArrayList et utiliser des Collections.sort() pour le tri. Tous ces cours sont en java.jusqu'à 151910920"

52
répondu Michael Borgwardt 2009-01-06 12:06:05

si vous voulez maintenir une liste triée que vous allez modifier fréquemment (c.-à-d. une structure qui, en plus d'être triée, permet des doublons et dont les éléments peuvent être référencés efficacement par index), puis utiliser un ArrayList mais quand vous avez besoin d'insérer un élément, toujours utiliser Collections.binarySearch () pour déterminer l'indice auquel vous ajoutez un élément donné. Cette dernière méthode vous indique l'index dont vous avez besoin pour insérer à garder votre liste dans l'ordre de tri.

32
répondu Neil Coffey 2009-01-06 13:25:27

utilisez la classe de Google Guava TreeMultiset . Goyave a une spectaculaire API de collections.

un problème avec la mise en œuvre de List qui maintient l'ordre trié est la promesse faite dans les JavaDocs de la méthode add() .

29
répondu jtb 2018-09-27 21:00:25

il y a quelques options. Je suggère TreeSet si vous ne voulez pas de doublons et les objets que vous insérez sont comparables.

Vous pouvez également utiliser les méthodes statiques de la classe regroupements pour ce faire.

voir Collections#sort(java.util.Liste) et TreeSet pour plus d'info.

12
répondu BenM 2012-06-24 01:16:49

vous voulez le SortedSet implémentations, à savoir TreeSet .

11
répondu cletus 2009-01-06 12:06:42

si vous voulez simplement trier une liste, utilisez n'importe quelle sorte de liste et utilisez Collections.sort () . Si vous voulez vous assurer que les éléments de la liste sont uniques et toujours triés, utilisez un SortedSet .

9
répondu Guillaume 2009-01-06 12:09:35

ce que j'ai fait c'est mettre en œuvre une liste ayant une instance interne avec toutes les méthodes déléguées.

 public class ContactList implements List<Contact>, Serializable {
    private static final long serialVersionUID = -1862666454644475565L;
    private final List<Contact> list;

public ContactList() {
    super();
    this.list = new ArrayList<Contact>();
}

public ContactList(List<Contact> list) {
    super();
    //copy and order list
    List<Contact>aux= new ArrayList(list);
    Collections.sort(aux);

    this.list = aux;
}

public void clear() {
    list.clear();
}

public boolean contains(Object object) {
    return list.contains(object);
}

après, j'ai mis en place une nouvelle méthode" putOrdered " qui insère dans la bonne position si l'élément n'existe pas ou remplacer juste au cas où il existe.

public void putOrdered(Contact contact) {
    int index=Collections.binarySearch(this.list,contact);
    if(index<0){
        index= -(index+1);
        list.add(index, contact);
    }else{
        list.set(index, contact);
    }
}

si vous voulez permettre des éléments répétés, il suffit d'implémenter addOrdered à la place (ou les deux).

public void addOrdered(Contact contact) {
    int index=Collections.binarySearch(this.list,contact);
    if(index<0){
        index= -(index+1);
    }
    list.add(index, contact);
}

Si vous voulez éviter les inserts vous pouvez également lancer et l'exception d'opération non supportée sur les méthodes "add" et "set".

public boolean add(Contact object) {
    throw new UnsupportedOperationException("Use putOrdered instead");
}

... et aussi vous devez être prudent avec les méthodes de ListIterator parce qu'ils pourraient modifier votre liste interne. Dans ce cas, vous pouvez renvoyer une copie de la liste interne ou encore lancer une exception.

public ListIterator<Contact> listIterator() {
    return (new ArrayList<Contact>(list)).listIterator();
}
5
répondu Carlos Verdes 2012-11-29 20:20:25

TreeSet ne fonctionnerait pas parce qu'ils ne permettent pas les doublons plus ils ne fournissent pas la méthode pour récupérer l'élément à la position spécifique. PriorityQueue ne fonctionnerait pas parce qu'il ne permet pas de récupérer des éléments à un poste spécifique qui est une exigence de base pour une liste. Je pense que vous avez besoin d'implémenter votre propre algorithme pour maintenir une liste triée en Java avec O(logn) insert time, à moins que vous n'ayez pas besoin de doublons. Peut-être qu'une solution pourrait être d'utiliser une bande de TreeMap où la clé est une sous-classe de l'élément qui supplante la méthode equals de sorte que les doublons soient autorisés.

4
répondu Giuseppe 2012-04-23 14:17:16

Utilisant LambdaJ

vous pouvez essayer de résoudre ces tâches avec LambdaJ si vous utilisez des versions antérieures à java 8. Vous pouvez le trouver ici: http://code.google.com/p/lambdaj /

voici un exemple:

Tri Itératif

List<Person> sortedByAgePersons = new ArrayList<Person>(persons);
Collections.sort(sortedByAgePersons, new Comparator<Person>() {
        public int compare(Person p1, Person p2) {
           return Integer.valueOf(p1.getAge()).compareTo(p2.getAge());
        }
}); 

Trier avec LambdaJ

List<Person> sortedByAgePersons = sort(persons, on(Person.class).getAge()); 

bien sûr, avoir ce genre d'impact de beauté dans la performance (une moyenne de 2 fois), mais pouvez-vous trouver un code plus lisible?

Trier avec java 8 en utilisant l'expression lambda

Collections.sort(persons, (p1, p2) -> p1.getAge().compareTo(p2.getAge()));
//or
persons.sort((p1, p2) -> p1.getAge().compareTo(p2.getAge()));
4
répondu Federico Piazza 2015-06-20 14:28:22

la manière la plus efficace de mettre en œuvre une liste triée comme vous le souhaitez serait d'implémenter une liste déroulante indexable comme ici: Wikipedia: liste déroulante Indexable . Cela permettrait d'avoir des insertions/suppressions en O(log(n)) et permettrait d'avoir un accès indexé dans le même temps. Et cela permettrait aussi les doublons.

Skiplist est une structure de données assez intéressante et, je dirais, sous-estimée. Malheureusement il n'y a pas de liste indexée implémentation dans la bibliothèque Java base, mais vous pouvez utiliser l'une des implémentations open source ou l'implémenter vous-même. Il y a des implémentations régulières de Skiplist comme et

4
répondu vladich 2018-09-27 02:01:41

le problème avec PriorityQueue est qu'il est soutenu par un tableau simple, et la logique qui obtient les éléments dans l'ordre est faite par la" queue[2*n+1] and queue[2*(n+1)] " thingie. Cela fonctionne bien si vous tirez juste de la tête, mais rend inutile si vous essayez d'appeler le .toArray à un moment donné.

je contourne ce problème en utilisant com.Google.commun.recueillir.TreeMultimap, mais je fournis un comparateur personnalisé pour les valeurs, enveloppé dans une commande, que ne renvoie jamais 0.

ex. pour Double:

private static final Ordering<Double> NoEqualOrder = Ordering.from(new Comparator<Double>() {

    @Override
    public int compare(Double d1, Double d2)
    {
        if (d1 < d2) {
            return -1;
        }
        else {
            return 1;
        }
    }
});

de cette façon, j'obtiens les valeurs en ordre quand j'appelle .toArray(), et aussi avoir des doublons.

2
répondu Martin Klosi 2014-11-01 00:21:23

ce que vous voulez est un arbre de recherche binaire. Il maintient l'ordre trié tout en offrant un accès logarithmique pour les recherches, les suppressions et les insertions (sauf si vous avez un arbre dégénéré - alors il est linéaire). Il est assez facile à mettre en œuvre et vous pouvez même le faire mettre en œuvre l'interface de liste, mais alors l'index-accès devient compliqué.

deuxième approche est d'avoir un ArrayList puis une mise en œuvre de tri de bulles. Parce que vous insérez ou retirez un élément à un temps, les temps d'accès pour les insertions et les retraits sont linéaires. Les recherches sont logarithmique et index constante d'accès (les temps peuvent varier pour LinkedList). Le seul code dont vous avez besoin est 5, peut-être 6 lignes de type bulle.

1
répondu Jakub Zaverka 2012-04-23 15:26:37

vous pouvez utiliser Arraylist et Treemap, comme vous avez dit que vous voulez des valeurs répétées aussi bien que vous ne pouvez pas utiliser TreeSet, bien qu'il soit trié aussi bien, mais vous devez définir comparator.

1
répondu 2015-10-28 09:56:11

utiliser la méthode sort () pour trier la liste comme suit:

List list = new ArrayList();

//add elements to the list

Comparator comparator = new SomeComparator();

Collections.sort(list, comparator);

Pour référence, voir le lien: http://tutorials.jenkov.com/java-collections/sorting.html

0
répondu Shashank Mungantiwar 2016-11-30 07:58:33

utiliser TreeSet qui donne les éléments dans l'ordre trié. Ou utilisez Collection.sort() pour le tri externe avec Comparator() .

0
répondu Hari 2017-01-20 08:10:18
import java.util.TreeSet;

public class Ass3 {
    TreeSet<String>str=new TreeSet<String>();
    str.add("dog");
    str.add("doonkey");
    str.add("rat");
    str.add("rabbit");
    str.add("elephant");
    System.out.println(str);    
}
0
répondu Deepica M Y 2017-08-18 09:42:59

avec Java 8 Comparator, si nous voulons trier la liste alors voici les 10 villes les plus peuplées dans le monde et nous voulons Trier par nom, comme rapporté par le temps. Osaka, Japon. ... Mexico, Mexico. ... Beijing, Chine. ... São Paulo, Brésil. ... Mumbai, En Inde. ... Shanghai, China. ... Delhi, En Inde. ... Tokyo, Japon.

 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.List;

public class SortCityList {

    /*
     * Here are the 10 most populated cities in the world and we want to sort it by
     * name, as reported by Time. Osaka, Japan. ... Mexico City, Mexico. ...
     * Beijing, China. ... São Paulo, Brazil. ... Mumbai, India. ... Shanghai,
     * China. ... Delhi, India. ... Tokyo, Japan.
     */
    public static void main(String[] args) {
        List<String> cities = Arrays.asList("Osaka", "Mexico City", "São Paulo", "Mumbai", "Shanghai", "Delhi",
                "Tokyo");
        System.out.println("Before Sorting List is:-");
        System.out.println(cities);
        System.out.println("--------------------------------");

        System.out.println("After Use of List sort(String.CASE_INSENSITIVE_ORDER) & Sorting List is:-");
        cities.sort(String.CASE_INSENSITIVE_ORDER);
        System.out.println(cities);
        System.out.println("--------------------------------");
        System.out.println("After Use of List sort(Comparator.naturalOrder()) & Sorting List is:-");
        cities.sort(Comparator.naturalOrder());
        System.out.println(cities);

    }

}
0
répondu vipul gulhane 2018-08-14 05:06:00