Étant donné la tâche sumNumbers de CodingBat :
Étant donné une chaîne , renvoie la somme des nombres apparaissant dans la chaîne, en ignorant tous les autres caractères. Un nombre est une série de
1
chiffres ou plus dans une rangée.(Remarque :
Character.isDigit(char)
teste sia
char est l'un des caractères0
,1
, ...,9
.Integer.parseInt(string)
convertita
la chaîne enint
.)
sumNumbers("abc123xyz") → 123
sumNumbers("aa11b33") → 44
sumNumbers("7 11") → 18
Ma solution à ce problème est la suivante :
public int sumNumbers(String str) {
int sum = 0;
java.util.regex.Matcher matcher = java.util.regex.Pattern.compile("[0-9]+").matcher(str);
while (matcher.find()) {
sum += Integer.parseInt(matcher.group());
}
return sum;
}
Est-il possible de résoudre ce problème en utilisant l' API Stream ?
Est-il possible de résoudre ce problème en utilisant l'API Stream ?
Divisez la chaîne donnée en sous-chaîne qui ne sont pas composées de chiffres à l'aide de .split("\\D+")
. Regex "\\D+"
correspond à une chaîne composée d'un ou de plusieurs caractères non numériques . Le résultat sera un tableau de chaînes numériques.
Créez un flux sur le tableau et filtrez les chaînes qui ne sont pas vides. Ensuite, analysez la chaîne int
avec mapToInt()
et appliquez- sum()
la en tant qu'opération terminale.
Cette solution passe tous les tests sur CodingBat :
public int sumNumbers(String str) {
return Arrays.stream(str.split("\\D+"))
.filter(s -> !s.isEmpty())
.mapToInt(Integer::parseInt)
.sum();
}
Puisqu'il ne pouvait y avoir qu'une seule chaîne vide au tout début du tableau produit par .split("\\D+")
, afin de réduire le nombre d'actions effectuées dans le stream-pipeline filter()
peut être remplacé par dropWhile()
.
Il ignorera la première chaîne si elle est vide et après la rencontre du premier élément non vide , cette vérification ne sera pas appliquée. C'est-à- dire que le prédicat dropWhile()
passé au dropWhile()
serait exécuté la plupart du 2
temps. En cas de longue chaîne ( sinon toutes les optimisations n'ont pas d'importance ), ce serait moins cher que de générer une nouvelle chaîne avec replaceAll()
.
public static int sumNumbers(String str) {
return Arrays.stream(str.split("\\D+"))
.dropWhile(String::isEmpty)
.mapToInt(Integer::parseInt)
.sum();
}
Avertissement : dropWhile()
est disponible à partir de Java 9. CodingBat est toujours sur Java 8, il n'est donc pas conscient de cette fonctionnalité. Néanmoins, c'est une solution valable et aussi performante. Vous pouvez le tester dans votre IDE et jouer avec la démo en ligne
Tests (la première solution):
Эта статья взята из Интернета, укажите источник при перепечатке.
Если есть какие-либо нарушения, пожалуйста, свяжитесь с[email protected] Удалить.
я говорю два предложения