有 Java 编程相关的问题?

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

Java递归按值/引用传递

在PHP工作两年后,我将重返Java。 抱歉,如果这看起来很愚蠢:

这是代码(图的深度优先遍历):

public List<List<Edge>> paths = new ArrayList<>();

public void traverse(Edge edge, List<Edge> currentPath){
    String vertex = graph.getEdgeTarget(edge);
    if(edge!=null) currentPath.add(edge);
    if(vertex=="TARGET_VERTEX"){
        System.out.println(currentPath);  // prints fine

        paths.add(currentPath); // elements are empty at end of reccursion

        if(edge!=null) currentPath.remove(edge);
        return;
    }
    for(Edge e : graph.outgoingEdgesOf(vertex)){
        traverse(e, currentPath);
    }
    if(edge!=null) path.remove(edge);
}

public void search(){
    //graph is initalized, vertices and edges are added

    for(Edge e : graph.outgoingEdgesOf("START_VERTEX")){
        traverse(e, new ArrayList<Edge>());
    }
    System.out.println("############################");
    System.out.println(paths);
    System.out.println(paths.size());
}

有人能解释为什么在递归结束时paths有空元素,以及如何让它包含我需要的路径吗
似乎通过参考资料传递给我带来了麻烦

ArrayList有一个浅clone()方法,它不会复制元素(根据JavaDoc)
我是否需要创建一个临时变量,它将是currentPath(遍历这些值)的手动复制

我仍然对Java中的按值传递和按引用传递有点困惑,在PHP中,通过使用按引用传递(&variable)很容易区分这两种方式

已编辑,因此我不会收到关于字符串比较的投诉


共 (2) 个答案

  1. # 1 楼答案

    if(edge!=null) currentPath.remove(edge);删除List的元素

    这可能会导致您的问题,因为currentPath是递归的

    在一个不相关的问题上,你将String==进行比较,而不是使用equals,这是一种不好的做法。(更多解释请参见here

  2. # 2 楼答案

    这两条线导致了问题:

          paths.add(currentPath);
          currentPath.remove(edge);
    

    currentPath添加到paths时,它会添加currentPath的引用。最后,currentPath是空的,因此paths留下了空引用

    为避免此问题,请创建currentPath的副本,并将副本添加到paths

    同时更新以下行:

     if(vertex=="TARGET_VERTEX"){
    

    作为

      if("TARGET_VERTEX".equals(vertex)){
    

    使用正确的字符串相等性检查并避免NullPointerException

    如果你想在检查时忽略这个案例,那么使用equalsIgnoreCase()方法