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

数组返回零,需使用多维数组但不知用法,附Firebase数据获取代码求助

问题1:ArrayList返回值为零的原因及解决办法

你遇到的这个问题,大概率是Firebase数据库操作的异步特性导致的。addChildEventListener里的onChildAdded方法是在数据从Firebase服务器获取完成后才会回调执行的,而你如果在调用dbQuery.addChildEventListener(...)之后立刻去访问weather数组的话,此时回调还没触发,数组自然是空的。

举个反例,如果你原来的代码是这样的:

List<model> weather = new ArrayList<model>();
Query dbQuery = FirebaseDatabase.getInstance().getReference().child("NeuralNetwork");
dbQuery.addChildEventListener(new ChildEventListener() {
    @Override
    public void onChildAdded(DataSnapshot dataSnapshot, String s) {
        model m = dataSnapshot.getValue(model.class);
        weather.add(m); // 这里才会往数组里加数据
    }
    // 其他重写方法省略...
});
// 这里立刻打印size,肯定是0,因为onChildAdded还没执行
Log.d("TAG", weather.size() + "");

解决办法很直接:所有需要使用weather数组的逻辑,都要放在onChildAdded回调里面(或者回调触发之后)。比如你要处理数据、更新UI,都得在回调里做:

@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
    model m = dataSnapshot.getValue(model.class);
    weather.add(m);
    // 在这里处理数据,比如转换成多维数组,或者更新UI
    processWeatherData(weather);
    updateWeatherUI(weather);
}

如果你的业务逻辑需要在所有子节点都加载完成后再处理,可以改用addListenerForSingleValueEvent的onDataChange方法,它会一次性获取所有数据:

dbQuery.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
            model m = childSnapshot.getValue(model.class);
            weather.add(m);
        }
        // 所有数据都加载完了,这里可以放心使用weather数组
        convertToMultiDimensionalArray(weather);
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        // 记得处理数据库请求失败的情况
        Log.e("TAG", "数据获取失败:" + databaseError.getMessage());
    }
});

另外还要注意:你的model类字段要和Firebase数据库里的键完全匹配(大小写敏感),否则getValue(model.class)会解析失败,也会导致数组为空。


问题2:多维数组的使用方法

结合你的需求,你需要把每个model里的previous、humidity、temperature、wind这些数值存到多维数组里。多维数组可以理解为“数组的数组”,比如int[][]类型,每个子数组对应一个model的四个参数。

方法1:使用原生二维数组(固定长度)

如果能提前知道数据总条数(可以通过dataSnapshot.getChildrenCount()获取),可以直接初始化固定长度的二维数组:

@Override
public void onDataChange(DataSnapshot dataSnapshot) {
    int dataCount = (int) dataSnapshot.getChildrenCount();
    // 每行存4个参数:previous、humidity、temperature、wind
    int[][] weatherMultiArray = new int[dataCount][4];
    int currentIndex = 0;
    
    for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
        model m = childSnapshot.getValue(model.class);
        weatherMultiArray[currentIndex][0] = m.getPrevious();
        weatherMultiArray[currentIndex][1] = m.getHumidity();
        weatherMultiArray[currentIndex][2] = m.getTemperature();
        weatherMultiArray[currentIndex][3] = m.getWind();
        currentIndex++;
    }
    
    // 现在就可以使用这个多维数组了,比如打印第一组数据
    Log.d("TAG", "第一组数据:" + weatherMultiArray[0][0] + ", " + weatherMultiArray[0][1] + ", " + weatherMultiArray[0][2] + ", " + weatherMultiArray[0][3]);
}

方法2:使用ArrayList<int[]>(动态长度)

如果不确定数据条数,或者需要动态添加数据,用ArrayList<int[]>会更灵活,不需要提前指定长度:

// 先在回调外声明这个列表
List<int[]> weatherMultiList = new ArrayList<>();

@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
    model m = dataSnapshot.getValue(model.class);
    int[] singleWeatherData = new int[4];
    singleWeatherData[0] = m.getPrevious();
    singleWeatherData[1] = m.getHumidity();
    singleWeatherData[2] = m.getTemperature();
    singleWeatherData[3] = m.getWind();
    
    weatherMultiList.add(singleWeatherData);
    // 每次添加后都可以使用这个列表,比如打印当前数据条数
    Log.d("TAG", "当前累计数据条数:" + weatherMultiList.size());
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:37:19