Java实现多字段分组,多字段求和(上)

一 需求

以 name phone city三个字段为关键字,分组计算 area和money的和。

name

phone

city

area

money

tom

15687675434

北京

100

99.0

tom

15687675434

北京

50

49.0

tom

13654345654

上海

77

76.0

jerry

15976543454

苏州

30

69.0

erry

15976543454

苏州

40

99.0

二 算法分析

这里采用逐步求解的方法。

第一步:以 name phone city三个字段为分组字段,计算 area 的和,结果保存到list1。此时列表中的 money 字段为空。

第二步:以 name phone city三个字段为分组字段,计算 money 的和,结果保存到list2。此时列表中 area 字段为空。

第三步:将 list2 中的 money 拷贝到 list1 的 money 中去。

三 代码

package com.cakin.javademo;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* @ClassName: GroupManyToMany
* @Description: 多字段分组,多字段求和
* @Date: 2021/3/14
* @Author: cakin
*/
public class GroupManyToMany {
    /**
     * 功能描述:多字段分组,单字段求和 测试
     *
     * @author cakin
     * @date 2021/3/14
     * @param args 命令行
     */
    public static void main(String[] args) {
        List<Person> users = new ArrayList<>();
        users.add(new Person("tom", "15687675434", "北京", 100l,99.0));
        users.add(new Person("tom", "15687675434", "北京", 50l,49.0));
        users.add(new Person("tom", "13654345654", "上海", 77l,76.0));
        users.add(new Person("jerry", "15976543454", "苏州", 70l,69.0));
        users.add(new Person("jerry", "15976543454", "苏州", 100l,99.0));

        // 第一步:以 name phone city 三个字段为分组字段,计算 area 的和。
        List<Person> userList = new ArrayList<>();
        users.stream().collect(Collectors
                .groupingBy(user -> new Person(user.getName(), user.getPhone(), user.getCity()), Collectors.summarizingLong(user -> user.getArea())))
                .forEach((k, v) -> {
                    k.setArea(v.getSum());
                    userList.add(k);
                });

        // 第二步:以 name phone city 三个字段为分组字段,分组计算 money 的和。
        List<Person> userList1 = new ArrayList<>();
        users.stream().collect(Collectors
                .groupingBy(user -> new Person(user.getName(), user.getPhone(), user.getCity()), Collectors.summarizingDouble(user -> user.getMoney())))
                .forEach((k, v) -> {
                    k.setMoney(v.getSum());
                    userList1.add(k);
                });

        // 第三步:将 userList1 中的 money 拷贝到 userList中
        for (int i = 0; i < userList1.size(); i++) {
            userList.get(i).setMoney(userList1.get(i).getMoney());
        }

        for (Person person : userList) {
            System.out.println(person);
        }
    }
}

/**
* @ClassName: Person
* @Description: person类
* @Date: 2021/3/13
* @Author: cakin
*/
class Person {
    /**
     * 姓名
     */
    public String name;
    /**
     * 手机
     */
    public String phone;
    /**
     * 城市
     */
    public String city;
    /**
     * 房屋面积
     */
    public Long area;

    /**
     * 房屋总价
     */
    public Double money;

    public Person(String name, String phone, String city) {
        this.name = name;
        this.phone = phone;
        this.city = city;
    }

    public Person(String name, String phone, String city, Long area,Double money) {
        this.name = name;
        this.phone = phone;
        this.city = city;
        this.area = area;
        this.money = money;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public Long getArea() {
        return area;
    }

    public void setArea(Long area) {
        this.area = area;
    }

    public Double getMoney() {
        return money;
    }

    public void setMoney(Double money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", phone='" + phone + '\'' +
                ", city='" + city + '\'' +
                ", area=" + area +
                ", money=" + money +
                '}';
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, phone, city);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return Objects.equals(name, person.name) &&
                Objects.equals(phone, person.phone) &&
                Objects.equals(city, person.city) &&
                Objects.equals(area, person.area) &&
                Objects.equals(money, person.money);
    }
}

四 测试

User{name='tom', phone='15687675434', city='北京', area=150, money=148.0}
User{name='jerry', phone='15976543454', city='苏州', area=170, money=168.0}
User{name='tom', phone='13654345654', city='上海', area=77, money=76.0}

五 说明

该算法比较笨拙,如果有更多的字段求和,就不可行了,还有更好的算法,在下一篇再介绍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值