Java 在2D ArrayList Android中从实时数据库检索字符串

Java 在2D ArrayList Android中从实时数据库检索字符串,java,android,firebase,firebase-realtime-database,Java,Android,Firebase,Firebase Realtime Database,我有一个Firebase实时数据库结构,如下所示: 如何使用Java将其检索到像这样的2D ArrayList中 private String mChoices [][] = { {"Mutare", "Harare", "Bulawayo","Mozambique"}, {"Johhannesburg", "Pretoria", "

我有一个Firebase实时数据库结构,如下所示:

如何使用Java将其检索到像这样的2D ArrayList中

private String mChoices [][] = {
        {"Mutare", "Harare", "Bulawayo","Mozambique"},
        {"Johhannesburg", "Pretoria", "Duran","Capetown"},
        {"Nairobi", "Lusaka", "Windhoek","Lilongwe"},
        {"Harare", "Lilongwe", "Pretoria","Nairobi"}
};

您要求使用2D数组,这使得代码更加复杂,因为数组不是动态的。考虑到firebase数据是动态的,以及Java中数组列表的一般便利性,我建议您使用ArrayList。 这个解决方案的重点是问题所在——一个二维数组

private String[][] mChoices;
private void initializeMChoices(int i, int j) {
    mChoices = new String[i][j];
}
无论何时需要用字符串值填充数组,请粘贴以下代码:

        //Get the reference to the "choices" node:
        DatabaseReference ref = FirebaseDatabase.getInstance().getReference("choices");
        ref.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                // We first go through the whole node to count it's child nodes
                int i = 0, j = 0;
                while(snapshot.child(Integer.toString(i)).exists())
                {
                    j = 0;
                    while(snapshot.child(Integer.toString(i)).child(Integer.toString(i)).exists())
                    {
                        j++;
                    }
                    i++;
                }
                // we have the numbers, now we initialize the array
                initializeMChoices(i, j);
            //we go through the whole node to put child-node values in the 2D array
            i = 0;
            j = 0;
            while(snapshot.child(Integer.toString(i)).exists())
            {
                while(snapshot.child(Integer.toString(i)).child(Integer.toString(i)).exists())
                {
                    j++;
                    mChoices[i][j] = snapshot.child(Integer.toString(i)).child(Integer.toString(i)).toString();
                }
                i++;
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {

        }
    });

正如@SardorbekKhujaev在回答中提到的,数组是固定的数据类型。为了解决这个问题,我们需要使用ArrayList,因为它的大小可以动态增加。填充ArrayList后,我们可以简单地将其转换为2D数组,如以下代码行所示:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference choicesRef = rootRef.child("choices");
ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        List<String[]> choices = new ArrayList<>();
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            int size = (int) ds.getChildrenCount();
            String[] choice = new String[size];
            int count = 0;
            for(DataSnapshot dSnapshot : ds.getChildren()) {
                choice[count++] = dSnapshot.getValue(String.class);
            }
            choices.add(choice);
        }
        String choicesArray[][] = new String[choices.size()][];
        for (int j = 0; j < choices.size(); j++) {
            choicesArray[j] = choices.get(j);
        }
        //Test the array
        for(String[] array : choicesArray) {
            Log.d(TAG, Arrays.toString(array));
        }
        //Do what you need to do with your 2D array
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        Log.d("TAG", databaseError.getMessage()); //Don't ignore potential errors!
    }
};
choicesRef.addListenerForSingleValueEvent(valueEventListener);
DatabaseReference rootRef=FirebaseDatabase.getInstance().getReference();
DatabaseReference choicesRef=rootRef.child(“选项”);
ValueEventListener ValueEventListener=新的ValueEventListener(){
@凌驾
公共void onDataChange(DataSnapshot DataSnapshot){
列表选项=新建ArrayList();
对于(DataSnapshot ds:DataSnapshot.getChildren()){
int size=(int)ds.getChildrenCount();
字符串[]选项=新字符串[大小];
整数计数=0;
对于(DataSnapshot dSnapshot:ds.getChildren()){
选项[count++]=dSnapshot.getValue(String.class);
}
选择。添加(选择);
}
String choicesArray[][]=新字符串[choices.size()][];
对于(int j=0;j

此代码的结果将与您要查找的2D数组完全相同。

您确定他们正在按字母顺序接收数据吗?据我所知,firebase默认情况下会按数据在数据库中存在的顺序发送数据。我注意到我所犯的错误,我改变了问题第一个数组应该是
Mutare,Harare,Bulawayo,Mozibo
第一个节点的所有子节点或
Mutare,约翰内斯堡,内罗毕,Harare
,每个元素在特定索引处?请回复@AlexMamo@AlexMamo为了清楚起见,我对问题进行了编辑,请检查并回答help@TinovimbaMawoyo哦,现在更清楚了。还有一个问题。数组的数量和数组中元素的数量将始终是4和4?如何使用ArrayList,我认为它们是最完美的ones@AlexMamo提供了一个实现ArrayList的代码段。我想现在你的问题已经解决了,我和亚历克斯的答案都被认为是正确的。我看到亚历克斯半小时前对这个问题进行了复述,以使它大体上有用。