• 请不要在回答技术问题时复制粘贴 AI 生成的内容
buptlee
V2EX  ›  程序员

关于 java 的传址和传值

  •  1
     
  •   buptlee ·
    Xiaoxin2009 · Sep 2, 2014 · 4787 views
    This topic created in 4307 days ago, the information mentioned may be changed or developed.
    我写了一个函数:
    public void updateDistMatrix(HashMap<Integer ,LinkedList<Node> > dist_matrix,ArrayList<Integer> nearestNodePair,HashMap<Integer,ArrayList<Integer>> clusterSet)
    {
    doSomething(dist_matrix);
    doSomething(clusterSet);
    }
    函数是要对传进去的两个参数dist_matrix和clusterSet进行更新,外层是一个循环,不断的调用updateDistMatrix()这个函数,以达到不断更新dist_matrix,clusterSet这两个变量的目的。
    但是,我发现,函数里对这两个变量的修改并不能保留到下次迭代,也就是说,下次迭代时,这两个变量的值依然是它们的初始值,我想问下大家,如果我想实现类似于c++的传址(参数)的效果,应该怎么做呢,将dist_matrix,clusterSet在main()前面声明成public static 类型的可以吗?
    大神们,教教我。
    Supplement 1  ·  Sep 2, 2014
    public void updateDistMatrix(HashMap<Integer ,LinkedList<Node> > dist_matrix,ArrayList<Integer> nearestNodePair,HashMap<Integer,ArrayList<Integer>> clusterSet){
    Integer user1 = nearestNodePair.get(0);
    Integer user2 = nearestNodePair.get(1);
    ArrayList<Integer> set1 = clusterSet.get(user1);
    ArrayList<Integer> set2 = clusterSet.get(user2);
    set1.addAll(set2);
    clusterSet.remove(user2);
    clusterSet.put(user1, set1);

    LinkedList<Node> list1 = dist_matrix.get(user1);
    LinkedList<Node> list2 = dist_matrix.get(user2);
    LinkedList<Node> newList = mergeSort(list1,list2,nearestNodePair);

    dist_matrix.remove(user1);
    dist_matrix.remove(user2);
    dist_matrix.put(user1, newList);

    Iterator<Integer> iter = dist_matrix.keySet().iterator();
    while (iter.hasNext()) {
    Integer key = iter.next();
    LinkedList<Node> value = dist_matrix.get(key);
    ArrayList<Node> occurence = new ArrayList<Node>();
    int occurIndex = 0;
    for(Node node : value){
    if(nearestNodePair.get(0)==node.getImsi() || nearestNodePair.get(1)==node.getImsi()){
    occurence.add(occurIndex,node);
    occurIndex++;

    }
    }
    if(occurence.size() == 0){
    continue;
    }
    if(occurence.size() == 1){
    Node node = occurence.get(0);
    if(node.getImsi()==user1){
    continue;
    }
    else{
    value.remove(node);
    node.setImsi(user1);
    int mid = findIndex(value,node.getDist());
    value.add(mid, node);
    dist_matrix.put(key, value);
    }
    }
    if(occurence.size() == 2){
    value.remove(occurence.get(1));
    Node node = occurence.get(0);
    if(node.getImsi()==user1){
    continue;
    }
    else{
    value.remove(node);
    node.setImsi(user1);
    int mid = findIndex(value,node.getDist());
    value.add(mid, node);
    dist_matrix.put(key, value);
    }
    }
    }
    }
    }
    class Node{
    Integer imsi;
    Integer dist;
    }
    15 replies    2014-09-02 11:37:29 +08:00
    yufz
        1
    yufz  
       Sep 2, 2014   ❤️ 1
    不知道你方法体里怎么操作的,java中除了几种基本数据类型之外都是传引用的。
    buptlee
        2
    buptlee  
    OP
       Sep 2, 2014
    @jinyang656
    程序里面就是对dist_matrix和clusterSet进行一些修改。
    传递引用的意思是不是,传递实参的一个副本,因此对实参的修改不会反应到传进去的参数上?
    那如果我希望这种修改能保留,应该怎么做?就像c++的传址那样。thanks.
    chocotan
        3
    chocotan  
       Sep 2, 2014   ❤️ 1
    难道楼主在doSomething里这样了.... dist_matrix=new XXX...
    shuson
        4
    shuson  
       Sep 2, 2014   ❤️ 1
    main() 声明static没用吧。
    试试update后return一下?
    Aegwynn
        5
    Aegwynn  
       Sep 2, 2014   ❤️ 1
    java根本没有传址的说法,这个是人们从C那边搬过来的概念。

    java里面只有传值,不同在于:对基本数据类型,值就是它自身的值;其他是传引用的值。

    想要改变对象的值,就不要去改变它的引用即可。
    defaultuser
        6
    defaultuser  
       Sep 2, 2014   ❤️ 1
    @Aegwynn 说的对
    buptlee
        7
    buptlee  
    OP
       Sep 2, 2014
    @chocotan 没有,就是拿出dist_matrix里面的某些键值对做了修改,然后重新插入到dist_matrix里面。
    buptlee
        8
    buptlee  
    OP
       Sep 2, 2014
    @shuson 可是我有两个实参变量啊。两个都要改变,不能return两个变量吧,毕竟不是Python。
    buptlee
        9
    buptlee  
    OP
       Sep 2, 2014
    @Aegwynn 能解释一下,“想要改变对象的值,就不要去改变它的引用即可。”这句话的意思吗,thanks。我的逻辑是这样的:
    while(clusterSet.size()>3){
    updateDistMatrix(dist_matrix,clusterSet);
    }
    当然,每次循环,updateDistMatrix()函数体里面有减少clusterSet项数的逻辑。
    jamiesun
        10
    jamiesun  
       Sep 2, 2014   ❤️ 1
    试试不要用函数包裹,直接在循环里顺序执行

    doSomething(dist_matrix);
    doSomething(clusterSet);


    八成是方法里改变了引用。
    buptlee
        11
    buptlee  
    OP
       Sep 2, 2014
    @jamiesun 好的,我试试不要函数包裹。
    能不能解释一下,改变了引用具体是指什么呢,刚刚用java不久,好多概念也是边做边学,见笑啦。
    Aegwynn
        12
    Aegwynn  
       Sep 2, 2014   ❤️ 1
    @buptlee updateDistMatrix这个方法的源代码都贴出来看看,主要是对clusterSet的操作部分。

    另外建议public void updateDistMatrix(HashMap<Integer ,LinkedList<Node> > dist_matrix,ArrayList<Integer> nearestNodePair,HashMap<Integer,ArrayList<Integer>> clusterSet)
    的方法签名改成
    public void updateDistMatrix(Map<Integer ,List<Node> > dist_matrix,List<Integer> nearestNodePair,Map<Integer,List<Integer>> clusterSet)
    shuson
        13
    shuson  
       Sep 2, 2014   ❤️ 1
    @buptlee 对,如果要返回两个值,就不值当再封装后返回了。
    看了回复们,我也是觉得doSomething函数中可能改变了参数的引用,类似重新创建了新的引用并update的是这个新引用,导致原来传入的参数的引用没有被方法执行操作。
    buptlee
        14
    buptlee  
    OP
       Sep 2, 2014
    已经贴出来啦,方法签名改成map和list之后有啥好处呢,是不是为了多态?效率上能有所提高吗?thanks
    gangsta
        15
    gangsta  
       Sep 2, 2014   ❤️ 2
    sof上的经典问题:
    Is Java “pass-by-reference” or “pass-by-value”?

    http://stackoverflow.com/q/40480/1299675
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3045 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 64ms · UTC 10:39 · PVG 18:39 · LAX 03:39 · JFK 06:39
    ♥ Do have faith in what you're doing.