当前位置: 首页 > 知识库问答 >
问题:

Lambda表达式返回null

况景龙
2023-03-14

我正在编写一个lambda表达式来将给定的纬度和经度转换为地址。表达式应该以坐标为参数,并返回其相应的地址。但是,返回的值为null。以下是我的班级:

public class LambdaDeclarations {

String loc;

private static final String TAG = "LambdaDeclarations";

public CoordinatesToAddressInterface convert = (latitude, longitude, context) -> {
    RequestQueue queue = Volley.newRequestQueue(context);

    Log.d(TAG, "onCreate: Requesting: Lat: "+latitude+" Lon: "+longitude);
    String url ="https://maps.googleapis.com/maps/api/distancematrix/json?units=metric&origins="+latitude+","+longitude+"&destinations="+latitude+","+longitude+"&key=AIzaSyCdKSW0glin4h9sGYa_3hj0L83zI0NsNRo";
    // Request a string response from the provided URL.
    StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
            (String response) -> {
                try {
                    JSONObject jsonObject = new JSONObject(response);
                    JSONArray destinations = jsonObject.getJSONArray("destination_addresses");
                    Log.d(TAG, "GETRequest: JSON Object: "+destinations.toString());
                    String location = destinations.toString();
                    Log.d(TAG, "Location: "+location);
                    setLocation(location);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }, error -> Log.d(TAG, "onErrorResponse: That didn't work!"));
    queue.add(stringRequest);
    return getLocation();
};


public String getLocation() {
    return loc;
}

public void setLocation(String location) {
    this.loc = location;
    }
}

以下是logcat的输出:

09-16 10:31:09.160 26525-26525/com.rmit.tejas.mad_foodtruck_2 D/LambdaDeclarations: GETRequest: JSON Object: ["77 State Route 32, West Melbourne VIC 3003, Australia"]
Location: ["77 State Route 32, West Melbourne VIC 3003, Australia"]
09-16 10:31:09.176 26525-26525/com.rmit.tejas.mad_foodtruck_2 D/LambdaDeclarations: GETRequest: JSON Object: ["111 Adderley St, West Melbourne VIC 3003, Australia"]
Location: ["111 Adderley St, West Melbourne VIC 3003, Australia"]
09-16 10:31:09.177 26525-26525/com.rmit.tejas.mad_foodtruck_2 D/LambdaDeclarations: GETRequest: JSON Object: ["4\/326 William St, Melbourne VIC 3000, Australia"]
Location: ["4\/326 William St, Melbourne VIC 3000, Australia"]

以下是我的用法:

myViewHolder.textView3.setText("Location: i->"+i+" add: "+l.convert.toAddress(trackingInfos.get(i).getLatitude(),trackingInfos.get(i).getLongitude(),context));

l是类lambdeclarations的对象,以下是相关接口:

public interface CoordinatesToAddressInterface {
String toAddress(double latitude, double longitude, Context context);
}

当我尝试从相关适配器打印坐标时,它们会正确打印。因此,位置正在正确设置,但是当我试图从另一个类访问它时,它会显示字符串的空值。你能建议一个替代方法来从表达式中提取位置吗?

共有1个答案

范兴文
2023-03-14

首先,Lambda表达式只是一个匿名类实现,它被设计为用作方法或类参数,并解决匿名类的隐藏问题
因此,在您的情况下,您根本不需要它,只需像往常一样将CoordinatesAddressInterface接口实现为命名类即可。

第二,您使用的截击错误,您提供给StringRequest的第一个lambda(下文将是call-response-callback)将在HTTP请求完成但返回语句

return getLocation();

在执行setLocation(location)之前,甚至在执行响应回调之前,都会立即返回null,这就是为什么每次调用convert()时都会返回null,尽管您仍然可以看到打印的日志,因为响应回调无论如何都会执行(假设请求成功)。

要正确使用响应回调,您必须在回调中更新UI,就像下面这样

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
public static final String TAG = "MyAdapter";
private RequestQueue mQueue;

public MyAdapter(Context context) {
    this.mQueue = Volley.newRequestQueue(context);
}

public RequestQueue getMyAdapterRequestQueue() {
    return this.mQueue;
}

    ...

@Override
public void onBindViewHolder(@NonNull final MyViewHolder holder, int position) {
    String url ="some url";

    StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
            (String response) -> {
                try {
                    JSONObject jsonObject = new JSONObject(response);
                    JSONArray destinations = jsonObject.getJSONArray("destination_addresses");
                    Log.d(TAG, "GETRequest: JSON Object: "+destinations.toString());
                    String location = destinations.toString();
                    Log.d(TAG, "Location: "+location);
                    // update UI
                    holder.mTextView.setText(location);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }, error -> Log.d(TAG, "onErrorResponse: That didn't work!"));

    stringRequest.setTag(TAG);
    mQueue.add(stringRequest);
}

当然,您可以编辑接口的方法签名并使适配器实现该接口(尽管我更愿意这样做),但关键是您必须在回调方法中处理异步结果,不要期望异步操作的回调在下一行代码之前完成。

RequestQueue不应该为每个请求创建,因为它管理内部状态,帮助您加快请求速度(缓存),您也可以在诸如电话轮换之类的事件中取消请求,您的请求将被销毁,在这种情况下,只需调用Activity/Fragment的onStop()中的cancel方法即可

@Override
protected void onStop () {
    super.onStop();
    if (myAdapter.getMyAdapterRequestQueue() != null) {
        myAdapter.getMyAdapterRequestQueue().cancelAll(MyAdapter.TAG);
    }
}

取消请求后将不会调用响应回调。

 类似资料:
  • 我有一个静态的通用FormBuilder超文本标记语言助手方法(HTMLHelper类上的扩展方法),它接受视图模型类型的通用参数,然后当从数据库传递一个或多个字符串属性名称时,生成一个超文本标记语言形式在ASP. NET MVC 5.1 with. NET 4.5中。 我有一个公共方法来生成表单,还有单独的私有方法来生成表单中的“模块”部分,然后渲染其中的每个字段。类型参数从上到下沿此链传递。

  • 问题内容: 我试图弄清楚如何从lambda表达式返回方法值: 但是,似乎在lambda表达式中使用关键字将显式返回lambda函数本身。是否有某种方式可以中断或强制返回整个方法? 问题答案: 是否有某种方式可以中断或强制返回整个方法? 不会。至少,除非抛出异常,否则不会。 基本上,这不是什么意思。您可以编写一个方法,该方法接受一个函数,该函数将返回“继续执行” ,而返回非null则表示“停止,并将

  • 将异常获取为 :lambda表达式中的返回类型错误:

  • 以下代码在IntelliJ和Eclipse中编译得很好,但JDK编译器1.8.0\u 25对此表示不满。首先,代码。 javac 1.8.0\u 25的输出为: 当我更换时?超级E只需使用E,JDK就能成功编译。 当我将替换为,JDK编译成功。 由于它适用于JDK 1.8.0_60,我怀疑它是编译器错误。 有没有详细说明是什么原因造成的以及何时修复的?

  • 我正在学习Java中的Lambda并试图理解它。例如,我有以下代码: 我不理解这个语句我看到是类型的引用变量。但是我不明白这个到底是什么。这是方法定义吗?这个方法的返回类型是什么?我认为应该是,因为方法的返回类型是。如有任何反馈将不胜感激。

  • (译注:目前支持lambda的gcc编译器版本为4.5,其它详细的编译器对于C++11新特性的支持请参考http://wiki.apache.org/stdcxx/C%2B%2B0xCompilerSupport) Lambda表达式是一种描述函数对象的机制,它的主要应用是描述某些具有简单行为的函数(译注:Lambda表达式也可以称为匿名函数,具有复杂行为的函数可以采用命名函数对象,当然,何谓复杂