我想确保列表中的所有数字都组合在一起。让我用例子解释一下:
{1, 1, 1, 2, 2} // OK, two distinct groups
{1, 1, 2, 2, 1, 1} // Bad, two groups with "1"
{1, 2, 3, 4} // OK, 4 distinct groups of size 1
{1, 1, 1, 1} // OK, 1 group
{3, 4, 3} // Bad, two groups with "3"
{99, -99, 99} // Bad, two groups with "99"
{} // OK, no groups
这是我获取流的方式:
IntStream.of(numbers)
...
现在我需要为“OK”示例传递或返回 true,并在“Bad”示例中抛出 AssertionError
或返回 false。我如何使用 Stream API 做到这一点?
这是我当前的解决方案,创建了额外的 Set
:
Set<Integer> previousNumbers = new HashSet<>();
IntStream.of(numbers)
.reduce(null, (previousNumber, currentNumber) -> {
if (currentNumber == previousNumber) {
assertThat(previousNumbers).doesNotContain(currentNumber);
previousNumbers.add(currentNumber);
}
return currentNumber;
}
);
最佳答案
使用我的免费 StreamEx图书馆:
IntStreamEx.of(numbers).boxed().runLengths().toMap();
如果有重复组,此代码将抛出 IllegalStateException
。
在这里runLengths()
使用的方法。它折叠相等的相邻元素,用 Map.Entry
替换它们,其中键是输入元素,值是重复次数。最后使用 toMap()
,它是 .collect(Collectors.toMap(Entry::getKey, Entry::getValue))
的快捷方式。我们使用的事实是 .toMap()
在键重复时抛出 IllegalStateException
(除非提供自定义 mergeFunction)。
作为成功执行的免费奖励,您将获得一个 map ,其中键是输入元素,值是系列的长度。
关于java - 检测流中的重复组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35220028/