2015-09-09 13 views
8

Bazen bir dizede her karakterle basit bir şey yapmak istiyorum. Ne yazık ki, bir dizge değişmez olduğu için, oldukça ayrıntılı olabilen dizgenin içinden döngü yapmak dışında bunu yapmanın iyi bir yolu yoktur. Bunun yerine bir Akış kullanırsanız, sadece bir veya iki satırda çok daha kısa yapılabilirdi.Bir dize için bir java.util.Stream dönüştürün <Character>

String'u Stream<Character>'a dönüştürmenin bir yolu var mı?

cevap

7

Sen CharSequence sağlanan chars() yöntemi kullanabilirsiniz ve String sınıf bu arayüzü uygulayan beri erişebilirsiniz. Eğer Stream<Character>

için IntStream dönüştürmek ister eğer (char) için döküm gerek böylece chars() yöntem, bir IntStream döndürür Ör

public class Foo { 

    public static void main(String[] args) { 
     String x = "new"; 

     Stream<Character> characters = x.chars().mapToObj(i -> (char) i); 
     characters.forEach(System.out::println); 
    } 
} 
+0

Bu özüm, Java koduna uymayan Unicode karakteri içeriyorsa, bu çözüm çalışmaz. Bu, örneğin, bazı arcane dillerin yanı sıra ifadeler ile durumdur. Bunu işleyen bir çözüm için [Tagir'in cevabı] 'na (https://stackoverflow.com/a/32472793/452775) bakın. – Lii

1

Sen IntStream döndürür chars yöntemi kullanabilirsiniz ve char bunu eşleyerek Eğer Stream<Character> olacaktır. mapToObj döner Object bizim durumumuzda Stream değerli Character ait Stream, biz içtenintCharacter o kadar Oto Kutulu char ve java eşlenen çünkü.

Stream<Character> stream = "abc".chars().mapToObj(c -> (char)c); 

Dahası, guava (com.google.common.collect.Lists) yardımı ile size String den Character değişmez listesini döndürür bu, hangi gibi kullanabilirsiniz.

Stream<Character> stream = Lists.charactersOf("abc").stream(); 
5

O IntStream olan kod noktalarının akışını kullanmak genellikle daha güvenlidir:

IntStream codePoints = string.codePoints(); 

Bu şekilde herhangi bir Unicode sembolleriyle doğru sonuçlar olacak böylece Unicode karakter çiftlerini, tek kod noktasıyla birleştirilecek olacak . Örnek kullanım:

String result = string.codePoints().map(Character::toUpperCase) 
     .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) 
     .toString(); 

Ayrıca böylece Stream<Character> işleme bile daha etkili olabilir Boksu önlemek unutmayın. Böyle bir yaklaşım daha az işlevsel görünüyor

StringBuilder sb = new StringBuilder(); 
String result = string.codePoints().map(Character::toUpperCase) 
         .forEachOrdered(sb::appendCodePoint); 

iken Zaten bir StringBuilder varsa veya daha sonra bir şey daha bitiştirmek istiyorsanız, daha verimli olabilir:

böyle akışı toplamak için başka bir yol StringBuilder ayrı kullanmaktır aynı dize.

+1

Artı chars() tercihinde codePoints() önermek için bir tane. –

İlgili konular