问题描述
我正在尝试将以下代码转换为 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","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();
}
}
}
解决方法
可以使用 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","FALSE")));
印刷品:
Optional[flag = true]
,
您这样做的方式没有任何问题,而流对于此来说太过分了,而且效率可能较低。但是,我会提出两个建议:
- 不需要布尔值。比较失败后立即
return Optional.empty()
。否则,return Optional.of("flag = true")
在 for 循环之后。 - 您应该检查不相等的
List
大小。如果您为循环选择较长的循环,则可能会引发异常。您可以采用两种大小中的Math.min
,忽略比较中的额外元素,或者只检查列表大小是否相等,然后根据应用程序的列表相等性决定这意味着什么。
不幸的是,您不能使用流同时操作 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");
}
我希望这对您有所帮助,并让您有一个开始。
,您可以使用另一种可能的解决方案。它看起来像 python
zip
函数。
public class ComparisonString {
private static List<String> input;
public static void main(String[] args) {
input = Arrays.asList("TRUE","N/A");
ComparisonString cs = new ComparisonString();
System.out.println(cs.getMatchedOutput(
Arrays.asList("TRUE","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]
,
您可以使用 IntStream#noneMatch
方法简化代码,如下所示:
private static List<String> input;
public static void main(String[] args) {
input = Arrays.asList("TRUE","N/A");
System.out.println(
getMatchedOutput(Arrays.asList("TRUE","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();
}