Home  >  Article  >  Java streaming array list and comparing with previous record

Java streaming array list and comparing with previous record

WBOY
WBOYforward
2024-02-22 14:00:10670browse

php editor Yuzai brings you this issue of Java Q&A to discuss how to use streaming in Java to process array lists and compare them with previous records. Through this article, you will learn how to use Java's streaming capabilities to efficiently operate on array lists and compare them with previous records. Let's delve deeper into this topic and improve your understanding and skills of Java programming.

Question content

I have a simple recorda class that contains an id and an int value. Multiple "sorted" recorda elements are stored in a list.

I want to iterate through the list and compare the current element with the previous element and find the difference in their values.

Code:

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

I would like to use a stream (if possible) to compare the current recorda.value with the previous recorda.value, mapping the result into a recordb with the same id and value, but storing the current-previous one.

Finally, the recordb list will contain

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

I want to avoid class for loop and previous_val variable. Any ideas how to do this using streams?

Solution

You can use 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())

This is a slightly unintuitive approach and I actually had to look it up.
StackOverflow – Java Stream Using Previous Element in Foreach Lambda.

Typically, streams are used to aggregate a set of values, not necessarily to compare and contrast them.
Lesson: Aggregate Operations (The Java™ Tutorials > Collections).

This is an example using the Collector class and the Collector#of method.

Essentially, during collection, you retrieve the previous element from what has been collected.

For the BiConsumer parameter, a is the element collected so far.

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

Output

1, 10, 0
2, 15, 5
3, 25, 10
4, 30, 5

As a final note, you may want to get rid of the recordb class and just use Map.

Map<RecordA, Integer> m = new LinkedHashMap<>();
RecordA a, b;
m.put(a = listA.get(0), 0);
for (int i = 1, n = listA.size(); i < n; i++)
    m.put(b = listA.get(i), -a.value + (a = b).value);

The above is the detailed content of Java streaming array list and comparing with previous record. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete