转换为循环到流的双倍?

时间:2016-07-01 16:00:48

标签: 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;
        }
        System.out.println(checksum);
    }
}

进入管道Java流(只有那个条件,没有递归方法等)。

我的第一次尝试是

    public static void main(String... args) {
    Stream.of(args)
            .?
    }

然后以某种方式使用如下函数:

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;
    }
}

但我想我已经走到了尽头......

有人有更好的想法还是实际上不可能?

4 个答案:

答案 0 :(得分:6)

Arrays.stream(args)
      .map(Integer::parseInt)
      .map(number -> {
          int sum = 0;
          for(int i = 0; i < 10; i ++) {
              sum += number % 10;
              number /= 10;
          }
          return sum;
      })
      .forEach(System.out::println);

或者(注意这会为负数工作):

Arrays.stream(args)
      .map(number -> number.split(""))
      .map(Arrays::stream)
      .map(strStream -> strStream.mapToInt(Integer::parseInt))
      .map(IntStream::sum)
      .forEach(System.out::println);

这个字符串将字符串拆分为单独的字符串,将它们映射为整数然后将它们相加

最后,也是一个只有正数的解决方案:

 Arrays.stream(args)
       .map(CharSequence::chars)
       .map(chars -> chars.map(Character::getNumericValue))
       .map(IntStream::sum)
       .forEach(System.out::println);

答案 1 :(得分:3)

假设输入的方法是字符串

这有点模糊,因为只有IntStream,但没有CharStreamCharSequence.chars()给出了一个IntStream。 '0'根据ASCII,48'1'等映射到49。因此,您只需减去48即可获得int值。

 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_VALUE的整数的字符串),则不会抛出异常。 此外,它会为负数返回正数(对于-符号,可能会对其进行过滤,例如使用.filter(Character::isDigit)

假设输入的另一种方法是整数

这更像是&#34;翻译&#34; OP的代码为IntStream.generate()。流以原始整数开始,后续元素由除以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:

  

1495 149 14 1 0 0 ...

(2)映射到modulo:

  

5 9 4 1 0 0 ...

(3)因为这是一个无限的流,我们需要一个限制

答案 2 :(得分: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);

答案 3 :(得分:2)

校验和计算不适合基于流的解决方案IMO。但是,通过参数的循环可以转换为流:

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;
    }
}