我有这个代码
List<Integer> numbers = new ArrayList<>(30, 25, 17, 12 ,8, 5, 3, 2));
List<Integer> indices = new ArrayList<>(5, 3, 2));
Integer newNumber = 1;
for (int i = indices.size() - 1; i >= 0; i--) {
newNumber *= (numbers.get(indices.get(i)));
}
newNumber
将为:5*12*17 = 1020
可以使用流减少吗?
稍后,我需要从原始数字中删除索引(我在过滤器中考虑过,但目标是索引而不是Integer对象)。
List<Integer> newNumbers = new ArrayList<>(numbers);
for (int i = indices.size() - 1; i >= 0; i--) {
newNumbers.remove(indices.get(i).intValue()); // Remove position
}
或者,我在考虑这段代码。
List<Integer> newNumbers2 = new ArrayList<>();
for (int i = 0; i < numbers.size(); i++) {
if (!indices.contains(i)) {
newNumbers2.add(numbers.get(i));
}
}
可以使用流吗?
谢谢。
答案 0 :(得分:2)
是的,您可以使用简单的归约法做到这一点。在这种情况下,减少量的标识元素为1。
int product = indices.stream().mapToInt(numbers::get).reduce(1, (n1, n2) -> n1 * n2);
后一个问题的答案是
Set<Integer> indicesSet = new HashSet<>(indices);
List<Integer> newNumbers = IntStream.range(0, numbers.size())
.filter(n -> !indicesSet.contains(n))
.mapToObj(n -> numbers.get(n))
.collect(Collectors.toList());
在数学中,恒等元素是a的一种特殊类型的元素 关于该集合上的二进制运算的集合,这将留下任何 集合中的元素与它组合在一起时保持不变。
答案 1 :(得分:0)
假设索引按相反顺序排序,则使用顺序流的两个操作的单个管道可能是:
int product = indices.stream().sequential()
.mapToInt(index -> numbers.remove((int) index))
.reduce(1, (a, b) -> a * b);
注意:此处使用List.remove
是为了从索引而不是对象中删除一个元素,然后转换为(int)
。
答案 2 :(得分:0)
要从具有列表索引的列表编号中删除索引。
List<Integer> newNumbers = numbers.stream().filter(num ->
!indices.contains(numbers.indexOf(num))
).collect(Collectors.toList());
答案 3 :(得分:0)
为防止整数溢出,我建议对乘法使用Math.multiplyExact()
。为了防止IndexOutOfBoundsException
,您应该先过滤索引:
int newNumber = indices.stream()
.filter(i -> i < numbers.size())
.mapToInt(numbers::get)
.reduce(Math::multiplyExact)
.orElseThrow();
如果您想将数字相乘,则应将它们映射为长值:
long nNumber = indices.stream()
.filter(i -> i < numbers.size())
.mapToLong(numbers::get)
.reduce(Math::multiplyExact)
.orElseThrow();
或者,orElseThrow()
可以使用orElse()
来返回空流的默认值。
要从numbers
数组中删除索引,可以使用以下方法:
indices.stream()
.filter(i -> i < numbers.size())
.sorted(Comparator.reverseOrder())
.mapToInt(i -> i)
.forEach(numbers::remove);