Ich habe versucht, Sterling Sort mit Java Collector zu implementieren

Überblick

Ich habe versucht, die Stalin-Sortierung, einen epochalen Sortieralgorithmus für den Berechnungsbetrag O (n), in Haskell #Haskell zu implementieren

Es scheint, dass Starlin Sort beliebt ist, also werde ich es in Java schreiben. Die von Java 8 eingeführte Stream-API ist bereits bekannt, nicht wahr? Dieses Mal erstellen wir eine Implementierungsklasse der Collector-Schnittstelle, die die Collect-Methode empfängt, damit der Stream eine coole Sterling-Sortierung durchführen kann.

Code

/**
 *Collector-Implementierungsklasse, die die Stalin-Sortierung implementiert
 */
public final class StalinSortCollector {
    private StalinSortCollector() {}
    /**
     *Gibt einen Collector zurück, bei dem Starlin die Eingabeelemente in natürlicher Reihenfolge sortiert und das Ergebnis in einen Stream konvertiert.
     * @param <T>Eingabeelementtyp
     */
    public static <T extends Comparable<? super T>> Collector<T, List<T>, Stream<T>> sorting(){
        return new StalinSortCollectorImplements<T, T>(Comparator.naturalOrder(), x -> x);
    }

    /**
     *Gibt einen Collector zurück, bei dem Starlin die Eingabeelemente in umgekehrter natürlicher Reihenfolge sortiert und das Ergebnis in einen Stream konvertiert.
     * @param <T>Eingabeelementtyp
     */
    public static <T extends Comparable<? super T>> Collector<T, List<T>, Stream<T>> reverseSorting(){
        return new StalinSortCollectorImplements<T, T>(Comparator.reverseOrder(), x -> x);
    }

    /**
     *Gibt einen Collector zurück, bei dem Stalin die Eingabeelemente in der natürlichen Reihenfolge der von der Mapper-Funktion konvertierten Werte sortiert und das Ergebnis in einen Stream konvertiert.
     * @param mapper Funktion zum Konvertieren von Eingabeelementen
     * @param <T>Eingabeelementtyp
     * @param <A>Geben Sie ein, um Eingabeelemente zu vergleichen
     */
    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);
    }

    /**
     *Gibt einen Collector zurück, bei dem Stalin die Eingabeelemente in umgekehrter Reihenfolge der natürlichen Reihenfolge der von der Mapper-Funktion konvertierten Werte sortiert und das Ergebnis in einen Stream konvertiert.
     * @param mapper Funktion zum Konvertieren von Eingabeelementen
     * @param <T>Eingabeelementtyp
     * @param <A>Geben Sie ein, um Eingabeelemente zu vergleichen
     */
    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);
    }

    /**
     *Gibt einen Collector zurück, bei dem Starlin die Eingabeelemente in der Reihenfolge sortiert, in der sie vom Vergleicher verglichen werden, und das Ergebnis in einen Stream konvertiert.
     * @Komparator zum Vergleichen von Param-Komparatorelementen
     * @param <T>Eingabeelementtyp
     */
    public static <T> Collector<T, List<T>, Stream<T>> sorting(Comparator<? super T> comparator){
        return new StalinSortCollectorImplements<T, T>(comparator, x -> x);
    }

    /**
     *Gibt einen Collector zurück, bei dem Stalin die von der Mapper-Funktion konvertierten Eingabeelemente in der Reihenfolge sortiert, in der sie vom Vergleicher verglichen werden, und das Ergebnis in Stream konvertiert.
     * @param mapper Funktion zum Konvertieren von Eingabeelementen
     * @Komparator zum Vergleichen von Param-Komparatorelementen
     * @param <T>Eingabeelementtyp
     * @param <A>Geben Sie ein, um Eingabeelemente zu vergleichen
     */
    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 In Bezug auf die Klasse verfügt StalinSortCollector nur über statische Methoden, die Collectors zurückgeben. Ich lasse dich. Die StalinSortCollectorImplements-Klasse implementiert tatsächlich Stalin Sort.

Was ist die Collector-Schnittstelle?

Collector Die Schnittstelle gibt die Erfassungsmethode an, indem sie an die Erfassungsmethode von Stream übergeben wird. .. Es hat 3 Typparameter, 5 Methoden und 2 statische Methoden (nicht relevant, da es nicht implementiert ist).

Geben Sie den Parameter \ <T, A, R> ein

Wenn es sich beispielsweise um einen Collector handelt, der eine Sammlung von Ints an StringBuilder anfügt und sie schließlich als String zurückgibt, lautet sie \ <Integer, StringBuilder, String>. Dieses Mal fügt StalinSortCollectorImplements ein Element vom Typ T zu List \ hinzu und gibt es schließlich als Stream zurück. Implementieren Sie also Collector \ <T, List \ , Stream \ >. Ich bin. Der Typparameter von StalinSortCollectorImplements selbst ist \ <T, A>, da er zum Vergleich einen Mapper empfängt.

Supplier<A> supplier()

Das Folgende ist eine Beschreibung der zu implementierenden Methoden. Der Lieferant gibt einen Lieferanten zurück, der eine Instanz erstellt, die die Ergebnisse auf dem Weg sammelt. Apropos for-Anweisung, es ist das, was Sie mit for ([here] ;;) (Initialisierungsformel von for) tun möchten. Da das Zwischenergebnis die dadurch generierte Instanz wiederverwendet, ist es außerdem nicht möglich, eine leere Zeichenfolge zurückzugeben und so etwas wie eine Verkettung von Zeichenfolgen durchzuführen. (Weil das Kombinieren von Zeichenfolgen eine neue Instanz zurückgibt) Hier wird ArrayList :: new zurückgegeben.

BiConsumer<A, T> accumulator()

Der Akkumulator verwendet ein Eingabeelement vom Typ T und gibt einen BiConsumer zurück, der Zwischenergebnisse in einer Instanz vom Typ A akkumuliert. Apropos Aussagen, es ist das, was Sie mit for (;;) [here] (dem Körper von for) machen wollen. Hier wird es der Liste hinzugefügt, wenn die Liste, in der die Zwischenergebnisse gespeichert sind, leer ist oder wenn "Eingabeelement> = letztes Element der Liste". (Umgekehrt, wenn "Eingabeelement <letztes Element der Liste", wird ** Stille ** ausgeführt.)

BinaryOperator<A> combiner()

Der Kombinierer gibt einen BinaryOperator zurück, der Instanzen vom Typ A kombiniert, bei denen Zwischenergebnisse akkumuliert wurden. Da Stream parallel ausgeführt werden kann, müssen die Ergebnisse verkettet werden, die bei paralleler Ausführung mit dieser Kombiniererfunktion erzielt werden. Hier werden die Elemente der Liste auf der verketteten Seite verworfen (** bereinigt **), bis sie gleich oder größer als das letzte Element auf der verketteten Seite sind. Beachten Sie, dass dropWhile nur mit Java 9 oder höher verwendet werden kann.

Function<A, R> finisher()

Der Finisher gibt die Funktion des Endbearbeitungsprozesses für die Instanz vom Typ A zurück, die alle Ergebnisse gesammelt hat. Hier wird die nach Starlin sortierte Liste als Stream zurückgegeben. Auf diese Weise kann collect die Methodenkette fortsetzen, obwohl es sich um eine Beendigungsoperation handelt.

Set characteristics()

properties gibt eine Reihe von Collector.Characteristics zurück, die die Attribute dieses Collectors angeben. Es gibt drei Typen: CONCURRENT (kann parallel ausgeführt werden), UNORDERED (keine Reihenfolge) und IDENTITY_FINISH (Finisher kann weggelassen werden). Hier wird nur CONCURRENT zurückgegeben, da der Finisher verarbeitet wird und die Bestellung eine wichtige Sortierung ist.

Anwendungsbeispiel

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

Immerhin fühlt es sich gut an, mit Stream verarbeiten zu können.

Recommended Posts

Ich habe versucht, Sterling Sort mit Java Collector zu implementieren
Ich habe versucht, TCP / IP + BIO mit JAVA zu implementieren
Ich habe versucht, mit Java zu interagieren
Ich habe versucht, eine Standardauthentifizierung mit Java durchzuführen
Ich habe versucht, den Block mit Java zu brechen (1)
Ich habe versucht, das Hochladen von Dateien mit Spring MVC zu implementieren
Ich habe versucht, die Firebase-Push-Benachrichtigung in Java zu implementieren
[Java 11] Ich habe versucht, Java auszuführen, ohne mit Javac zu kompilieren
[Java] Ich habe versucht, die Yahoo API-Produktsuche zu implementieren
Ich habe versucht, die Methode der gegenseitigen Teilung von Eugrid in Java zu implementieren
Ich habe versucht, UDP mit Java zu kommunizieren
Ich habe versucht, das Java-Lernen zusammenzufassen (1)
Ich habe jetzt versucht, Java 8 zusammenzufassen
Ich habe versucht, mit Chocolatey eine Java8-Entwicklungsumgebung zu erstellen
Ich habe versucht, eine Java EE-Anwendung mit OpenShift zu modernisieren.
[Rails] Ich habe versucht, die Stapelverarbeitung mit der Rake-Task zu implementieren
Ich möchte verschiedene Funktionen mit Kotlin und Java implementieren!
Ich habe versucht, Java-Lambda-Ausdrücke zusammenzufassen
Ich habe versucht, mit Web Assembly zu beginnen
Ich habe versucht, die Bildvorschau mit Rails / jQuery zu implementieren
Ich habe versucht, eine flexible ODER-Zuordnung mit MyBatis Dynamic SQL zu implementieren
Ich habe versucht, das Iterator-Muster zu implementieren
Ich habe versucht, OpenCV mit Java + Tomcat zu verwenden
Ich habe versucht, eine Android-Anwendung mit MVC zu erstellen (Java)
Ich habe versucht, AdoptOpenJDK 11 (11.0.2) mit dem Docker-Image zu überprüfen
Ich habe versucht, polymorph in Nogizaka zu implementieren.
Ich habe versucht, die Federbeinkonfiguration mit Coggle zu verwalten
Java Ich habe versucht, einen einfachen Block zu brechen
Ich möchte Java8 für jeden mit Index verwenden
Ich habe versucht, neunundneunzig in Java auszugeben
Versuchen Sie, TCP / IP + NIO mit JAVA zu implementieren
Ich habe versucht, Alexa-Fähigkeiten mit Java zu erstellen
Ich habe versucht, einen Server mit Netty zu implementieren
Ich habe versucht, mit HCE-F von Android eine Funktion zu implementieren, die Felica Lite entspricht
[Java] Ich habe versucht, über den Verbindungspool eine Verbindung mit Servlet (Tomcat) & MySQL & Java herzustellen
Ich habe versucht, was ich mit Stream leise versuchen wollte.
Ich habe versucht, CSV mit Outsystems zu lesen und auszugeben
[Java] Ich habe versucht, Paizas B-Rang-Problem zu lösen
Ich habe versucht, SQS mit AWS Java SDK zu betreiben
# 2 [Anmerkung] Ich habe versucht, neunundneunzig mit Java zu berechnen.
Ich habe MySQL 5.7 mit Docker-Compose gestartet und versucht, eine Verbindung herzustellen
Ich habe versucht, eine Anmeldefunktion mit Java zu erstellen
Ich habe versucht, Animationen mit der Blazor + Canvas-API zu zeichnen
Ich habe versucht, mit OCR eine PDF-Datei mit Java zu verarbeiten
Ich möchte Bildschirmübergänge mit Kotlin und Java machen!
~ Ich habe jetzt versucht, funktionale Programmierung mit Java zu lernen ~
Ich habe nc (netcat) normalerweise mit JAVA gemacht
Ich habe versucht herauszufinden, was sich in Java 9 geändert hat
Ich habe versucht, mit Java und Spring eine Funktion / einen Bildschirm für den Administrator einer Einkaufsseite zu erstellen
[Swift] Ich habe versucht, mit UICollectionView eine Instagram-ähnliche Benutzeroberfläche mit nur Code ohne Storyboard zu implementieren
[Azure] Ich habe versucht, eine kostenlose Java-App zu erstellen ~ Mit FTP verbinden ~ [Anfänger]
Java zum Spielen mit Function
Sortieren Sie Zeichenfolgen als charakteristische Funktion mit Java
Ich habe Drools (Java, InputStream) ausprobiert.
Stellen Sie mit Java eine Verbindung zur Datenbank her
Ich habe versucht, Java REPL zu verwenden