Imprimer simple pour un `` IntStream` comme CHAINE`

voix
30

Avec Java-8 je peux traiter facilement un String(ou tout autre CharSequence) comme IntStreamutilisant soit le charsou la codePointsméthode.

IntStream chars = Hello world..codePoints();

Je peux ensuite manipuler le contenu du flux

IntStream stars = chars.map(c -> c == ' ' ? ' ': '*');

Je suis la chasse d'un moyen bien rangé pour imprimer les résultats et je ne peux même pas trouver un moyen simple. Comment puis-je mettre ce courant de ints en un format qui peut être imprimé comme je peux un String.

De ce qui précède , starsje l' espère à imprimer

***** ******
Créé 28/11/2013 à 10:36
source utilisateur
Dans d'autres langues...                            


10 réponses

voix
28

String result = "Hello world."
  .codePoints()
//.parallel()  // uncomment this line for large strings
  .map(c -> c == ' ' ? ' ': '*')
  .collect(StringBuilder::new,
           StringBuilder::appendCodePoint, StringBuilder::append)
  .toString();

Mais encore, "Hello world.".replaceAll("[^ ]", "*")est plus simple. Pas tout de lambdas. Avantages

Créé 28/11/2013 à 12:39
source utilisateur

voix
16

Un peu moins efficace mais plus concise solution à Holger de:

String result = "Hello world."
    .codePoints()
    .mapToObj(c -> c == ' ' ? " ": "*")
    .collect(Collectors.joining());

Collectors.joining()utilise en interne StringBuilder, au moins dans les sources OpenJDK .

Créé 09/05/2014 à 11:15
source utilisateur

voix
6

D' autres réponses montrent comment collecter un flux de chaînes en une seule chaîne et comment collecter des caractères à partir d' un IntStream. Cette réponse montre comment utiliser un collecteur personnalisé sur un flux de caractères.

Si vous souhaitez collecter un flux de ints dans une chaîne, je pense que la plus propre et la solution la plus générale est de créer une méthode utilitaire statique qui retourne un collecteur. Ensuite , vous pouvez utiliser la Stream.collectméthode comme d' habitude.

Cet utilitaire peut être mis en œuvre et utilisé comme ceci:

public static void main(String[] args){
    String s = "abcacb".codePoints()
        .filter(ch -> ch != 'b')
        .boxed()
        .collect(charsToString());

    System.out.println("s: " + s); // Prints "s: acac"
}

public static Collector<Integer, ?, String> charsToString() {
    return Collector.of(
        StringBuilder::new,
        StringBuilder::appendCodePoint,
        StringBuilder::append,
        StringBuilder::toString);
}

Il est un peu surprenant qu'il n'y ait pas quelque chose comme ça dans la bibliothèque standard.

Un inconvénient de cette approche est qu'il exige que les caractères soient mis en boîte depuis l' IntStreaminterface ne fonctionne pas avec les collectionneurs.

Un problème non résolu et dur est ce que la méthode utilitaire doit être nommé. La convention pour les méthodes d'utilité collecteur est de les appeler toXXX, mais toStringest déjà pris.

Créé 07/02/2015 à 11:48
source utilisateur

voix
-1

Vous pouvez le faire directement avec le code suivant: -

"Hello world".codePoints().forEach(n -> System.out.print(n == ' ' ? ' ':'*'));
Créé 18/04/2016 à 08:15
source utilisateur

voix
0

Il y a une réponse simple qui est un peu moins enclin à faire tout en streaming. Il est donc pas une doublure, mais il est probablement plus efficace et très facile à lire:

public static String stars(String t) {
    StringBuilder sb = new StringBuilder(t.length());
    t.codePoints().map(c -> c == ' ' ? ' ' : '*').forEach(sb::appendCodePoint);
    return sb.toString();
}

Parfois courte n'est pas la même chose que concise, je ne pense pas que tout le monde doit se demander comment fonctionne la fonction ci-dessus.

Cette solution fait en sorte que les points de code ne sont jamais reconvertis en caractères. Il est donc un peu plus générique que d'autres solutions énumérées ici.

Créé 21/11/2016 à 21:21
source utilisateur

voix
1

Si nous devons, nous pouvons faire une seule ligne de cette façon extrêmement laid:

public static String stars(String t) {
    return t.codePoints().map(c -> c == ' ' ? ' ': '*').mapToObj(i -> new String(new int[] { i }, 0, 1)).collect(Collectors.joining());
}

Il effectue exactement la même version que mon autre réponse , mais il utilise le streaming tout le chemin. Certaines fonctions pour convertir un seul point de code à une chaîne est évidemment nécessaire:

public static String stars(String t) {
    return t.codePoints().map(c -> c == ' ' ? ' ': '*').mapToObj(Stars::codePointToString).collect(Collectors.joining());
}

private static String codePointToString(int codePoint) {
    return new String(new int[] { codePoint }, 0, 1);
}

qui place ces fonctions dans la classe Starsde cours.

Créé 21/11/2016 à 21:36
source utilisateur

voix
0

Tu peux faire:

chars.mapToObj(c -> c == ' ' ?  " ": "*").collect(joining());

Un autre exemple:

Les exemples suivants renvoient la chaîne d' origine. Mais ceux - ci peuvent être combinés avec d' autres opérations intermédiaires telles que filter().

chars.mapToObj(i -> String.valueOf((char) i)).collect(Collectors.joining()));

"abc".chars().mapToObj(i -> "" + (char) i)).collect(Collectors.joining()));
Créé 25/09/2018 à 15:53
source utilisateur

voix
1

La façon dont je le fais est à l'aide de réduire . Pour obtenir * pour chaque caractère et de l' espace pour chaque espace , il ressemblera à ceci

    String hello = "hello world";
    String result = hello.chars()
        .map(val -> (val == ' ') ?  ' ' : '*')
        .mapToObj(val -> String.valueOf((char) val))
        .reduce("",(s1, s2) -> s1+s2);

Le point est de savoir si ce que vous voulez avec les entiers que de le jeter aux caractères carte puis à cordes puis concaténer , vous pouvez utiliser réduire ou Collectors.joining ()

Créé 21/08/2019 à 01:11
source utilisateur

voix
0

Que dis-tu de ça.

  System.out.println(stars.mapToObj(c -> String.format("%c", c)).collect(
            Collectors.joining()));

  or

  String s = stars.mapToObj(c -> String.format("%c", c)).reduce("",
            (a, b) -> a + b);
Créé 21/08/2019 à 01:20
source utilisateur

voix
0
  IntStream charStream = "hello".chars();
  charStream.mapToObj(c -> (char)c).forEach(System.out::println);

Cela fonctionne pour moi.

Créé 01/01/2020 à 23:48
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more