web-dev-qa-db-fra.com

Comment trier une collection <T>?

J'ai un Collection générique et j'essaie de déterminer comment je peux trier les éléments qu'il contient. J'ai essayé plusieurs choses mais je ne parviens pas à les faire fonctionner.

49
Mercer

Les collections en elles-mêmes n’ont pas d’ordre prédéfini, vous devez donc les convertir en A Java.util.List Ensuite, vous pouvez utiliser une forme de Java.util.Collections.sort

Collection< T > collection = ...;

List< T > list = new ArrayList< T >( collection );

Collections.sort( list );
 // or
Collections.sort( list, new Comparator< T >( ){...} );

// list now is sorted
67

Un Collection n'a pas d'ordre, donc vouloir le trier n'a pas de sens. Vous pouvez trier des instances et des tableaux List. Les méthodes permettant de le faire sont Collections.sort() et Arrays.sort()

9
Michael Borgwardt

Vous avez deux options de base fournies par Java.util.Collections:

Selon la nature de la Collection, vous pouvez également consulter SortedSet ou SortedMap.

6
polygenelubricants

Si votre objet collections est une liste, j'utiliserais la méthode de tri proposée dans les autres réponses.

Cependant, s'il ne s'agit pas d'une liste et que le type d'objet Collection renvoyé ne vous intéresse pas, il est plus rapide de créer un TreeSet au lieu d'une liste:

TreeSet sortedSet = new TreeSet(myComparator);
sortedSet.addAll(myCollectionToBeSorted);
6
Fortega

Vous ne pouvez pas si T est tout ce que vous obtenez. Il doit être injecté par le prestataire:

Collection<T extends Comparable>

ou passer au comparateur

Collections.sort(...)
5
andyczerwonka

En supposant que vous ayez une liste d'objets de type Personne, à l'aide d'une expression Lambda, vous pouvez par exemple trier les noms de famille des utilisateurs en procédant comme suit: 

import Java.util.Arrays;
import Java.util.Collections;
import Java.util.Comparator;
import Java.util.List;

class Person {
        private String firstName;
        private String lastName;

        public Person(String firstName, String lastName){
            this.firstName = firstName;
            this.lastName = lastName;
        }

        public String getLastName(){
            return this.lastName;
        }

        public String getFirstName(){
            return this.firstName;
        }

        @Override
        public String toString(){
            return "Person: "+ this.getFirstName() + " " + this.getLastName();
        }
    }

    class TestSort {
        public static void main(String[] args){
            List<Person> people = Arrays.asList(
                                  new Person("John", "Max"), 
                                  new Person("Coolio", "Doe"), 
                                  new Person("Judith", "Dan")
            );

            //Making use of lambda expression to sort the collection
            people.sort((p1, p2)->p1.getLastName().compareTo(p2.getLastName()));

            //Print sorted 
            printPeople(people);
        }

        public static void printPeople(List<Person> people){
            for(Person p : people){
                System.out.println(p);
            }
        }
    }
1
lomse

Voici un exemple. (J'utilise la classe CompareToBuilder d'Apache pour plus de commodité, bien que cela puisse être fait sans l'utiliser.)

import Java.util.ArrayList;
import Java.util.Calendar;
import Java.util.Collections;
import Java.util.Comparator;
import Java.util.Date;
import Java.util.HashMap;
import Java.util.List;
import org.Apache.commons.lang.builder.CompareToBuilder;

public class Tester {
    boolean ascending = true;

    public static void main(String args[]) {
        Tester tester = new Tester();
        tester.printValues();
    }

    public void printValues() {
        List<HashMap<String, Object>> list =
            new ArrayList<HashMap<String, Object>>();
        HashMap<String, Object> map =
            new HashMap<String, Object>();

        map.put( "actionId", new Integer(1234) );
        map.put( "eventId",  new Integer(21)   );
        map.put( "fromDate", getDate(1)        );
        map.put( "toDate",   getDate(7)        );
        list.add(map);

        map = new HashMap<String, Object>();
        map.put( "actionId", new Integer(456) );
        map.put( "eventId",  new Integer(11)  );
        map.put( "fromDate", getDate(1)       );
        map.put( "toDate",   getDate(1)       );
        list.add(map);

        map = new HashMap<String, Object>();
        map.put( "actionId", new Integer(1234) );
        map.put( "eventId",  new Integer(20)   );
        map.put( "fromDate", getDate(4)        );
        map.put( "toDate",   getDate(16)       );
        list.add(map);

        map = new HashMap<String, Object>();
        map.put( "actionId", new Integer(1234) );
        map.put( "eventId",  new Integer(22)   );
        map.put( "fromDate", getDate(8)        );
        map.put( "toDate",   getDate(11)       );
        list.add(map);


        map = new HashMap<String, Object>();
        map.put( "actionId", new Integer(1234) );
        map.put( "eventId",  new Integer(11)   );
        map.put( "fromDate", getDate(1)        );
        map.put( "toDate",   getDate(10)       );
        list.add(map);

        map = new HashMap<String, Object>();
        map.put( "actionId", new Integer(1234) );
        map.put( "eventId",  new Integer(11)   );
        map.put( "fromDate", getDate(4)        );
        map.put( "toDate",   getDate(15)       );
        list.add(map);

        map = new HashMap<String, Object>();
        map.put( "actionId", new Integer(567) );
        map.put( "eventId",  new Integer(12)  );
        map.put( "fromDate", getDate(-1)      );
        map.put( "toDate",   getDate(1)       );
        list.add(map);

        System.out.println("\n Before Sorting \n ");
        for( int j = 0; j < list.size(); j++ )
            System.out.println(list.get(j));

        Collections.sort( list, new HashMapComparator2() );

        System.out.println("\n After Sorting \n ");
        for( int j = 0; j < list.size(); j++ )
            System.out.println(list.get(j));
    }

    public static Date getDate(int days) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.add(Calendar.DATE, days);
        return cal.getTime();
    }

    public class HashMapComparator2 implements Comparator {
        public int compare(Object object1, Object object2) {
            if( ascending ) {
                return new CompareToBuilder()
                    .append(
                        ((HashMap)object1).get("actionId"),
                        ((HashMap)object2).get("actionId")
                    )
                    .append(
                        ((HashMap)object2).get("eventId"),
                        ((HashMap)object1).get("eventId")
                    )
                .toComparison();
            } else {
                return new CompareToBuilder()
                    .append(
                        ((HashMap)object2).get("actionId"),
                        ((HashMap)object1).get("actionId")
                    )
                    .append(
                        ((HashMap)object2).get("eventId"),
                        ((HashMap)object1).get("eventId")
                    )
                .toComparison();
            }
        }
    }
}

Si vous travaillez sur un code spécifique et rencontrez des problèmes, vous pouvez publier votre pseudo-code et nous pouvons essayer de vous aider!

1
jagamot

Je suis tombé sur un problème similaire. A dû trier une liste de classe de tiers (objets).

List<ThirdPartyClass> tpc = getTpcList(...);

ThirdPartyClass n'implémente pas l'interface Java Comparable. J'ai trouvé une excellente illustration de mkyong sur la façon d'aborder ce problème. J'ai dû utiliser l'approche du tri du comparateur.

//Sort ThirdPartyClass based on the value of some attribute/function
Collections.sort(tpc, Compare3rdPartyObjects.tpcComp);

où le comparateur est:

public abstract class Compare3rdPartyObjects {

public static Comparator<ThirdPartyClass> tpcComp = new Comparator<ThirdPartyClass>() {

    public int compare(ThirdPartyClass tpc1, ThirdPartyClass tpc2) {

        Integer tpc1Offset = compareUsing(tpc1);
        Integer tpc2Offset = compareUsing(tpc2);

        //ascending order
        return tpc1Offset.compareTo(tpc2Offset);

    }
};

//Fetch the attribute value that you would like to use to compare the ThirdPartyClass instances 
public static Integer compareUsing(ThirdPartyClass tpc) {

    Integer value = tpc.getValueUsingSomeFunction();
    return value;
}
}
0
spaniard81