【问题标题】:Iterate through 2 lists at the same time同时遍历 2 个列表
【发布时间】:2021-04-13 15:46:04
【问题描述】:

我正在尝试将以下代码转换为 Java 8(使用流),但不确定如何使用流精确地遍历 2 个列表。

public class ComparisonString {
    private static List<String> input;

    public static void main(String[] args) {
        input = Arrays.asList("TRUE","FALSE","TRUE","N/A");
        ComparisonString cs = new ComparisonString();
        System.out.println(cs.getMatchedOutput(Arrays.asList("TRUE","N/A","N/A","FALSE")));

    }
    /**
     * Check whether the 'input' List and the 'givenInput' List match.
     * If a value is "N/A" in either lists then it means does-not-matter/don't-check-for-a-match-and-go-next
     * @param givenInput
     * @return
     */
    public Optional<String> getMatchedOutput(final List<String> givenInput) {
        boolean flag = true;
        for (int i = 0; i < givenInput.size(); i++) {
            if (this.input.get(i) != null
                    && !(this.input.get(i).equalsIgnoreCase("N/A")
                    || givenInput.get(i).equalsIgnoreCase("N/A"))
                    && !this.input.get(i).equalsIgnoreCase(givenInput.get(i))) {
                flag = false;
                break;
            }
        }
        if (flag) {
            return Optional.of("flag = true");
        } else {
            return Optional.empty();
        }
    }
}

【问题讨论】:

    标签: java for-loop java-8 iterator java-stream


    【解决方案1】:

    很遗憾,您不能使用流同时操作 2 个列表。您可以做的是使用迭代器。我试着写了一些代码,它应该看起来像这样:

    public static void streamTest(List<String> givenList) {
        List<String> testing = new ArrayList<>();
        IntStream.range(0, givenList.size())
                .parallel()
                .forEach(i -> {
                    if (input.get(i) != null
                            && !(input.get(i).equalsIgnoreCase("N/A")
                            || givenList.get(i).equalsIgnoreCase("N/A"))
                            && !input.get(i).equalsIgnoreCase(givenList.get(i)))
                        testing.add("false");
                });
        if (testing.isEmpty())
            System.out.println("flag = true");
        else
            System.out.println("flag = false");
    }
    

    我希望这对您有所帮助并给您一个开始。

    【讨论】:

      【解决方案2】:

      可以使用IntStream为两个列表生成索引流,然后过滤掉不相关的列表值并匹配剩余的值:

      public Optional<String> getMatchedOutput(final List<String> givenInput) {
          return IntStream.range(0, givenInput.size())
                   .filter(i -> null != input.get(i) && null != givenInput.get(i))
                   .filter(i -> !"N/A".equalsIgnoreCase(input.get(i)) && !"N/A".equalsIgnoreCase(givenInput.get(i)))
                   .allMatch(i -> input.get(i).equalsIgnoreCase(givenInput.get(i)))
              ? Optional.of("flag = true")
              : Optional.empty();
      }
      

      测试已知数据:

      input = Arrays.asList("TRUE","FALSE","TRUE","N/A");
      ComparisonString cs = new ComparisonString();
       System.out.println(cs.getMatchedOutput(Arrays.asList("TRUE","N/A","N/A","FALSE")));
      

      打印:

      Optional[flag = true]
      

      【讨论】:

        【解决方案3】:

        您可以使用另一种可能的解决方案。它看起来像 python zip 函数。

        public class ComparisonString {
            private static List<String> input;
        
            public static void main(String[] args) {
                input = Arrays.asList("TRUE", "FALSE", "TRUE", "N/A");
                ComparisonString cs = new ComparisonString();
                System.out.println(cs.getMatchedOutput(
                        Arrays.asList("TRUE", "N/A", "N/A", "FALSE")));
            }
        
            public Optional<String> getMatchedOutput(final List<String> givenInput) {
                boolean notFlag = IntStream.range(0, input.size())
                        // zip to new object
                        .mapToObj(i -> new Pair<>(input.get(i), givenInput.get(i)))
        
                        // stop when the false flag is found
                        .anyMatch(p -> {
                            String inputValue = p.getKey();
                            String givenValue = p.getValue();
        
                            // true breaks the stream
                            return inputValue != null
                                    && !("N/A".equalsIgnoreCase(inputValue)
                                    || "N/A".equalsIgnoreCase(givenValue))
                                    && !inputValue.equalsIgnoreCase(givenValue);
                        });
                if (!notFlag) {
                    return Optional.of("flag = true");
                } else {
                    return Optional.empty();
                }
            }
        }
        

        输出

        Optional[flag = true]
        

        【讨论】:

          【解决方案4】:

          您的操作方式没有任何问题,并且流对此来说是多余的,并且可能效率较低。不过,我会提出两个建议:

          • 不需要布尔值。在比较失败后立即return Optional.empty()。否则,return Optional.of("flag = true") 在 for 循环之后。
          • 您应该检查不相等的List 大小。如果您为循环选择较长的循环,它可能会引发异常。您可以采用两种大小的Math.min,忽略比较中的额外元素,或者只检查相等的列表大小并确定这对您的应用程序的列表相等性意味着什么。

          【讨论】:

            【解决方案5】:

            您可以使用IntStream#noneMatch 方法简化您的代码,如下所示:

            private static List<String> input;
            
            public static void main(String[] args) {
                input = Arrays.asList("TRUE", "FALSE", "TRUE", "N/A");
                System.out.println(
                        getMatchedOutput(Arrays.asList("TRUE", "N/A", "N/A", "FALSE")));
            }
            
            public static Optional<String> getMatchedOutput(final List<String> givenInput) {
                return IntStream.range(0, givenInput.size()).noneMatch(i ->
                        input.get(i) != null
                                && !(input.get(i).equalsIgnoreCase("N/A")
                                || givenInput.get(i).equalsIgnoreCase("N/A"))
                                && !input.get(i).equalsIgnoreCase(givenInput.get(i)))
                        ? Optional.of("flag = true") : Optional.empty();
            }
            

            另见:Filter HashMap based on multiple 'optional' conditions

            【讨论】:

              猜你喜欢
              • 2011-04-26
              • 2011-03-18
              • 1970-01-01
              • 1970-01-01
              • 2015-12-07
              • 2011-08-03
              • 2012-05-26
              • 2017-01-12
              • 2014-06-26
              相关资源
              最近更新 更多