Java 将double for循环转换为流?
我只是好奇我能不能换一下Java 将double for循环转换为流?,java,for-loop,replace,java-stream,Java,For Loop,Replace,Java Stream,我只是好奇我能不能换一下 for (String arg : args) { int number = Integer.parseInt(arg); int checksum = 0; for (int digits = 0; digits < 10; digits++) { checksum += number % 10; number /= 10; } S
for (String arg : args) {
int number = Integer.parseInt(arg);
int checksum = 0;
for (int digits = 0; digits < 10; digits++) {
checksum += number % 10;
number /= 10;
}
System.out.println(checksum);
}
}
然后使用如下函数:
class FunctionTest implements Function<String, Integer> {
@Override
public Integer apply(String s) {
int number = Integer.parseInt(s);
int checksum = 0;
IntStream.range(1,10).reduce(number, ()-> ?)
checksum += number % 10;
number /= 10;
return checksum;
}
}
class FunctionTest实现函数{
@凌驾
公共整数应用(字符串s){
int number=整数。parseInt(s);
整数校验和=0;
IntStream.range(1,10).reduce(数字,()->?)
校验和+=数字%10;
数目/=10;
返回校验和;
}
}
但我想我已经走到了死胡同
是否有人有更好的想法,或者这实际上是不可能的?在我看来,校验和计算不是基于流的解决方案的好选择。通过参数的循环可以转换为流,但是:
public class Help {
public static void main(String[] args) {
Arrays.stream(args)
.mapToInt(Integer::parseInt)
.map(Help::toCheckSum)
.forEach(System.out::println);
}
private static int toCheckSum(int number) {
int checksum = 0;
for (int digits = 0; digits < 10; digits++) {
checksum += number % 10;
number /= 10;
}
return checksum;
}
}
公共类帮助{
公共静态void main(字符串[]args){
Arrays.stream(args)
.mapToInt(整数::parseInt)
.map(帮助::toCheckSum)
.forEach(System.out::println);
}
私有静态int-toCheckSum(int-number){
整数校验和=0;
用于(整数位数=0;位数<10;位数++){
校验和+=数字%10;
数目/=10;
}
返回校验和;
}
}
这个函数将字符串拆分为单独的字符串,将它们映射为整数,然后求和
最后,也是一个只有正数的解决方案:
Arrays.stream(args)
.map(CharSequence::chars)
.map(chars -> chars.map(Character::getNumericValue))
.map(IntStream::sum)
.forEach(System.out::println);
假设输入是字符串的方法
由于只有IntStream
,而没有CharStream
,这一点有些模糊。给出一个IntStream'0'
根据ASCII映射到48
,'1'
映射到49
等。因此,您只需减去48即可得到整数值
String[]x={"1495","34","333333","-13"};
Arrays.stream(x)
.map(y-> y.chars().map(z->z-48).sum())
.forEach(System.out::println);
正如JBNizet所指出的,该解决方案做的事情并不完全相同。如果任何字符串不是整数(并且适用于表示大于Integer.MAX\u VALUE
的整数的字符串),则不会引发异常。
此外,它还返回负数的正和(对于负数,-
符号可能应该进行过滤,例如使用.filter(Character::isDigit)
另一种方法是假设输入是整数
这更像是将OP的代码“翻译”为。流以原始整数开始,随后的元素通过除以10生成。元素被映射为模10
int[]ints={1495,34,333333,-13};
IntStream.of(ints)
.map( a-> IntStream.iterate(a,b->b/10) // (1)
.map(c->c%10) // (2)
.limit(10) // (3)
.sum())
.forEach(System.out::println);
(1) 例如,为1495生成以下IntStream:
14951491400
(2) 映射到模:
594100
(3) 由于这是一个无限流,我们需要一个限制。请注意,不仅数组和集合是可流的,字符序列也是可流的。现在,您可以对字符进行流式处理,并在求和之前将每个数字转换为数值,但转换只意味着减去相同的偏移量(
'0'
)根据字符,已经有了一个基本的算术解决方案,可以对同一个数字进行多次求和,乘法:
Arrays.stream(args)
.map(s -> s.chars().sum()-'0'*s.length())
.forEach(System.out::println);
这是简洁而有效的
如果您需要负数支持,可以将其更改为
Arrays.stream(args)
.map(s -> s.startsWith("-")?
'0'*(s.length()-1)-s.chars().skip(1).sum():
s.chars().sum()-'0'*s.length())
.forEach(System.out::println);
它应该是数字的前10位的总和吗?使用辅助函数比使用lambda更有效吗?我喜欢这个,因为它是可重用的。什么更有效?使用哪个lambda?是的,我明确地说不反对循环。那又怎样?专业人员使用正确的工具来完成工作,并提供关于他们的des的参数他们更喜欢可读性而不是“酷”(不管这意味着什么)。他们不会因为流是新事物而不加思考地到处使用流。他们会在不正确的情况下挑战他们的要求。当你成为一个流时,你会意识到这一点。@N-rG:如果你想要一个简短的解决方案,你可以尝试我的解决方案。但引用的解决方案的最大限制是:它使用正则表达式拆分字符串,即1.ob字串,2。可能效率不高。
Character::getNumericValue
更容易解释。但这两种解决方案的作用与OP不同(没有验证字符串是否为整数),并且对负整数给出不同的结果。@JBNizet结果表明-
的数值为-1(如果使用减法,则为-3),因此答案仅为1。也许可以通过映射运行字符串(s->s.replaceAll(“\\D+”,“”))
最初?不需要正则表达式时不要使用正则表达式。只需过滤器(z->z!='-'))
在映射之前。但无论如何,我觉得校验和算法应该是校验和整数。程序从字符串开始并解析它们的事实,对我来说,是一个轶事。所以我还是更喜欢一个checksum()方法,它处理整数而不是字符串。你的替代方法看起来很好(在我的例子中,我只使用正数)谢谢!.split((?!^)”)
看起来像是.split(“”
)的一个复杂变体。但最后,它是…@Holger是的,谢谢你指出这一点。我将它简化为split(“”
)。
int[]ints={1495,34,333333,-13};
IntStream.of(ints)
.map( a-> IntStream.iterate(a,b->b/10) // (1)
.map(c->c%10) // (2)
.limit(10) // (3)
.sum())
.forEach(System.out::println);
Arrays.stream(args)
.map(s -> s.chars().sum()-'0'*s.length())
.forEach(System.out::println);
Arrays.stream(args)
.map(s -> s.startsWith("-")?
'0'*(s.length()-1)-s.chars().skip(1).sum():
s.chars().sum()-'0'*s.length())
.forEach(System.out::println);