J'ai essayé d'implémenter Sterling Sort avec Java Collector

Aperçu

J'ai essayé d'implémenter le tri Staline, qui est un algorithme de tri historique du montant de calcul O (n), avec Haskell #Haskell

Il semble que Stalin Sort soit populaire, je vais donc l'écrire en Java. L'API de flux introduite à partir de Java 8 est déjà familière, n'est-ce pas? Cette fois, nous allons créer une classe d'implémentation de l'interface Collector que la méthode Collect reçoit afin que le flux puisse effectuer un tri en sterling cool.

code

/**
 *Classe d'implémentation de collecteur qui implémente le tri Staline
 */
public final class StalinSortCollector {
    private StalinSortCollector() {}
    /**
     *Renvoie un Collector qui Starlin trie les éléments d'entrée dans l'ordre naturel et convertit le résultat en Stream.
     * @param <T>Type d'élément d'entrée
     */
    public static <T extends Comparable<? super T>> Collector<T, List<T>, Stream<T>> sorting(){
        return new StalinSortCollectorImplements<T, T>(Comparator.naturalOrder(), x -> x);
    }

    /**
     *Renvoie un Collector qui Starlin trie les éléments d'entrée dans l'ordre naturel inverse et convertit le résultat en Stream.
     * @param <T>Type d'élément d'entrée
     */
    public static <T extends Comparable<? super T>> Collector<T, List<T>, Stream<T>> reverseSorting(){
        return new StalinSortCollectorImplements<T, T>(Comparator.reverseOrder(), x -> x);
    }

    /**
     *Renvoie un Collector qui Staline trie les éléments d'entrée dans l'ordre naturel des valeurs converties par la fonction mappeur et convertit le résultat en Stream.
     * @param mapper Fonction pour convertir les éléments d'entrée
     * @param <T>Type d'élément d'entrée
     * @param <A>Tapez pour comparer les éléments d'entrée
     */
    public static <T, A extends Comparable<? super A>> Collector<T, List<T>, Stream<T>> sortingBy(Function<? super T, ? extends A> mapper){
        return new StalinSortCollectorImplements<T, A>(Comparator.naturalOrder(), mapper);
    }

    /**
     *Renvoie un collecteur qui Staline trie les éléments d'entrée dans l'ordre inverse de l'ordre naturel des valeurs converties par la fonction de mappage et convertit le résultat en Stream.
     * @param mapper Fonction pour convertir les éléments d'entrée
     * @param <T>Type d'élément d'entrée
     * @param <A>Tapez pour comparer les éléments d'entrée
     */
    public static <T, A extends Comparable<? super A>> Collector<T, List<T>, Stream<T>> reverseSortingBy(Function<? super T, ? extends A> mapper){
        return new StalinSortCollectorImplements<T, A>(Comparator.reverseOrder(), mapper);
    }

    /**
     *Renvoie un Collector qui Starlin trie les éléments d'entrée dans l'ordre dans lequel ils sont comparés par le comparateur et convertit le résultat en Stream.
     * @Comparateur pour comparer les éléments du comparateur de paramètres
     * @param <T>Type d'élément d'entrée
     */
    public static <T> Collector<T, List<T>, Stream<T>> sorting(Comparator<? super T> comparator){
        return new StalinSortCollectorImplements<T, T>(comparator, x -> x);
    }

    /**
     *Renvoie un Collector qui Staline trie les éléments d'entrée convertis par la fonction de mappage dans l'ordre dans lequel ils sont comparés par le comparateur et convertit le résultat en Stream.
     * @param mapper Fonction pour convertir les éléments d'entrée
     * @Comparateur pour comparer les éléments du comparateur de paramètres
     * @param <T>Type d'élément d'entrée
     * @param <A>Tapez pour comparer les éléments d'entrée
     */
    public static <T, A> Collector<T, List<T>, Stream<T>> sortingBy(Function<? super T, ? extends A> mapper, Comparator<? super A> comparator){
        return new StalinSortCollectorImplements<T, A>(comparator, mapper);
    }

    private static class StalinSortCollectorImplements<T, A> implements Collector<T, List<T>, Stream<T>> {
        private final Comparator<? super A> comparator;
        private final Function<? super T, ? extends A> mapper;
        private StalinSortCollectorImplements(Comparator<? super A> comparator, Function<? super T, ? extends A> mapper) {
            this.comparator = comparator;
            this.mapper = mapper;
        }

        @Override
        public Supplier<List<T>> supplier() {
            return ArrayList::new;
        }

        @Override
        public BiConsumer<List<T>, T> accumulator() {
            return (list, element) -> {
                if(list.isEmpty() || this.comparator.compare(this.mapper.apply(element), this.mapper.apply(list.get(list.size() -1))) >= 0) {
                    list.add(element);
                }
            };
        }

        @Override
        public BinaryOperator<List<T>> combiner() {
            return (x, y) -> Stream.concat(x.stream(), y.stream().dropWhile(p -> this.comparator.compare(this.mapper.apply(p), this.mapper.apply(x.get(x.size() -1))) < 0)).collect(Collectors.toList());
        }

        @Override
        public Function<List<T>, Stream<T>> finisher() {
            return List::stream;
        }

        @Override
        public Set<Characteristics> characteristics() {
            return EnumSet.of(Characteristics.CONCURRENT);
        }
    }
}

Collectors En référence à la classe, StalinSortCollector n'a que des méthodes statiques qui renvoient des Collectors. Je te laisse. La classe StalinSortCollectorImplements implémente en fait Stalin Sort.

Qu'est-ce que l'interface Collector?

Collector L'interface indique la méthode de collecte en la passant à la méthode de collecte de Stream. .. Il a 3 paramètres de type, 5 méthodes et 2 méthodes staiques (non pertinent car non implémenté).

Paramètre de type \ <T, A, R>

Par exemple, s'il s'agit d'un collecteur qui ajoute une collection d'entiers à StringBuilder et le renvoie finalement sous forme de chaîne, ce sera \ <Integer, StringBuilder, String>. Cette fois, StalinSortCollectorImplements ajoute un élément de type T à List \ et le renvoie finalement en tant que Stream, implémentez donc Collector \ <T, List \ , Stream \ >. Je suis. Le paramètre de type de StalinSortCollectorImplements lui-même est \ <T, A> car il reçoit un mappeur pour comparaison.

Supplier<A> supplier()

Voici une description des méthodes à mettre en œuvre. Le fournisseur renvoie un fournisseur qui crée une instance qui accumule les résultats en cours de route. En parlant de l'instruction for, c'est ce que vous voulez faire avec for ([here] ;;) (formule d'initialisation de for). De plus, puisque le résultat intermédiaire réutilise l'instance générée par this, il n'est pas possible de renvoyer une chaîne de caractères vide et de faire quelque chose comme la concaténation de chaînes. (Parce que la combinaison de chaînes renvoie une nouvelle instance) Ici, il renvoie ArrayList :: new.

BiConsumer<A, T> accumulator()

L'accumulateur prend un élément d'entrée de type T et renvoie un BiConsumer qui accumule les résultats intermédiaires dans une instance de type A. En parlant de déclarations for, c'est ce que vous voulez faire avec for (;;) [here] (le corps de for). Ici, il est ajouté à la liste lorsque la liste qui stocke les résultats intermédiaires est vide ou lorsque "élément d'entrée> = dernier élément de la liste". (Inversement, lorsque "élément d'entrée <dernier élément de la liste", ** silence ** est terminé.)

BinaryOperator<A> combiner()

combiner renvoie un BinaryOperator qui combine des instances de type A qui ont accumulé des résultats intermédiaires. Puisque Stream peut être exécuté en parallèle, il est nécessaire de concaténer les résultats produits lorsqu'ils sont exécutés en parallèle avec cette fonction de combinateur. Ici, les éléments de la liste du côté concaténé sont ignorés (** nettoyés) jusqu'à ce qu'ils soient égaux ou supérieurs au dernier élément du côté concaténé. Notez que dropWhile ne peut être utilisé qu'avec Java 9 ou version ultérieure.

Function<A, R> finisher()

finisher renvoie la fonction du processus de finition pour l'instance de type A qui a accumulé tous les résultats. Ici, la liste triée par Starlin est renvoyée sous forme de flux. Cela permet à collect de continuer la chaîne de méthodes même s'il s'agit d'une opération de terminaison.

Set characteristics()

caractéristiques renvoie un ensemble de caractéristiques de collecteur qui indique les attributs de ce collecteur. Il existe trois types: CONCURRENT (peut être exécuté en parallèle), UNORDERED (pas d'ordre) et IDENTITY_FINISH (le module de finition peut être omis). Ici, seul CONCURRENT est renvoyé car le finisseur est en cours de traitement et la commande est un tri important.

Exemple d'utilisation

public class Soviet {
    public static void main(String... args) {
        Stream.of(1,2,2,4,3,5,3,5,7,1,1,9)
            .collect(StalinSortCollector.sorting())
            .forEach(System.out::println);
    }
}
1
2
2
4
5
5
7
9
public class Russia {
    public static void main(String... args) {
        Stream.of(12,2,23,499,325,51,334,55555,7898,1019,19,12345)
            .parallel()
            .collect(StalinSortCollector.sortingBy(x -> String.valueOf(x).length()))
            .forEach(System.out::println);
    }
}
12
23
499
325
334
55555
12345

Après tout, ça fait du bien de pouvoir traiter avec stream.

Recommended Posts

J'ai essayé d'implémenter Sterling Sort avec Java Collector
J'ai essayé d'implémenter TCP / IP + BIO avec JAVA
J'ai essayé d'interagir avec Java
J'ai essayé de faire une authentification de base avec Java
J'ai essayé de casser le bloc avec java (1)
J'ai essayé d'implémenter le téléchargement de fichiers avec Spring MVC
J'ai essayé d'implémenter la notification push Firebase en Java
[Java 11] J'ai essayé d'exécuter Java sans compiler avec javac
[Java] J'ai essayé de mettre en œuvre la recherche de produits de l'API Yahoo
J'ai essayé d'implémenter la méthode de division mutuelle d'Eugrid en Java
J'ai essayé la communication UDP avec Java
J'ai essayé de résumer l'apprentissage Java (1)
J'ai essayé de résumer Java 8 maintenant
J'ai essayé de créer un environnement de développement java8 avec Chocolatey
J'ai essayé de moderniser une application Java EE avec OpenShift.
[Rails] J'ai essayé d'implémenter le traitement par lots avec la tâche Rake
Je veux implémenter diverses fonctions avec kotlin et java!
J'ai essayé de résumer les expressions Java lambda
J'ai essayé de démarrer avec Web Assembly
J'ai essayé d'implémenter la fonction de prévisualisation d'image avec Rails / jQuery
J'ai essayé d'implémenter un mappage OU flexible avec MyBatis Dynamic SQL
J'ai essayé d'implémenter le modèle Iterator
J'ai essayé d'utiliser OpenCV avec Java + Tomcat
J'ai essayé de créer une application Android avec MVC maintenant (Java)
J'ai essayé de vérifier AdoptOpenJDK 11 (11.0.2) avec l'image Docker
J'ai essayé d'implémenter des relations polymorphes à Nogizaka.
J'ai essayé de gérer la configuration des jambes de force avec Coggle
java j'ai essayé de casser un simple bloc
Je veux utiliser java8 forEach avec index
J'ai essayé de sortir quatre-vingt-dix-neuf en Java
Essayez d'implémenter TCP / IP + NIO avec JAVA
J'ai essayé de créer une compétence Alexa avec Java
J'ai essayé d'implémenter un serveur en utilisant Netty
J'ai essayé d'implémenter une fonction équivalente à Felica Lite avec HCE-F d'Android
[Java] J'ai essayé de me connecter en utilisant le pool de connexion avec Servlet (tomcat) & MySQL & Java
J'ai essayé ce que je voulais essayer avec Stream doucement.
J'ai essayé de lire et de sortir CSV avec Outsystems
[Java] J'ai essayé de résoudre le problème de rang B de Paiza
J'ai essayé de faire fonctionner SQS en utilisant AWS Java SDK
# 2 [Note] J'ai essayé de calculer quatre-vingt-dix-neuf avec Java.
J'ai démarré MySQL 5.7 avec docker-compose et j'ai essayé de me connecter
J'ai essayé de créer une fonction de connexion avec Java
J'ai essayé de dessiner une animation avec l'API Blazor + canvas
J'ai essayé OCR de traiter un fichier PDF avec Java
Je veux faire des transitions d'écran avec kotlin et java!
~ J'ai essayé d'apprendre la programmation fonctionnelle avec Java maintenant ~
J'avais l'habitude de faire nc (netcat) avec JAVA normalement
J'ai essayé de découvrir ce qui avait changé dans Java 9
J'ai essayé de créer une fonction / écran d'administrateur de site commercial avec Java et Spring
[Swift] J'ai essayé d'implémenter une interface utilisateur semblable à un profil Instagram avec UICollectionView avec juste du code sans storyboard
[Azure] J'ai essayé de créer une application Java gratuitement ~ Se connecter avec FTP ~ [Débutant]
Java pour jouer avec Function
Trier les chaînes comme une fonction caractéristique avec Java
J'ai essayé Drools (Java, InputStream)
Connectez-vous à DB avec Java
J'ai essayé d'utiliser Java REPL