有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java8,流与另一个基于

我有这个密码

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

可以使用stream reduce吗

稍后,我需要从原始数字中删除索引(我在filter中考虑过,但目标是索引而不是整数对象)

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

是否可以使用stream来完成

谢谢


共 (4) 个答案

  1. # 1 楼答案

    假设索引按相反顺序排序,则使用顺序流的两个操作的单个管道可以是:

    int product = indices.stream().sequential()
            .mapToInt(index -> numbers.remove((int) index))
            .reduce(1, (a, b) -> a * b);
    

    注意:这里使用^{}是指从索引而不是对象中删除元素,从而强制转换为(int)

  2. # 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());
    

    In mathematics, an identity element is a special type of element of a set with respect to a binary operation on that set, which leaves any element of the set unchanged when combined with it.

  3. # 3 楼答案

    为了防止int溢出,我建议对乘法使用^{}。要防止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);
    
  4. # 4 楼答案

    从具有列表索引的列表编号中删除索引

    List<Integer> newNumbers = numbers.stream().filter(num ->           
                !indices.contains(numbers.indexOf(num)) 
        ).collect(Collectors.toList());