Java 8,使用另一个基于

时间:2019-05-07 02:02:21

标签: java java-8 java-stream reduce

我有这个代码

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));
  }
}

可以使用流吗?

谢谢。

4 个答案:

答案 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);