关于 java 的传址和传值 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
buptlee
V2EX    程序员

关于 java 的传址和传值

  •  1
     
  •   buptlee
    Xiaoxin2009 2014-09-02 10:02:04 +08:00 4400 次点击
    这是一个创建于 4066 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我写了一个函数:
    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 类型的可以吗?
    大神们,教教我。
    第 1 条附言    2014-09-02 11:33:48 +08:00
    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 条回复    2014-09-02 11:37:29 +08:00
    yufz
        1
    yufz  
       2014-09-02 10:14:33 +08:00   1
    不知道你方法体里怎么操作的,java中除了几种基本数据类型之外都是传引用的。
    buptlee
        2
    buptlee  
    OP
       2014-09-02 10:21:18 +08:00
    @jinyang656
    程序里面就是对dist_matrix和clusterSet进行一些修改。
    传递引用的意思是不是,传递实参的一个副本,因此对实参的修改不会反应到传进去的参数上?
    那如果我希望这种修改能保留,应该怎么做?就像c++的传址那样。thanks.
    chocotan
        3
    chocotan  
       2014-09-02 10:42:59 +08:00   1
    难道楼主在doSomething里这样了.... dist_matrix=new XXX...
    shuson
        4
    shuson  
       2014-09-02 10:46:07 +08:00   1
    main() 声明static没用吧。
    试试update后return一下?
    Aegwynn
        5
    Aegwynn  
       2014-09-02 10:55:14 +08:00   1
    java根本没有传址的说法,这个是人们从C那边搬过来的概念。

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

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

    doSomething(dist_matrix);
    doSomething(clusterSet);

    八成是方法里改变了引用。
    buptlee
        11
    buptlee  
    OP
       2014-09-02 11:22:51 +08:00
    @jamiesun 好的,我试试不要函数包裹。
    能不能解释一下,改变了引用具体是指什么呢,刚刚用java不久,好多概念也是边做边学,见笑啦。
    Aegwynn
        12
    Aegwynn  
       2014-09-02 11:23:40 +08:00   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  
       2014-09-02 11:34:14 +08:00   1
    @buptlee 对,如果要返回两个值,就不值当再封装后返回了。
    看了回复们,我也是觉得doSomething函数中可能改变了参数的引用,类似重新创建了新的引用并update的是这个新引用,导致原来传入的参数的引用没有被方法执行操作。
    buptlee
        14
    buptlee  
    OP
       2014-09-02 11:35:13 +08:00
    已经贴出来啦,方法签名改成map和list之后有啥好处呢,是不是为了多态?效率上能有所提高吗?thanks
    gangsta
        15
    gangsta  
       2014-09-02 11:37:29 +08:00   2
    sof上的经典问题:
    Is Java “pass-by-reference” or “pass-by-value”?

    http://stackoverflow.com/q/40480/1299675
    关于     帮助文档     自助推广系统     博客     API   &nbs; FAQ     Solana     983 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 22:29 PVG 06:29 LAX 15:29 JFK 18:29
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86