繁体   English   中英

Java 从用于数据输入的对象列表中计算相同日期

[英]Java counting same date from a list of objects for data entry

我正在使用 Java 在 Android Studio 中制作一个应用程序,即从我的 RestApi 接收数据。 我在包含日期和金额的对象“付款”的列表中获取数据。

想法是添加同一日期的金额并将其放入图表的数据条目中,然后显示在应用程序上。 我正在使用 AnyChart 作为图表。

我不确定如何比较日期,然后从那里将特定日期的一个数据条目的数量加在一起。 目标是能够选择您希望呈现数据的时间间隔。 是否是最后一周、一个月、6 个月等。

付款class

public class Payment {

private String id;
private Long amount;
private Date date;
private String email;
private String name;

public Payment(String id, Long amount, Date date, String email, String name) {
    this.id = id;
    this.amount = amount;
    this.date = date;
    this.email = email;
    this.name = name;
}}

为了从应用程序调用我的后端,我使用 retrofit。 下面的代码是我想象的样子

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    AnyChartView anyChartView = (AnyChartView) findViewById(R.id.any_chart_view);


    List<DataEntry> seriesData = new ArrayList<>();
    Cartesian cartesian = AnyChart.line();

    Call<List<Payment>> call = RetrofitClient
            .getInstance()
            .getAPI()
            .getPayment(new PaymentRequest("30"));

    call.enqueue(new Callback<List<Payment>>() {
        @Override
        public void onResponse(@NonNull Call<List<Payment>> call,
                               @NonNull Response<List<Payment>> response) {

            List<Payment> payments = response.body();

            if (payments != null) {
                for (int i = 0; i < payments.size(); i++) {
                    // If the date of the next index in the list is //the same as current 
                      //date add the amount together.
                       //If not add a new data entry to seriesData //with date eg. 31/08 and 
                       //the total amount from that date
                }
            }
        }

        @Override
        public void onFailure(@NonNull Call<List<Payment>> call,
                              @NonNull Throwable t) {
            Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_LONG).show();
        }
    });

    cartesian.data(seriesData);
    anyChartView.setChart(cartesian);
}}

我似乎无法找到或谷歌解决上述问题,或者我走错了路。

我试过类似的东西

seriesData.add(new ValueDataEntry(payments.get(i).getDate().toString(),
                            payments.get(i).getAmount()));

但这会为列表中的每个索引创建一个新条目。 我遇到的解决方案似乎比较了包括时间在内的日期,但在这种情况下,我只需要日期,时间无关紧要,所以数据输入可能看起来像

seriesData.add(new ValueDataEntry("31/08", totaled amount from that date));

我希望以上内容有意义。

编辑:我想我错过了重要信息。 这是项目中唯一与时间无关的部分。 项目的其他部分需要日期和时间。 我已经注意到,并从 Date 更改为 LocalDateTime。

您可以将 hashmap 用于此逻辑。 使用日期作为键,金额作为值。

HashMap<String, Double> paymentMap = new HashMap<>();
if (paymentMap.contains(date)) {
    paymentMap.put(date, amount + paymentMap.get(date));
}
else {
    paymentMap.put(date, amount);
}

其他人则暗示使用 LocalDate 和 HashMap。 您还可以使用 LocalDate 作为 Map 中的键。 此外,如果您使用 TreeMap 而不是 HashMap,它将保持日期按升序排列(从最早日期到最晚日期)。 这是一个最小的例子:

import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class Payment {

    private final String id;
    private final Long amount;
    private final LocalDate date;
    private final String email;
    private final String name;

    public Payment(String id, Long amount, LocalDate date, String email, String name) {
        this.id = id;
        this.amount = amount;
        this.date = date;
        this.email = email;
        this.name = name;
    }

    public Long getAmount() {
        return amount;
    }

    public LocalDate getDate() {
        return date;
    }

    public static void main(String[] args) {
        List<Payment> payments = List.of(
                new Payment("1", 10L, LocalDate.of(2022, 9, 13), "foo@example.com", "name"),
                new Payment("2", 20L, LocalDate.of(2022, 9, 13), "foo@example.com", "name"),
                new Payment("3", 30L, LocalDate.of(2022, 9, 14), "foo@example.com", "name"),
                new Payment("4", 40L, LocalDate.of(2022, 9, 15), "foo@example.com", "name"),
                new Payment("5", 50L, LocalDate.of(2022, 9, 15), "foo@example.com", "name"));

        Map<LocalDate, Long> dailyTotals = new TreeMap<>();
        for (Payment payment : payments) {
            LocalDate date = payment.getDate();
            if (dailyTotals.containsKey(date)) {
                dailyTotals.put(date, payment.getAmount() + dailyTotals.get(date));
            } else {
                dailyTotals.put(date, payment.getAmount());
            }
        }
    }
}

最后, dailyTotals的值为

"2022-09-13" -> 30
"2022-09-14" -> 30
"2022-09-15" -> 90

最后,迭代/流过dailyTotals中的entrySet 并将它们添加到您的seriesData object。

dailyTotals.entrySet().stream()
            .map(entry -> new ValueDataEntry(entry.getKey().toString(), entry.getValue()))
            .forEach(seriesData::add);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM