web-dev-qa-db-fra.com

Java Récupère une chaîne CompareTo en tant qu'objet comparateur

Je voudrais trier et rechercher binaire un tableau statique de chaînes via le comparateur String.CompareTo.

Le problème est que le tri et la recherche binaire nécessitent la transmission d'un objet Comparator. Comment puis-je passer dans le comparateur de chaînes intégré?

30

La classe Arrays a des versions de sort() et binarySearch() qui ne nécessitent pas de Comparator.. Par exemple, vous pouvez utiliser la version de Arrays.sort() qui prend juste un tableau d'objets . Ces méthodes appellent la méthode compareTo() des objets du tableau.

19
Code-Apprentice

Vous pouvez écrire votre propre comparateur

public class ExampleComparator  implements Comparator<String> {
  public int compare(String obj1, String obj2) {
    if (obj1 == obj2) {
        return 0;
    }
    if (obj1 == null) {
        return -1;
    }
    if (obj2 == null) {
        return 1;
    }
    return obj1.compareTo(obj2);
  }
}
37
kosa

Solution pour Java 8 basé sur Java.util.Comparator.comparing (...)) :

Comparator<String> c = Comparator.comparing(String::toString);

ou

Comparator<String> c = Comparator.comparing((String x) -> x);
28
Antonio

Si vous trouvez que vous avez besoin d'un Comparator et que vous utilisez déjà Guava , vous pouvez utiliser Ordering.natural() .

11

Ceci est un Comparator générique pour tout type d'objet Comparable, pas seulement String:

package util;

import Java.util.Comparator;

/**
 * The Default Comparator for classes implementing Comparable.
 *
 * @param <E> the type of the comparable objects.
 *
 * @author Michael Belivanakis (michael.gr)
 */
public final class DefaultComparator<E extends Comparable<E>> implements Comparator<E>
{
    @SuppressWarnings( "rawtypes" )
    private static final DefaultComparator<?> INSTANCE = new DefaultComparator();

    /**
     * Get an instance of DefaultComparator for any type of Comparable.
     *
     * @param <T> the type of Comparable of interest.
     *
     * @return an instance of DefaultComparator for comparing instances of the requested type.
     */
    public static <T extends Comparable<T>> Comparator<T> getInstance()
    {
        @SuppressWarnings("unchecked")
        Comparator<T> result = (Comparator<T>)INSTANCE;
        return result;
    }

    private DefaultComparator()
    {
    }

    @Override
    public int compare( E o1, E o2 )
    {
        if( o1 == o2 )
            return 0;
        if( o1 == null )
            return 1;
        if( o2 == null )
            return -1;
        return o1.compareTo( o2 );
    }
}

Comment utiliser avec String:

Comparator<String> stringComparator = DefaultComparator.getInstance();
10
Mike Nakis

Encore une fois, vous n'avez pas besoin du comparateur pour Arrays.binarySearch(Object[] a, Object key) tant que les types d'objets sont comparables, mais avec les expressions lambda, c'est maintenant beaucoup plus facile.

Il suffit de remplacer le comparateur par la référence de la méthode: String::compareTo

Par exemple.:

Arrays.binarySearch(someStringArray, "The String to find.", String::compareTo);

Vous pouvez aussi utiliser

Arrays.binarySearch(someStringArray, "The String to find.", (a,b) -> a.compareTo(b));

mais même avant les lambdas, il y avait toujours des classes anonymes:

Arrays.binarySearch(
                someStringArray,
                "The String to find.",
                new Comparator<String>() {
                    @Override
                    public int compare(String o1, String o2) {
                        return o1.compareTo(o2);
                    }
                });
9
Joseph Nields

Ok, quelques années plus tard, mais avec Java 8, vous pouvez utiliser Comparator.naturalOrder ():

http://docs.Oracle.com/javase/8/docs/api/Java/util/Comparator.html#naturalOrder--

De javadoc:

static <T extends Comparable<? super T>> Comparator<T> naturalOrder()

Renvoie un comparateur comparant les objets comparables dans un ordre naturel. Le comparateur renvoyé est sérialisable et lève NullPointerException lors de la comparaison de null.

6
brunesto

De plus, si vous souhaitez une comparaison ne respectant pas la casse, dans les versions récentes de Java, la classe String contient un public static final champ appelé CASE_INSENSITIVE_ORDER qui est de type Comparator<String>, comme je viens de le découvrir récemment. Donc, vous pouvez faire votre travail en utilisant String.CASE_INSENSITIVE_ORDER.

6
Mike Nakis

Nous pouvons utiliser le comparateur String.CASE_INSENSITIVE_ORDER pour comparer les chaînes dans un ordre ne respectant pas la casse.

Arrays.binarySearch(someStringArray, "The String to find.",String.CASE_INSENSITIVE_ORDER);
2
Sudhakar

Généraliser la bonne réponse de Mike Nakis avec String.CASE_INSENSITIVE_ORDER, vous pouvez aussi utiliser :

Collator.getInstance();

Voir Collator

0
Sharcoux