[Memo] Verwendung von Google MµG

Ein Memo zur Verwendung der Bibliothek Google MµG, einer Dienstprogrammbibliothek für Java 8.

Abhängigkeiten

dependencies {
    compile 'com.google.mug:mug:1.12'
}

BiStream

Stream mit Schlüssel und Wert.

Erstellen Sie einen BiStream

Verwenden Sie die statische Methode von "BiStream".

biStream()

var input = Stream.of( "foo", "bar", "buz" );
var result = BiStream.biStream( input )
                     .mapValues( e -> e.toUpperCase() )
                     .toMap();
assertThat( result ).containsExactly( "foo", "FOO", "bar", "BAR", "buz", "BUZ" );

Wickeln Sie einen normalen "Stream" ein. Wenn Sie sich fragen, was Sie verwenden sollen, scheint es, als ob Sie danach eine Operation wie "mapKeys ()" aufrufen möchten.

var input = Stream.of( "foo", "bar", "buz" );
var result = BiStream.biStream( input, Function.identity(), e -> e.toUpperCase() )
                     .toMap();
assertThat( result ).containsExactly( "foo", "FOO", "bar", "BAR", "buz", "BUZ" );

Eine Version, die eine Zuordnungsfunktion als Argument verwendet.

from()

var input = Map.of( "foo", "123", "bar", "456", "buz", "789" );
var result = BiStream.from( input )
                     .map( ( i, v ) -> i + ":" + v )
                     .collect( toList() );
assertThat( result ).containsExactly( "foo:123", "bar:456", "buz:789" );

Erstellen Sie einen BiStream mit dem Kartenschlüssel und dem Wert als Paar.

indexed()

var input = Stream.of( "foo", "bar", "buz" );
var result = BiStream.indexed( input )
                     .map( ( i, v ) -> i + ":" + v )
                     .collect( toList() );
assertThat( result ).containsExactly( "0:foo", "1:bar", "2:buz" );

Fügen Sie einen Index ab 0 hinzu. Das ist schön, weil es in die Standard-APIs der meisten Programmiersprachen integriert ist. Der Rückgabetyp ist "BiStream <Integer, V>". Primitive Typen werden nicht wie erwartet unterstützt.

neighbors()

var input = Stream.of( "foo", "bar", "buz" );
var result = BiStream.neighbors( input )
                     .map( ( i, v ) -> i + ":" + v )
                     .collect( toList() );
assertThat( result ).containsExactly( "foo:bar", "bar:buz" );

Koppeln Sie zwei benachbarte Werte.

of()

var result = BiStream.of( "foo", "123", "bar", "456" )
                     .map( ( i, v ) -> i + ":" + v )
                     .collect( toList() );
assertThat( result ).containsExactly( "foo:123", "bar:456" );

Ähnlich dem JDK-Standard of ().

zip()

var input1 = Stream.of( "foo", "bar", "buz" );
var input2 = Stream.of( "hoge", "piyo", "fuga" );
var result = BiStream.zip( input1, input2 )
                     .map( ( t, u ) -> t + ":" + u )
                     .collect( toList() );
assertThat( result ).containsExactly( "foo:hoge", "bar:piyo", "buz:fuga" );

Kombiniere die beiden Streams. Ich habe das immer selbst gemacht. Um ehrlich zu sein, das Level, das Sie zur Standardbibliothek hinzufügen sollen. Beachten Sie jedoch, dass bei einer anderen Größe von "Stream" der Rest entsprechend der kleineren ignoriert wird.

var input1 = Stream.of( "foo", "bar", "buz" );
var input2 = Stream.of( "hoge", "piyo" );
var result = BiStream.zip( input1, input2 )
                     .map( ( t, u ) -> t + ":" + u )
                     .collect( toList() );

assertThat( result ).containsExactly( "foo:hoge", "bar:piyo" );

Verwenden Sie "BiStream"

append()

var result = BiStream.of( "foo", "123" ).append( "bar", "456" )
                     .map( ( t, u ) -> t + ":" + u )
                     .collect( toList() );
assertThat( result ).containsExactly( "foo:123", "bar:456" );

Fügen Sie danach einen Wert hinzu.

inverse()

var result = BiStream.of( "foo", "123", "bar", "456" )
                     .inverse()
                     .map( ( t, u ) -> t + ":" + u )
                     .collect( toList() );
assertThat( result ).containsExactly( "123:foo", "456:bar" );

Tauschen Sie Werte gegen Schlüssel aus. Ich möchte, dass Sie es dem Standard-Stream hinzufügen ...

MoreStream

Bietet Erweiterungen, die in JDK oder Guava nicht gefunden wurden.

generate()

var result = MoreStreams.generate( 1, n -> n >= 9 ? Stream.empty() : Stream.of( n + 1 ) )
                        .collect( toList() );
assertThat( result ).containsExactly( 1, 2, 3, 4, 5, 6, 7, 8, 9 );

Eine Methode zum Generieren von * endlichen * Streams. Beenden Sie die Generierung, wenn ein leerer Stream zurückgegeben wird. Gibt es eine Verwendung dafür?

flatten()

var input = Stream.of(
        Stream.of( "foo", "bar", "buz" ),
        Stream.of( "hoge", "piyo", "fuga" )
);
var result = MoreStreams.flatten( input )
                        .collect( toList() );
assertThat( result ).containsExactly( "foo", "bar", "buz", "hoge", "piyo", "fuga" );

Der gleiche Prozess sollte mit "flatMap" möglich sein, aber es gibt diese Methode, da sie aufgrund eines Java-Fehlers keine unendlichen Streams verarbeiten kann. Es scheint, dass es in JDK 10 behoben wurde.

dice()

var input = Stream.of( "foo", "bar", "buz", "hoge", "piyo" );
var result = MoreStreams.dice( input, 2 )
                        .collect( toList() );
assertThat( result.size() ).isEqualTo( 3 );
var list1 = result.get( 0 );
assertThat( list1 ).containsExactly( "foo", "bar" );
var list2 = result.get( 1 );
assertThat( list2 ).containsExactly( "buz", "hoge" );
var list3 = result.get( 2 );
assertThat( list3 ).containsExactly( "piyo" );

Listen Sie die Streams nach der angegebenen Größe auf und fügen Sie sie in einer neuen Stream-Liste zusammen. Bei sequentiellen Streams wird garantiert, dass eine Liste der angegebenen Größe zurückgegeben wird, außer am Ende des Streams. Nicht garantiert für parallele Streams.

Übrigens habe ich zum ersten Mal erfahren, dass eine solche Operation "Würfel" heißt. Wie unterscheidet es sich von "Fenster"?

iterateOnce()

var input = Stream.of( "foo", "bar", "buz" );
for ( var e : MoreStreams.iterateOnce( input ) ) {
    assertThat( e ).isAnyOf( "foo", "bar", "buz" );
}

Eine Methode zum Iterieren eines Streams mit einer for-Anweisung. Vielleicht werde ich es für den Rest meines Lebens nicht benutzen.

iterateThrough()

expect(() -> {
    MoreStreams.iterateThrough( Stream.of( "foo" ), e -> {
        throw new Exception( "Checked Exception!" );
    });
}).throwsException( e -> {
    assertThat( e ).hasMessageThat().isEqualTo( "Checked Exception!" );
});

Es ist im Grunde dasselbe wie "forEach ()", mit dem Unterschied, dass Sie eine aktivierte Ausnahme auslösen können.

Retryer

Ein Prozess zum erneuten Versuchen eines Prozesses, der möglicherweise fehlschlägt. Ich denke, es ist praktisch, aber die meisten Prozesse, die Wiederholungsversuche erfordern, sind in erster Linie mit einer Wiederholungsfunktion ausgestattet, so dass es überraschend nutzlos ist.

  1. Erstellen Sie eine Instanz von "Retryer".
  2. Geben Sie die Wiederholungsbedingung mit "upon ()", "ifReturns ()" usw. an.
  3. Geben Sie das Ausführungsintervall mit "Verzögerung" an. In den meisten Fällen können Sie exponententialBackoff () verwenden, um das Wiederholungsintervall zu verdoppeln.
  4. Geben Sie den zu wiederholenden Prozess mit "retryBlockingly ()", "retry ()", "retryAsync ()" an.

Synchronisieren

var result = new Retryer()
        .upon( RuntimeException.class, Retryer.Delay.ofMillis( 100 ).exponentialBackoff( 2, 2 ) )
        .retryBlockingly( this::mayFail );
assertThat( result ).isEqualTo( "success" );

asynchron

CompletionStage<String> future = new Retryer()
        .upon( RuntimeException.class, Retryer.Delay.ofMillis( 100 ).exponentialBackoff( 2, 2 ) )
        .retry( this::mayFail, Executors.newSingleThreadScheduledExecutor() );
future.thenAccept( result -> {
    assertThat( result ).isEqualTo( "success" );
});

Um ehrlich zu sein, ist die asynchrone API subtil.

Maybe

Eine Klasse für die Wrapping-Verarbeitung, die möglicherweise eine Ausnahme auslöst. So etwas wie eine Version von java.util.Optional mit der Fähigkeit, Ausnahmen zu behandeln. Ist "Try" in Scala relativ nah?

Der Hauptzweck scheint darin zu bestehen, geprüfte Ausnahmen in Streams einfach zu handhaben.

maybe()

Die grundlegende Methode zum Erstellen einer "Vielleicht" -Instanz. Akzeptiert verschiedene Funktionsschnittstellen.

var result = IntStream.range( 1, 10 ).boxed()
                      .map( Maybe.maybe( e -> {
                          if ( e <= 5 ) {
                              return e;
                          } else {
                              throw new Exception();
                          }
                      } ) )
                      .map( m -> m.orElse( e -> Integer.valueOf( 0 ) ) )
                      .collect( toList() );
assertThat( result ).containsExactly( 1, 2, 3, 4, 5, 0, 0, 0, 0 );

Der Wert, der eine Ausnahme in "orElse ()" verursacht hat, wird in "0" konvertiert.

expect(() -> {
    Maybe.maybe( () -> { throw new RuntimeException( "Unchecked!" );} );
}).throwsException( e -> {
    assertThat( e ).hasMessageThat().isEqualTo( "Unchecked!" );
});

Nicht aktivierte Ausnahmen werden unverändert erneut ausgelöst. Hinweis. Es ist nicht so, dass es für etwas anderes als Streams verwendet werden kann, aber aufgrund dieser Einschränkung denke ich, dass es besser ist, eine dedizierte Bibliothek zu verwenden.

byValue()

var result = IntStream.range( 1, 10 ).boxed()
                      .map( Maybe.maybe( e -> {
                          if ( e <= 5 ) {
                              return e;
                          } else {
                              throw new Exception();
                          }
                      } ) )
                      .filter( Maybe.byValue( n -> n % 2 == 0 ) )
                      .map( m -> m.orElse( e -> Integer.valueOf( 0 ) ) )
                      .collect( toList() );
assertThat( result ).containsExactly( 2, 4, 0, 0, 0, 0 );

Da filter () Vielleicht empfängt, gibt es eine Methode, um es zu entpacken. Wie Sie sehen, wird eine Ausnahme bei der nachfolgenden Verarbeitung fortgesetzt.

1.PNG 2.PNG

catching()

var result = IntStream.range( 1, 10 ).boxed()
                      .map( Maybe.maybe( e -> {
                          if ( e <= 5 ) {
                              return e;
                          } else {
                              throw new Exception();
                          }
                      } ) )
                      .flatMap( m -> m.catching( e -> {} ) )
                      .collect( toList() );
assertThat( result ).containsExactly( 1, 2, 3, 4, 5 );

Verwenden Sie diese Option, wenn Sie den Wert nur ignorieren möchten.

Funnel

Es ist eine ziemliche Nische, aber es scheint praktisch, wenn Sie süchtig werden.

Anwendungsfall

Funnel

var funnel = new Funnel<String>();
var batch = funnel.<String>through( data -> {
    assertThat( data ).containsExactly( "batch1", "batch2" );
    return data.stream().map( String::toUpperCase ).collect( toList() );
} );

var input = List.of( "local1", "batch1", "local2", "batch2" );
for ( var i : input ) {
    if ( i.startsWith( "local" ) ) {
        funnel.add( i );
    } else {
        batch.accept( i );
    }
}
var result = funnel.run();

assertThat( result ).containsExactly( "local1", "BATCH1", "local2", "BATCH2" );
  1. Instanziieren Sie zuerst "Trichter"
  2. Verwenden Sie die Methode through (), um den Stapelkonvertierungsprozess anzugeben.
  3. Rufen Sie "Funnel.add ()" auf, damit die Werte einzeln verarbeitet werden.
  4. Übergeben Sie die zu verarbeitenden Werte gemeinsam an "Funnel.Batch.accept ()".
  5. Führen Sie mit Funnel.run () aus.

Beachten Sie, dass accept () eine Überladung hat, die eine Funktion akzeptiert, die das Ergebnis als Argument konvertiert.

var funnel = new Funnel<String>();
var batch = funnel.<String>through( data -> List.of() );
batch.accept( "batch1" );
expect(() -> {
    funnel.run();
}).throwsException( e -> {
    assertThat( e ).isInstanceOf( IllegalStateException.class );
});

Wenn sich die Größe der Stapelrückgabeliste von der Eingabe unterscheidet, wird offensichtlich eine Fehlermeldung angezeigt.

var funnel = new Funnel<String>();
var batch = funnel.<String>through( data -> List.of() );
batch.accept( "batch1" );

expect(() -> {
    funnel.run();
}).throwsException( e -> {
    assertThat( e ).isInstanceOf( IllegalStateException.class );
});

Die Reihenfolge hängt von der Reihenfolge der Stapelverarbeitung ab. Es muss sichergestellt werden, dass der Prozess in derselben Reihenfolge wie die Eingabe zurückgegeben wird.

var funnel = new Funnel<String>();
var batch = funnel.<String>through( data -> {
    var newList = new ArrayList<String>( data );
    Collections.reverse( newList );
    return newList;
} );
batch.accept( "batch1" );
batch.accept( "batch2" );
var result = funnel.run();

assertThat( result ).containsExactly( "batch2", "batch1" );

Parallelizer

Parallelisieren Sie, wie der Name schon sagt, die Verarbeitung.

var input = Stream.of( "foo", "bar", "buz" );
var result = Collections.synchronizedList( new ArrayList<String>() );
new Parallelizer( executor, 3 )
        .parallelize( input, result::add );
assertThat( result ).containsExactly( "foo", "bar", "buz" );
  1. Instanziieren Sie "Parallelizer". Die Argumente sind "ExecutorService" zum Ausführen des Prozesses und die Anzahl der Aufgaben, die gleichzeitig ausgeführt werden können. Entspricht es im Grunde der Anzahl der Threads in "ExecutorService"?
  2. Rufen Sie "parallelize ()" oder "parallelizeUninterruptibly ()" auf. Das erste Argument ist "Stream" oder "Iterator", dh die Eingabedaten, und das zweite Argument ist die auszuführende Verarbeitung.

Der Prozess wird blockiert, bis er abgeschlossen ist. Wenn in der Mitte eine Ausnahme auftritt, wird die nachfolgende Verarbeitung unterbrochen.

Laut README

Parallel streams are for CPU-bound tasks. JDK has built-in magic to optimally use the available cores. Parallelizer is for IO-bound tasks.

Es scheint, dass es für die Eingabe / Ausgabe von Dateien, den Aufruf einer externen API usw. verwendet werden sollte.

Zusammenfassung

Recommended Posts

[Memo] Verwendung von Google MµG
So verwenden Sie Google Colaboratory
Verwendung von cron (persönliches Memo)
[Memo] Verwendung von BeautifulSoup4 (1) HTML anzeigen
Verwendung von Google Test in C-Sprache
So verwenden Sie Google Assistant unter Windows 10
Verwendung von xml.etree.ElementTree
Wie benutzt man Python-Shell
Hinweise zur Verwendung von tf.data
Verwendung von virtualenv
Wie benutzt man Seaboan?
Verwendung von Image-Match
Wie man Shogun benutzt
Verwendung von Pandas 2
Verwendung von numpy.vectorize
Verwendung von pytest_report_header
Wie man teilweise verwendet
Wie man Bio.Phylo benutzt
Verwendung von SymPy
Wie man x-means benutzt
Verwendung von WikiExtractor.py
Verwendung von IPython
Wie benutzt man Matplotlib?
Verwendung von iptables
Wie benutzt man numpy?
Verwendung von TokyoTechFes2015
Wie benutzt man venv
Verwendung des Wörterbuchs {}
Wie benutzt man Pyenv?
Verwendung der Liste []
Wie man Python-Kabusapi benutzt
Verwendung von OptParse
Verwendung von return
Wie man Imutils benutzt
Verwendung von Qt Designer
Verwendung der Suche sortiert
[gensim] Verwendung von Doc2Vec
python3: Verwendung der Flasche (2)
Verwendung des Generators
[Python] Verwendung von Liste 1
Wie benutzt man Python Argparse?
Verwendung von IPython Notebook
Wie man Pandas Rolling benutzt
[Hinweis] Verwendung von virtualenv
Verwendung von Redispy-Wörterbüchern
Python: Wie man pydub benutzt
[Python] Verwendung von checkio
[Go] Verwendung von "... (3 Perioden)"
So bedienen Sie GeoIp2 von Django
[Python] Verwendung von input ()
Wie benutzt man den Dekorateur?
[Einführung] Verwendung von open3d
Wie benutzt man Python Lambda?
So verwenden Sie Jupyter Notebook
[Python] Verwendung von virtualenv
python3: Verwendung der Flasche (3)
python3: Wie man eine Flasche benutzt