Java List <Object>大小

时间:2019-06-25 21:02:57

标签: java android arrays arraylist

我在Java android中有一个列表:

List<FirebaseData> GetListMap(String data){

    final List<FirebaseData> Elements = new ArrayList<>();

    FirebaseDatabase database = FirebaseDatabase.getInstance();

    mShiftReference = database.getReference("Map/Data/").child(data);

    mListener = mShiftReference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

            for (DataSnapshot child: dataSnapshot.getChildren()) {

                Elements.add(child.getValue(FirebaseData.class));
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            // Failed to read value
            Log.w("data", "Failed to read value.", error.toException());
        }
    });

    return Elements;
}

当我尝试提取数组的大小时,它返回0,例如:

int size = GetListMap("2019-06-24").size();

否则我无法吸引任何财产。

任何想法我在做什么错。

4 个答案:

答案 0 :(得分:3)

首先,我假设您的意思是int size = GetListMap("2019-06-24").size();(末尾的大小)。

第二,您正在为返回的值分配一个列表,此刻它是一个空列表。然后,您附加一个等待事件(数据更改)的侦听器,如果发生此事件,则只有这样,它才会向列表中添加元素。

基本上,除非发生数据更改事件,否则列表始终为空。您需要触发一个事件,然后检查列表,它应该更改其大小。

答案 1 :(得分:3)

由于监听器的异步特性,您要在Elements集合实际上从Firebase数据库获取数据之前返回。

如果要在异步代码完成后获取更新,则必须定义一个回调

List<FirebaseData> GetListMap(String data){

final List<FirebaseData> Elements = new ArrayList<>();

FirebaseDatabase database = FirebaseDatabase.getInstance();

mShiftReference = database.getReference("Map/Data/").child(data);

mListener = mShiftReference.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        System.out.println("About to fill Elements");
        for (DataSnapshot child: dataSnapshot.getChildren()) {

            Elements.add(child.getValue(FirebaseData.class));
        }
        System.out.println("Elements is filled");

    }

    @Override
    public void onCancelled(@NonNull DatabaseError error) {
        // Failed to read value
        Log.w("data", "Failed to read value.", error.toException());
    }
});
System.out.println("Returning Elements with size: " + Elements.size());
return Elements;
}
int x = GetListMap("...").size();
System.out.println("x: +" x);

``

该代码将导致以下输出:

  1. 返回大小为0的元素
  2. x:0
  3. 关于填充元素
  4. 元素已填充

在使用Java开发时,请 camelCase 作为方法和变量

答案 2 :(得分:1)

您将在Firebase添加完所有内容之前返回列表。您要为该函数创建接口方法。

在类中创建一个接口:

public interface Complete{
    void taskCompleted(List<FirebaseData> list);
}

然后将其分配给您的方法(由于接口将生成结果,因此现在返回void):

public void GetListMap(String data, Complete completeListener){

. . . .

mListener = mShiftReference.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        for (DataSnapshot child: dataSnapshot.getChildren()) {
            Elements.add(child.getValue(FirebaseData.class));
        }

        completeListener.taskComplete(Elements);
    }

    @Override
    public void onCancelled(@NonNull DatabaseError error) {
            completeListener.taskComplete(null);
        }
    });

}

使用方法:

GetListMap("data", new Complete() {
                    @Override
                    public void taskCompleted(List<FirebaseData> list) {
                        //do what you want with the list object
                    }
                });

答案 3 :(得分:0)

首先,您的GetListMap方法包含firebase数据库调用,该过程是异步调用。意味着您正在单独的线程上获取数据。因此,此调用下面的行在firebase进程查询响应之前执行。因此,不可能从包含异步函数的方法中获取返回值。

因此,要准确获取所需的内容,必须等待查询响应。

请参考以下代码以实现所需的功能。

// Avoiding return type with this method.
void GetListMap(String data){

    final List<FirebaseData> Elements = new ArrayList<>();

    FirebaseDatabase database = FirebaseDatabase.getInstance();

    mShiftReference = database.getReference("Map/Data/").child(data);

    mListener = mShiftReference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

            for (DataSnapshot child: dataSnapshot.getChildren()) {

                Elements.add(child.getValue(FirebaseData.class));
            }

            // Use below method to update data inside your views.
            // This method will only called once firebase query return response.
            updateUI(Elements); 
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            // Failed to read value
            Log.w("data", "Failed to read value.", error.toException());
        }
    });

    // Now this method is void so need to return any value.
    //return Elements;
}

updateUI(...)方法的示例。

void updateUI(List<FirebaseData> elements) {

   int size = elements.size();

}