San
San

Reputation: 347

How to apply groupby->mapping->reducing in Java 8 stream

I am having List of below object.

public class Sample {
    private String driver;
    private String vehicle;
    private Double score;
    private Integer time;
}

My data would look like below.

enter image description here

I am trying to groupBy driver and then apply map function(mentioned in the above table) and then reduce to Map with key as driver and value as map function's result(which is of type Double). I have tried below

list.stream().collect(Collectors.groupingBy(o-> o.getDriverId(),
            Collectors.mapping()
            ));

But not able to apply the map function. Please give some inputs to proceed further.

Upvotes: 1

Views: 579

Answers (2)

ETO
ETO

Reputation: 7279

Try this:

Map<String, Double> res =
    list.stream()
        .collect(groupingBy(Sample::getDriver,
                            collectingAndThen(
                                reducing(new Sample("", "", 0.0,0),
                                         (a, b) -> new Sample("", "", a.score + b.score * b.time, a.time + b.time)), 
                                         s -> s.score / s.time)));

Upvotes: 2

iamgirdhar
iamgirdhar

Reputation: 1155

I hope this will help you for your problem statement.

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Test {
    public static void main(String[] args) {
        List<Sample> data = Arrays.asList(
        new Sample("D1","V1",1.0,10),
        new Sample("D1","V2",2.0,20),
        new Sample("D2","V3",3.0,30),
        new Sample("D2","V4",4.0,40));

        Map<String,Double> calculatedDataMapping = new HashMap<>();

        data.stream().collect(Collectors.groupingBy(Sample::getDriver)).forEach((k,v) -> {
            double value = 0.0;
           for(int i = 0 ; i < v.size()-1; i++){
               value = ((v.get(i).getScore() * v.get(i).getTime()) + (v.get(i+1).getScore() * v.get(i+1).getTime()))
                       / (v.get(i).getTime() + v.get(i + 1).getTime());
           }
           calculatedDataMapping.put(k,value);
        });
        System.out.println(calculatedDataMapping);
    }
}

Sample.java

public class Sample {

    private String driver;
    private String vehicle;
    private Double score;
    private Integer time;

    public Sample(String driver, String vehicle, Double score, Integer time) {
        this.driver = driver;
        this.vehicle = vehicle;
        this.score = score;
        this.time = time;
    }

    public String getDriver() {
        return driver;
    }

    public void setDriver(String driver) {
        this.driver = driver;
    }

    public String getVehicle() {
        return vehicle;
    }

    public void setVehicle(String vehicle) {
        this.vehicle = vehicle;
    }

    public Double getScore() {
        return score;
    }

    public void setScore(Double score) {
        this.score = score;
    }

    public Integer getTime() {
        return time;
    }

    public void setTime(Integer time) {
        this.time = time;
    }

    @Override
    public String toString() {
        return "Sample{" +
                "driver='" + driver + '\'' +
                ", vehicle='" + vehicle + '\'' +
                ", score=" + score +
                ", time=" + time +
                '}';
    }
}

Output

{D1=1.6666666666666667, D2=3.5714285714285716}

Thanks Girdhar

Upvotes: 0

Related Questions