Java 通过聚合和分组将一个对象映射到另一个对象

Java 通过聚合和分组将一个对象映射到另一个对象,java,java-8,java-stream,grouping,Java,Java 8,Java Stream,Grouping,通过聚合和分组将一个对象映射到另一个对象 我有一节课 class Q { String username; int taskId; double timediff; // constructor } 我需要把它转换成 class ToQ { String username; int noOfTasks; double sum; // constructor } 因此,强度是按用户名、Ta

通过聚合和分组将一个对象映射到另一个对象

我有一节课

class Q {
    String username;
    int taskId;
    double timediff;

   // constructor
}
我需要把它转换成

 class ToQ {
        String username;
        int noOfTasks;
        double sum;

       // constructor
    }
因此,强度是按用户名、TaskID计数、timediff之和分组的

此列表

List<Q> qs = new ArrayList<>();
    qs.add(new Q("tom", 2, 2.0));
    qs.add(new Q("tom", 6, 1.0));
    qs.add(new Q("harry", 8, 0.03));
我尝试使用分组函数,但它生成HashMap,但不确定如何转换为object

Map<String, Double> collect = qs
            .stream()
            .collect(groupingBy(Q::getUsername, summingDouble(Q::getLocalDateTime)));
Map collect=qs
.stream()
.collect(groupingBy(Q::getUsername,summingDouble(Q::getLocalDateTime));
这最好通过
toMap
收集器完成:

Collection<ToQ> values = qs.stream().collect(toMap(Q::getUsername,
            v -> new ToQ(v.getUsername(), 1, v.getTimediff()),
            (l, r) -> {
                l.setNoOfTasks(l.getNoOfTasks() + r.getNoOfTasks());
                l.setSum(l.getSum() + r.getSum());
                return l;
            })).values();
如果您希望继续使用
分组方式
,则可以按如下方式执行:

public ToQ(String username, int noOfTasks, double sum) {...}
List<ToQ> result = qs.stream()
                .collect(groupingBy(Q::getUsername))
                .values()
                .stream()
                .map(l -> new ToQ(l.get(0).getUsername(), l.size(), l.stream().mapToDouble(Q::getTimediff).sum()))
                .collect(toList());
List result=qs.stream()
.collect(分组方式(Q::getUsername))
.values()
.stream()
.map(l->newtoq(l.get(0).getUsername(),l.size(),l.stream().mapToDouble(Q::getTimediff.sum()))
.collect(toList());

您可以按如下方式执行:

public ToQ(String username, int noOfTasks, double sum) {...}
List<ToQ> result = qs.stream()
                .collect(groupingBy(Q::getUsername))
                .values()
                .stream()
                .map(l -> new ToQ(l.get(0).getUsername(), l.size(), l.stream().mapToDouble(Q::getTimediff).sum()))
                .collect(toList());
按TimeDiff的名称分组
简单的方法如下:将
toMap()
与merge函数一起使用

 Map<String, ToQ> map = qs.stream()
      .collect(toMap(Q::getUsername, q -> new ToQ(q.username, q.taskId, q.timediff), ToQ::merge));
 List<ToQ> toQList =  new ArrayList<>( map.values());
您也可以使用单衬里进行尝试:

List toQS=qs.stream()
.map(Q::getUserName)
.distinct()
.map(用户名->新ToQ(
用户名,
qs.stream()
.map(Q::getUserName)
.filter(用户名::等于)
.count(),
qs.stream()
.map(Q::getUserName)
.filter(q->Objects.equals(userName,q.getUserName()))
.mapToDouble(Q::getTimeDiff)
.sum()
))
.collect(toList())

我想知道“斯塔克”和“汤姆”之间的关系是什么?它们是一样的:-)我实际上想要最终输出作为集合。我会仔细检查你的答案。
List<ToQ> toQS = qs.stream().map(a -> 
        new ToQ(a.getUsername(), nameToCountMap.get(a.getUsername()), nameToTimeDiffSumMap.get(a.getUsername())))
        .collect(toList());
class ToQ {
    String username;
    long noOfTasks;
    double sum;
}

class Q {
    String username;
    int taskId;
    double timediff;
}
 Map<String, ToQ> map = qs.stream()
      .collect(toMap(Q::getUsername, q -> new ToQ(q.username, q.taskId, q.timediff), ToQ::merge));
 List<ToQ> toQList =  new ArrayList<>( map.values());
public ToQ merge(ToQ q){
     this.noOfTasks+=q.noOfTasks;
     this.sum+=q.sum;
     return this;
}
List<ToQ> toQS = qs.stream()
    .map(Q::getUserName)
    .distinct()
    .map(userName -> new ToQ(
        userName,
        qs.stream()
            .map(Q::getUserName)
            .filter(userName::equals)
            .count(),
        qs.stream()
            .map(Q::getUserName)
            .filter(q -> Objects.equals(userName, q.getUserName()))
            .mapToDouble(Q::getTimeDiff)
            .sum()
    ))
    .collect(toList())