有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么最终变量返回时没有内部类?

我想在Android中返回final{},但是ArrayList总是返回大小0。我在内部类中执行add(),但是返回日志比内部类日志快

我的代码:

public static ArrayList<SportsData> getSportsFavorite(){
    final ArrayList<SportsData> sportsDatas = new ArrayList<>();

    DBRequestData reqData = new DBRequestData();
    reqData.cmdId = CmdConst.DISCIPLINE_DATA.SELECT_ALL.ordinal();
    DisciplineCmd cmd = new DisciplineCmd();
    cmd.requestCmd(reqData, new OnDatabaseListener() {
        @Override
        public void onDBResponse(BaseCmd command) {
            if (command == null || command.getResponseData() == null) {
                return;
            }

            ArrayList<DisciplineTable> dbDisciplineList = command.getResponseData().disciplineTableList;
            if (dbDisciplineList == null) {
                return;
            }

            if(sportsFavoriteList.size() == 0) {
                init();
            }

            for (DisciplineTable disciplineData : dbDisciplineList){
                for (String favoriteCode : sportsFavoriteList){
                    String[] codeArr = favoriteCode.split("[|]");
                    String discCode = codeArr[0];
                    String compeCode = codeArr[1];

                    if(disciplineData.disciplineCode.equals(discCode) && disciplineData.competitionCode.equals(compeCode)){
                        int imgRes = SportsUtil.getSportsImgResource(disciplineData.disciplineCode, disciplineData.competitionCode);
                        sportsDatas.add(new SportsData(imgRes, disciplineData));
                        Log.e("SportsUtil", "inner Size : "+sportsDatas.size()); // RETURN SECOND -
                    }
                }
            }
        }
    });

    Log.e("SportsUtil", "Return Size : "+sportsDatas.size()); //RETURN FIRST
    return sportsDatas;
}

日志:

07-22 14:33:32.337      651-651/com.samsung.riowow.result E/SportsUtil﹕ Return Size : 0
07-22 14:33:32.347      651-651/com.samsung.riowow.result E/SportsUtil﹕ inner Size : 1
07-22 14:33:32.347      651-651/com.samsung.riowow.result E/SportsUtil﹕ inner Size : 2
07-22 14:33:32.347      651-651/com.samsung.riowow.result E/SportsUtil﹕ inner Size : 3
07-22 14:33:32.347      651-651/com.samsung.riowow.result E/SportsUtil﹕ inner Size : 4
07-22 14:33:32.347      651-651/com.samsung.riowow.result E/SportsUtil﹕ inner Size : 5

想要的结果是ArrayList大小是5。但始终返回ArrayList,其大小为0。请帮帮我:)谢谢



解决

如果你想知道这种情况的原因,请查看Florian Schaetz的答案

我的解决方案是,更改方法的返回类型并添加interface侦听器参数。请检查我的解决方案

首先,创建接口和方法,其中包含要返回的参数

public static interface SportsDataListener{
    public void onSportsDataResponse(ArrayList<SportsData> sportsDataList);
}

其次,将方法的返回类型更改为void并添加接口参数。而调用接口的方法返回

public static void getSportsFavorite(final SportsDataListener listener){
    final ArrayList<SportsData> sportsDatas = new ArrayList<>();
    DBRequestData reqData = new DBRequestData();
    reqData.cmdId = CmdConst.DISCIPLINE_DATA.SELECT_ALL.ordinal();
    DisciplineCmd cmd = new DisciplineCmd();
    cmd.requestCmd(reqData, new OnDatabaseListener() {
        @Override
        public void onDBResponse(BaseCmd command) {
            if (command == null || command.getResponseData() == null) {
                return;
            }

            ArrayList<DisciplineTable> dbDisciplineList = command.getResponseData().disciplineTableList;
            if (dbDisciplineList == null) {
                return;
            }

            if(sportsFavoriteList.size() == 0) {
                init();
            }

            for (DisciplineTable disciplineData : dbDisciplineList){
                for (String favoriteCode : sportsFavoriteList){
                    String[] codeArr = favoriteCode.split("[|]");
                    String discCode = codeArr[0];
                    String compeCode = codeArr[1];

                    if(disciplineData.disciplineCode.equals(discCode) && disciplineData.competitionCode.equals(compeCode)){
                        int imgRes = SportsUtil.getSportsImgResource(disciplineData.disciplineCode, disciplineData.competitionCode);
                        sportsDatas.add(new SportsData(imgRes, disciplineData));
                    }
                }
            }
            listener.onSportsDataResponse(sportsDatas);
        }
    });
}

最后,您可以使用

SportsUtil.getSportsFavorite(new SportsUtil.SportsDataListener() {
    @Override
    public void onSportsDataResponse(ArrayList<SportsData> sportsDataList) {
        //Some action you want to do. You can use parameter
    }
}

共 (5) 个答案

  1. # 1 楼答案

    您应该为getSportsFavorite()提供一个回调接口,该接口将数组列表作为参数,并在OnDatabaseListener方法完成时调用它

  2. # 2 楼答案

    你必须至少运行一次onDBResponse

    public static void main(String[] args) {
        final List<String> sportsDatas = new ArrayList<>();
        Commond commond = new Commond() {
            @Override
            public void onDBResponse() {
                sportsDatas.add("1");
                sportsDatas.add("2");
                sportsDatas.add("3");
            }
        };
        System.out.println(sportsDatas.size());
    
        commond.onDBResponse();
    
        System.out.println(sportsDatas.size());
        }
    }
    

    输出:

    0
    3
    
  3. # 3 楼答案

    我猜你的onDBResponse方法运行在不同的线程中。您正在修改该方法中的arraylist。因此,在本例中,在修改arraylist之前,将返回。它将始终为您提供大小为0的arraylist

  4. # 4 楼答案

    是的,问题是因为在方法返回数组列表后调用了onDBResponse()。你应该根据日志的顺序怀疑这一点

    解决方案

    假设您需要同步获取数组列表。就在你的cmd.requestCmd开始之前:

    final Object lock = new Object();
    

    然后在return sportsDatas;之前添加以下内容:

    synchronized(lock) {
        lock.wait();
    }
    

    onDBResponse()的末尾添加:

    synchronized(lock) {
        lock.notify();
    }
    

    基本上,现在您的方法将等待DB的响应,然后返回数组列表

    你需要捕捉中断异常,就这样! 希望有帮助!:)

  5. # 5 楼答案

    我觉得很不同步。您正在调用一个方法,并给它一个回调,该回调将在操作完成后调用,这里可能是在数据库返回后。主代码没有被阻止,而是执行一个,而另一个OnDatabaseListener在后台等待答案,因此您的方法返回原始列表,该列表会随着数据库答案的返回而突然增长