2016-04-26 5 views
1

Ich habe versucht, einen Strom von Zeichenfolgen auf den Hash dieser Zeichenfolgen abzubilden, während die Zeichenfolgen in der Ausgabe beibehalten werden. Am Ende konvertierte ich den Hash in eine Zeichenkette, so dass ich entweder eine String[] zuordnen oder sie sogar als eine Zeichenkette zusammenfügen konnte. Ich hätte vorgezogen in einem Lambda-Ausgang hätte sowohl eine String als auch eine byte[] Vermeidung einer Umwandlung sein können. Ohne ein spezifisches Wertobjekt zu definieren, das nur diese beiden enthält, gibt es eine Art reziproker BiConsumer, d. H. Einen BiProducer?Gibt es eine Umkehrung von BiConsumer für die Zuordnung zu mehreren Werten wie Tupel

public static final ArrayList<String> inputs; // ... initialized elsewhere 
... 
inputs.parallelStream().map(s -> { 
    try { 
    String h = String.format("%032x", 
     new BigIntger(1, MessageDigest.getInstance("MD5") 
         .digest(s.getBytes(StandardCharsets.UTF_8)))); 
    String[] r = {s, h}; 
    return r; 
    } catch (NoSuchAlgorithmException e) { 
    throw new RuntimeException(e); 
    } 
}).foreach(tuple -> {String input = tuple[0], hash = tuple[1]; ...}); 

Sie sehen, wenn in foreach ich eine byte[] des Hash wollte ich es mir gewünscht hätte zu passieren, was ich schon in der map hatte, sonst würde ich zu und aus einem String werden Umwandlung lediglich in der Lage sein übergeben Sie es bequem. Offensichtlich, wenn ich eine Klasse machen würde, nur um diese beiden Typen zu halten, wäre das die mühsame Lösung; Gibt es kein bereits bestehendes Angebot für Mapping-Schritte, die auf mehrere Werte stromabwärts übertragen werden?

+0

Ihre Frage ist widersprüchlich. Ein 'BiConsumer' * verbraucht * zwei Gegenstände, ohne etwas zu produzieren. Das Gegenteil, der hypothetische "BiSupplier", würde zwei Gegenstände produzieren, ohne etwas zu verbrauchen, was für eine "Karten" -Operation ungeeignet wäre, die eine "Funktion" erwartet, die ein Element verbraucht und einen Gegenstand erzeugt, also das Gegenteil von "Funktion" ist wieder 'Funktion'. Alles andere wäre nutzlos, da 'map' ein' Function'-Argument erwartet, also müssen Sie ein'Function'-Argument ohne Diskussion zur Verfügung stellen ... – Holger

+0

Das Boxen der zwei Werte in ein anderes Objekt ist mit dem aktuellen Stand der Technik unvermeidlich, aber wenn Sie suchen nach einer Möglichkeit, es angenehmer zu codieren, können Sie versuchen, [StreamEx] (http://amaembo.github.io/streamex/javadoc/one/util/streamex/StreamEx.html#mapToEntry-java.util.function .Funktion-). – Holger

Antwort

0

Verwirrung über die BiConsumer beiseite, danke für den Vorschlag StreamEx in den Kommentaren. Es sieht aus wie es eine sehr schöne Art und Weise hat dies zu schreiben, wie:

StreamEx.of(inputs).toMap(Functions.identity(), 
          s -> { 
          try { 
           return new BigIntger(1, MessageDigest.getInstance("MD5") 
             .digest(s.getBytes(StandardCharsets.UTF_8)))); 
          } catch (NoSuchAlgorithmException e) { 
           throw new RuntimeException(e); 
          }).etc...; 

Es stellt sich heraus, für diesen Fall, da ich weiß, dass die Eingabe eindeutig ist, kann ich dies mit den verfügbaren grouping collector ähnlich tun:

inputs.stream().collect(
    toConcurrentMap(Functions.identity(), 
        s -> { 
         try { 
         return new BigIntger(1, MessageDigest.getInstance("MD5") 
            .digest(s.getBytes(StandardCharsets.UTF_8)))); 
         } catch (NoSuchAlgorithmException e) { 
         throw new RuntimeException(e); 
         }).etc...; 
Verwandte Themen