任务是使用流检查这种类型的字符串“az6byw59uo6cr8bnt7nm284130”是否满足以下条件:
空格前20个大写字母字符或数字,严格数字为6
空格后6位
以下是我迄今为止所做的:
public static boolean validateCode(String input)
{
String[] words = input.split("\\s+");
ArrayList<String> wordList = new ArrayList<String>(Arrays.asList(words));
Stream<Character> left = wordList.get(0).chars().mapToObj(ch -> (char)ch);
Stream<Character> right = wordList.get(1).chars().mapToObj(ch -> (char)ch);
boolean leftIs20 = left
.collect(Collectors.counting()).equals(20L);
boolean leftisAlfaDigit = left
.allMatch(x -> (Character.isDigit(x) || Character.isUpperCase(x)));
boolean leftis6Digits = left.filter(x -> Character.isDigit(x)).equals(6L);
boolean rightAreDigits = right.allMatch(x ->Character.isDigit(x));
boolean rightAre6Digits = right.collect(Collectors.counting()).equals(6L);
return leftIs20 && leftisAlfaDigit && leftis6Digits && rightAreDigits && rightAre6Digits;
}
但是由于流不能被重用,这是错误的,但是我不知道如何克服这个问题。
3条答案
按热度按时间zxlwwiss1#
确保检查结果数组的大小(即通过拆分给定字符串获得的数组)以避免
ArrayIndexOutOfBoundsException
.由于您必须在子字符串的左侧执行三个独立的操作,因此必须创建一个流提供者来构造一个新的流,并且已经设置了所有中间操作。查看本文了解更多信息。
演示:
输出:
jtw3ybtb2#
正如其他人指出的,没有必要为此使用流,但可以做到。如果我理解正确的要求,那么这应该可以满足您对streams的需求。
要测试它:
编辑-我错过了第一部分必须有6位数字的事实
我要提醒的是,使用它可以工作,但是streamapi可能太过杀伤力了。此解决方案还可以在map reduce期间创建临时对象,而其他解决方案可以避免这些临时对象。对于许多情况来说,这并不是什么大问题,但在性能危急的情况下,这可能会出现在分析中。您必须在自己的测试中查看它与regex或其他解决方案的比较。这只是使用所要求的方法回答问题。
iqjalb3h3#
您所需要的只是匹配模式,这样流就没有必要或不太合适了。但是,您可以使用
filter
```String[] data = { "AZ6BYW59UO6CR8BNT7NM 284130", // valid
"AZ6BYW59UO6&C8BNT7NM 2841S0", // non letter or digit (&)
"MMMMMMMMMMMMMMMMMMMM 823820", // not enough digits
"111111MMMMMMMMMMMMMM 228130", // valid
"11111111111111111111 228130", // too may digits
"AZ6BYW59UO6CR8BT7NM 284130", // first word too short
"AZ6BYW59UO6CR8BNT7NM 2824130", // seven digits
"AZ6BYW59UO6CRs8BNT7NM 284130", // first word too long
"AZ6BYW59UO6CR8BNT7NM 282230" // too many spaces
"AZ6BYW59UO6CR8BNT7NM 28230" }; // five digits
for (String text : data) {
System.out.printf("%30s -> %s%n", text, validateCode(text) ? "Valid" : "Invalid");
}
AZ6BYW59UO6CR8BNT7NM 284130 -> Valid
AZ6BYW59UO6&C8BNT7NM 2841S0 -> Invalid
MMMMMMMMMMMMMMMMMMMM 823820 -> Invalid
111111MMMMMMMMMMMMMM 228130 -> Valid
11111111111111111111 228130 -> Invalid
AZ6BYW59UO6CR8BT7NM 284130 -> Invalid
AZ6BYW59UO6CR8BNT7NM 2824130 -> Invalid
AZ6BYW59UO6CRs8BNT7NM 284130 -> Invalid
AZ6BYW59UO6CR8BNT7NM 282230 -> Invalid
AZ6BYW59UO6CR8BNT7NM 28230 -> Invalid
public static boolean validateCode(String text) {
return Stream.<String[]>of(text.split("\s"))
.filter(s -> s.length == 2 && s[0].matches("\w{20}") && s[0].chars()
.filter(Character::isDigit)
.count() == 6 && s[1].matches("\d{6}"))
.count() == 1;
}