You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java数组重复元素统计及Firebase实时数据库当日记录数查询问题

Java统计数组内重复元素出现次数实现方案

核心逻辑是通过哈希表存储元素与对应出现次数,示例代码如下:

import java.util.HashMap;
import java.util.Map;

public class ArrayDuplicateCount {
    public static void main(String[] args) {
        // 示例数组,可替换为任意类型数组
        String[] arr = {"a", "b", "a", "c", "b", "a", "d"};
        Map<String, Integer> countMap = new HashMap<>();

        for (String item : arr) {
            // 元素已存在则计数+1,不存在则初始化为1
            countMap.put(item, countMap.getOrDefault(item, 0) + 1);
        }

        // 遍历输出统计结果
        for (Map.Entry<String, Integer> entry : countMap.entrySet()) {
            System.out.printf("元素%s出现次数:%d%n", entry.getKey(), entry.getValue());
        }
    }
}

如果使用Java 8及以上版本,可以用流式写法简化代码:

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

Map<String, Long> countMap = Arrays.stream(arr)
    .collect(Collectors.groupingBy(item -> item, Collectors.counting()));
Firebase Realtime Database当日记录统计问题修复

问题根因

  • 版本兼容问题:LocalDate.now()仅支持Android API 26及以上系统,低版本设备上currDate为空,无法匹配日期
  • 统计逻辑错误:每次遍历子节点都会重新创建日期列表,只要列表中存在当日日期就直接将整个列表长度作为统计值,会把其他日期的条目也计入结果
  • 冗余操作:在循环内反复创建SimpleDateFormat实例,无意义消耗性能
  • 效率问题:全量拉取所有节点数据再过滤,数据量大时性能极差,可通过Firebase查询能力直接过滤符合条件的节点

方案1:修复现有遍历逻辑

private void fetchDataWaterCount() {
    String uid = firebaseAuth.getUid();
    if (uid == null) return;
    // 兼容所有Android版本的当日日期格式化
    SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
    String currDate = dateFormatter.format(new Date());
    int waterCount = 0;

    waterRef = FirebaseDatabase.getInstance().getReference("Users").child(uid).child("body").child("water");
    waterRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            if (snapshot.exists()) {
                for (DataSnapshot ds : snapshot.getChildren()) {
                    WaterModel waterModel = ds.getValue(WaterModel.class);
                    if (waterModel == null) continue;
                    long timeStamp = waterModel.getDate();
                    String itemDate = dateFormatter.format(new Date(timeStamp));
                    if (currDate.equals(itemDate)) {
                        waterCount++;
                    }
                }
                // 统计完成后统一更新UI
                updateWaterProgress(waterCount);
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            // 建议添加错误处理逻辑
        }
    });
}

// 单独抽取UI更新逻辑,避免代码冗余
private void updateWaterProgress(int waterCount) {
    progressBar.setMax(12);
    progressBar.setProgress(waterCount);
    progressBar.setSecondaryProgress(waterCount);
    if (waterCount >= 12) {
        textViewWaterCount.setText("Done");
        textViewWaterCount.setTextColor(getResources().getColor(R.color.colorGreen_900));
        progressBar.setProgressDrawable(getActivity().getDrawable(R.drawable.circut_progressbar_green));
    } else {
        textViewWaterCount.setText(String.valueOf(waterCount));
        progressBar.setProgressDrawable(getActivity().getDrawable(R.drawable.circut_progress_bar));
    }
}

方案2:优化查询效率(推荐)

直接通过时间戳范围查询,无需拉取全量数据,性能更高:

private void fetchDataWaterCountOptimized() {
    String uid = firebaseAuth.getUid();
    if (uid == null) return;

    // 计算今日0点和明日0点的时间戳
    Calendar calendar = Calendar.getInstance();
    // 今日0点
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    long startTime = calendar.getTimeInMillis();
    // 明日0点
    calendar.add(Calendar.DAY_OF_MONTH, 1);
    long endTime = calendar.getTimeInMillis();

    waterRef = FirebaseDatabase.getInstance().getReference("Users").child(uid).child("body").child("water");
    // 直接查询date字段在今日时间范围内的节点
    waterRef.orderByChild("date").startAt(startTime).endAt(endTime - 1)
        .addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                int waterCount = (int) snapshot.getChildrenCount();
                updateWaterProgress(waterCount);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                // 建议添加错误处理逻辑
            }
        });
}

内容的提问来源于stack exchange,提问作者Nikita Alekseev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 05:36:10