简体   繁体   English

如何访问(修改、添加元素)到 Java 内部类中的 ArrayList/Collection?

[英]How to access (modify, add elements) to an ArrayList/Collection in an Inner class in java?

I've got this search function to search for specific Users using a firebase Database using GeoFire.我有这个搜索功能,可以使用 GeoFire 使用 firebase 数据库搜索特定用户。

What i want to do :我想做的事 :

In GeoQueryEventListener() & onKeyEntered , I want to add each key found to an ArrayList (outside onKeyEntered() ).GeoQueryEventListener() & onKeyEntered ,我想将找到的每个键添加到 ArrayList (在onKeyEntered()之外)。

The problem i have :我遇到的问题:

When I print it inside the onKeyEntered() , it works.当我在onKeyEntered()打印它时,它可以工作。 But as soon as I exit the GeoQueryEventListener() , keysGeolocated is empty但是一旦我退出GeoQueryEventListener()keysGeolocated就为空

public ArrayList<User> search(GeoFire geoFire, int day, final boolean isBartender, double latitude, double longitude, double radius, double rate, double nightlyRate, double hourlyRate, final String speciality){

    keysGeolocated = new ArrayList<>();
    FirebaseDatabase database = FirebaseDatabase.getInstance();
    root = database.getReference();
    DatabaseReference usersRef = root.child("Users");

    GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(latitude, longitude), radius);
    geoQuery.addGeoQueryEventListener(new MyGeoListener(keysGeolocated));

    System.out.println("KEYS GEOLOCATED" + keysGeolocated);

    final ArrayList<User> result = new ArrayList<>();

    for(String key : keysGeolocated){

        Query queryByLocation = usersRef.orderByKey().equalTo(key);
        DatabaseReference refToLocationQuery = queryByLocation.getRef();

        if(checkRefNull(refToLocationQuery) == true) {
            System.out.println("QUERY BY LOCATION NULL");
            continue;
        }

        Query queryByTypeOfUser  = refToLocationQuery.orderByChild("isBarTender").equalTo(isBartender);
        DatabaseReference refToTypeOfUserQuery = queryByTypeOfUser.getRef();

        if(checkRefNull(refToTypeOfUserQuery) == true) {
            System.out.println("QUERY BY TYPE NULL");
            continue;
        }
        Query queryByRate  = refToTypeOfUserQuery.orderByChild("rate").startAt(rate);
        DatabaseReference refToRateQuery = queryByRate.getRef();

        if(checkRefNull(refToRateQuery) == true) {
            System.out.println("QUERY BY RATE NULL");
            continue;
        }

        DatabaseReference finalRef = null;

        if(isBartender == true){

            if(nightlyRate == 0){
                Query queryByPrice  = refToRateQuery.orderByChild("nightlyRate").endAt(nightlyRate);
                finalRef = queryByPrice.getRef();
            }
            else if(hourlyRate == 0){
                Query queryByPrice  = refToRateQuery.orderByChild("hourlyRate").endAt(hourlyRate);
                finalRef = queryByPrice.getRef();
            }

            //TODO Impelement checks for available dates

        }
        else{
            finalRef = refToRateQuery;
        }

        finalRef.addValueEventListener(new ValueEventListener() {

            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                if(dataSnapshot.getValue()!=null){

                    User userFound = dataSnapshot.getValue(User.class);

                    if(isBartender == true){
                        Bartender barTenderFound = (Bartender) userFound;
                        if(speciality != null){
                            if(barTenderFound.getSpeciality().contains(speciality)){
                                result.add(barTenderFound);
                            }
                        }
                        else{
                            result.add(barTenderFound);
                        }
                    }
                    else{
                        result.add(userFound);
                    }
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });

    }

    return result;
}

public boolean checkRefNull(DatabaseReference ref){

    final boolean[] result = new boolean[1];
    result[0] = false;

        ref.addValueEventListener(new ValueEventListener() {


            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                System.out.println("TEST1");
                if(dataSnapshot.getValue()==null){
                    result[0] = true;
                    System.out.println("TESTTEST");
                }
                else{
                    System.out.println("TESTTEST TRUE" + dataSnapshot.getValue());
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
    });

    return result[0];
}

public void setBarTender(boolean barTender){

    this.barTender = barTender;
}
}

class MyGeoListener implements GeoQueryEventListener {

private ArrayList<String> keysGeolocated;

MyGeoListener(ArrayList<String> keysGeolocated){
    this.keysGeolocated = keysGeolocated;
}

@Override
public void onKeyEntered(String key, GeoLocation location) {
    keysGeolocated.add(key);
}

@Override
public void onKeyExited(String key) {

}

@Override
public void onKeyMoved(String key, GeoLocation location) {

}

@Override
public void onGeoQueryReady() {

}

@Override
public void onGeoQueryError(DatabaseError error) {

}
}

Make a Class which extends that listener and override all the methods创建一个扩展该侦听器并覆盖所有方法的类

class MyGeoListener extends GeoQueryEventListener{

    private ArrayList<String> keysGeolocated;

    MyGeoListener(ArrayList<String> keysGeolocated){
          this.keysGeolocated = keysGeolocated;
    }

    @Override
    public void onKeyEntered(String key, GeoLocation location) {
        keysGeolocated.add(key);
        System.out.println("1111111111 : "+keysGeolocated);
        System.out.println("2222222222 : "+key);
    }

    @Override
    public void onKeyExited(String key) {

    }

    @Override
    public void onKeyMoved(String key, GeoLocation location) {

    }

    @Override
    public void onGeoQueryReady() {

    }

    @Override
    public void onGeoQueryError(DatabaseError error) {

    }
}

Now use this class as follows:现在使用这个类如下:

geoQuery.addGeoQueryEventListener(new MyGeoListener(keysGeolocated));

The immediate next call will always print no values in the list as the listener is asynchronous and takes time to fill the list.由于侦听器是异步的并且需要时间来填充列表,因此立即下一次调用将始终在列表中不打印任何值。

Try putting the print inside a handler postdelayed with say 30000 milliseconds delay.尝试将打印内容放入延迟时间为 30000 毫秒的延迟处理程序中。 You will probably see entries in the list as by then the listener events should have fired.您可能会在列表中看到条目,因为那时监听器事件应该已经触发。

Since an arraylist is mutable and you are passing it's reference, the arraylist in the argument will also be modified when the listener calls.由于 arraylist 是可变的,并且您正在传递它的引用,因此当侦听器调用时,参数中的 arraylist 也将被修改。

Good luck and let me know if you still have issues.祝你好运,如果你还有问题,请告诉我。

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

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