在使用lambda的java8中使用双重条件的Foreach循环

时间:2017-12-04 22:42:42

标签: lambda java-8 java-stream

我练习了这个描述:

1122 produces a sum of 3 (1 + 2) because the first digit (1) matches the second digit and the third digit (2) matches the fourth digit.
1111 produces 4 because each digit (all 1) matches the next.
1234 produces 0 because no digit matches the next.
91212129 produces 9 because the only digit that matches the next one is the last digit, 9.

我写了以下代码:

String inputString = "1111"; // taking this number as example

int sum = 0;
for (int i = 0; i < inputString.length() - 1; i++) {
    if (inputString.charAt(i) == inputString.charAt(i + 1)) {
        sum += Integer.parseInt(String.valueOf(inputString.charAt(i)));
    }
    if (i + 2 == inputString.length() - 1) {
        if (inputString.charAt(i + 2) == inputString.charAt(0)) {
            sum += Integer.parseInt(String.valueOf(inputString.charAt(i + 2)));
        }
    }
}

sum的结果是4,这是正确的。

现在我尝试使用lambda在Java8中编写相同的文件,但我无法弄清楚如何在我的流中获取最后一个条件。

这是我走了多远:

Integer sum = IntStream.range(0, (inputString.length() - 1)).boxed()
                .filter(j -> inputString.charAt(j) == inputString.charAt(j + 1))
                .mapToInt(i -> Integer.parseInt(String.valueOf(inputString.charAt(i)))).sum();

3 个答案:

答案 0 :(得分:7)

如果您认为循环变量的模数为长度,那么最后一个条件实际上与其他条件相似:((length-1) + 1) % length == 0

int length = inputString.length();

IntStream.range(0, length)
  .filter(i -> inputString.charAt(i) == inputString.charAt((i + 1) % length))
  .map(i -> Integer.parseInt(String.valueOf(inputString.charAt(i))))
  .sum();

答案 1 :(得分:2)

就我的知识而言,这将使 真正凌乱的凌乱然而,我很喜欢这个挑战,而且我在这里是怎样的。 d做到:

首先,创建两个函数:

  1. charint的映射器功能,有助于减少我们不断重复的代码。
  2. 一个类似谓词的函数,用于验证两个给定字符是否相等;再次帮助减少我们不断重复的代码。
  3. 即:

    public static int mapper(String value, int index){
        return Integer.parseInt(String.valueOf(value.charAt(index)));
    }
    
    public static boolean areEqual(String inputString, int firstIndex, int secondIndex){
          return inputString.charAt(firstIndex) == inputString.charAt(secondIndex);
    }
    

    然后您可以通过执行以下任务来完成任务:

    int sum = IntStream.range(0, inputString.length() - 1)
                .map(i -> areEqual(inputString, i, i + 1) &&
                        i + 2 == inputString.length() - 1 &&
                        areEqual(inputString, i + 2, 0)?
                        mapper(inputString, i) + mapper(inputString, i + 2) :
                        areEqual(inputString, i , i + 1) &&
                                i + 2 != inputString.length() - 1 ?
                                mapper(inputString, i) :
                                i + 2 == inputString.length() - 1 &&
                                        areEqual(inputString,i + 2, 0) &&
                                        inputString.charAt(i) != inputString.charAt(i + 1) ?
                                        mapper(inputString, i + 2) :
                                        inputString.charAt(i) == inputString.charAt(i + 1) ?
                                                mapper(inputString, i) : 0
                )
                .sum();
    

    上述解决方案考虑了可以满足的所有可能条件,因此需要随后继续检查不同的条件。

    顺便说一句,你可能想要做的另一件事就是让inputString成为一个全局变量,你可以直接在两个辅助函数中使用它,这意味着我们可以摆脱它方法的inputString参数。

答案 2 :(得分:1)

好像我的非常复杂我之前的回答。考虑到这只是为了练习,那么你可以使用lambda语句块:

int sum1 = IntStream.range(0, inputString.length() - 1)
                .map(i -> {
                       int tempSum = 0;
                       if(areEqual(inputString, i, i + 1))
                             tempSum += mapper(inputString, i);

                       if (i + 2 == inputString.length() - 1)
                           if(areEqual(inputString, i + 2, 0))
                               tempSum += mapper(inputString, i + 2);

                       return tempSum;
                   }
                )
                .sum();

辅助函数:

public static int mapper(String value, int index){
    return Integer.parseInt(String.valueOf(value.charAt(index)));
}

public static boolean areEqual(String inputString, int firstIndex, int secondIndex){
      return inputString.charAt(firstIndex) == inputString.charAt(secondIndex);
}