Java 流式传输数组列表并与之前的记录进行比较

问题描述 投票:0回答:2

我有一个简单的 RecordA 类,它包含一个 id 和一个 int 值。多个“已排序”RecordA 元素存储在列表中。

我想遍历列表并将当前元素与前一个元素进行比较,并找到它们值的差异。

代码:

import java.util.*;  

class RecordA{
    Integer id;
    Integer value;
    
    RecordA(Integer id, Integer value) {
        this.id = id;
        this.value = value;
    }
    
    Integer getId() { return id;}
    Integer getValue() { return value;}
}

class RecordB {
    Integer id;
    Integer value;
    Integer diff;
    
    RecordB(Integer id, Integer value, Integer diff) {
        this.id = id;
        this.value = value;
        this.diff = diff;
    }
    
    Integer getId() { return id;}
    Integer getValue() { return value;}
    Integer getDiff() { return diff;}
}

class HelloWorld {
    public static void main(String[] args) {
        
        
        List<RecordA> listA = new ArrayList<>();
        RecordA recordA1 = new RecordA(1,10);
        listA.add(recordA1);
        RecordA recordA2 = new RecordA(2,15);
        listA.add(recordA2);
        RecordA recordA3 = new RecordA(3,25);
        listA.add(recordA3);
        RecordA recordA4 = new RecordA(4,30);
        listA.add(recordA4);
        
        System.out.println(listA.size());
    }
}

我想使用流(如果可能)将当前 RecordA.value 与先前的 RecordA.value 进行比较,将结果映射到具有相同 id 和值的 RecordB 中,但存储当前-上一个。

最后 RecordB 列表将包含

  • 1, 10, 0 //(10-0)
  • 2, 15, 5 //(15-10)
  • 3, 25, 10 //25-15
  • 4, 30, 5 //30-25

我想避免类 for 循环和 previous_val 变量。有什么想法如何使用流来做到这一点吗?

java dictionary java-8 stream
2个回答
1
投票

你可以使用 IntStream

IntStream.range(0, listA.size())
    .map(index -> 
        new RecordB(listA.get(index).getId(), listA.get(index).getValue(),  listA.get(index).getValue() - (index > 0 ? listA.get(index - 1).getValue() : 0))
    )
    .collect(Collectors.toList())
    

0
投票

“...我想避免类 for 循环和 previous_val 变量。有什么想法如何使用流来做到这一点吗?”

这是一种有点不直观的方法,我实际上必须查一下。
StackOverflow – 在 Foreach Lambda 中使用前一个元素的 Java 流

通常使用是为了聚合一组值,而不一定要比较和对比它们。
课程:聚合操作(Java™ 教程 > 集合)

这是一个使用 Collector 类和 Collector#of 方法的示例。

本质上,在收集过程中,您可以从已收集的内容中检索前一个元素。

对于 BiConsumer 参数,a 是迄今为止您收集的元素。

List<RecordB> l
    = listA.stream()
           .collect(
               Collector.<RecordA, List<RecordB>, List<RecordB>>of(
                   ArrayList::new,
                   (a, b) -> {
                       if (a.isEmpty()) a.add(new RecordB(b.id, b.value, 0));
                       else {
                           RecordB x = a.get(a.size() - 1);
                           a.add(new RecordB(b.id, b.value, b.value - x.value));
                       }
                   },
                   (a, b) -> {
                       a.addAll(b);
                       return a;
                   },
                   x -> x));

输出

1, 10, 0
2, 15, 5
3, 25, 10
4, 30, 5
© www.soinside.com 2019 - 2024. All rights reserved.