2017-06-03 7 views
3

Ich habe Mühe, einen funktionierenden Code dafür zu bekommen. Ich habe einen Strom von Ziffern zwischen 0 und 9. Ich möchte eine BigInteger von diesen Ziffern erhalten. Beispiel:Java Stream Ziffern zu Nummer

IntStream digits = IntStream.of(1, 2, 3) // should get me a Biginteger 123. 
IntStream digits = IntStream.of(9, 5, 3) // should get me a Biginteger 953. 

Gibt es eine Möglichkeit, alle Elemente aus dem Strom zu verketten? Hier ist meine Grundidee:

digits.forEach(element -> result=result.concat(result, element.toString())); 

Antwort

4

Sie jede Ziffer in eine Zeichenfolge zuordnen konnte, kommen sie alle zusammen und dann eine BigInteger daraus erstellen:

BigInteger result = 
    IntStream.of(1, 2, 3) 
      .mapToObj(String::valueOf) 
      .collect(Collectors.collectingAndThen(Collectors.joining(), 
                BigInteger::new)); 
+0

@Eugene viel besser, danke! Ich habe es bearbeitet in – Mureinik

+0

Sieht gut aus und macht Sinn, aber ich bekomme "Der Konstruktor BigInteger (Object) ist undefined". Außerdem muss ich eine Assertion hinzufügen, wenn der Stream Zahlen über 9 hat. Aber wenn ich den Stream vorher überprüfe, wird er geschlossen und ich kann ihn nicht mehr verwenden. Ideen? –

2

Sie reduzieren könnte wie folgt aussehen:

BigInteger big1 = IntStream.of(1, 2, 3, 4, 5, 6, 7, 8, 9) 
    .mapToObj(BigInteger::valueOf) 
    .sequential() // if parallel, reduce would return sweet potatoes 
    .reduce((a, b) -> a.multiply(BigInteger.TEN).add(b)) 
    .orElse(BigInteger.ZERO); 

System.out.println(big1); // 123456789 

Obwohl ich denke, es wäre besser, eine String zu erstellen und sie als Argument BigInteger ‚s Konstruktor verwenden, wie in @ Mureinik ist ein nswer. Hier verwende ich eine Variante, die kein String Objekt pro Ziffer schafft:

String digits = IntStream.of(1, 2, 3, 4, 5, 6, 7, 8, 9) 
    .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append) 
    .toString(); 
BigInteger big2 = new BigInteger(digits); 

System.out.println(big2); // 123456789 
2

Sie waren nicht so schlecht, kleinere Änderungen zu tun, die ich vorschlagen würde forEachOrdered verwendet, weil forEach nicht um übernimmt keine Garantie für parallele Ströme und Sammlung, die zu einem StringBuilder. Etwas wie:

IntStream digits = IntStream.of(1, 2, 3); 
StringBuilder sb = new StringBuilder(); 
digits.forEachOrdered(sb::append); 
System.out.println(new BigInteger(sb.toString())); 
1

Hier ist die Lösung von StreamEx

BigInteger res = new BigInteger(IntStreamEx.of(1, 2, 3).joining("")); 

Oder vielleicht sollten wir das Präfix entfernen ‚0‘, wenn das

BigInteger res = new BigInteger(IntStreamEx.of(0, 1, 2).dropWhile(i -> i == 0).joining("")); 

passieren könnte, und vielleicht sollten wir hinzufügen Auf leeren Strom prüfen:

String str = IntStreamEx.of(0, 1, 2).dropWhile(i -> i == 0).joining("") 
BigInteger res = str.length() == 0 ? BigInteger.ZERO : new BigInteger(str);